mirror of
https://github.com/bitwarden/browser
synced 2025-12-12 06:13:38 +00:00
@@ -5,4 +5,5 @@ export * from "./settings";
|
|||||||
export { EmailRandomizer } from "./email-randomizer";
|
export { EmailRandomizer } from "./email-randomizer";
|
||||||
export { EmailCalculator } from "./email-calculator";
|
export { EmailCalculator } from "./email-calculator";
|
||||||
export { PasswordRandomizer } from "./password-randomizer";
|
export { PasswordRandomizer } from "./password-randomizer";
|
||||||
|
export { SdkPasswordRandomizer } from "./sdk-password-randomizer";
|
||||||
export { UsernameRandomizer } from "./username-randomizer";
|
export { UsernameRandomizer } from "./username-randomizer";
|
||||||
|
|||||||
103
libs/tools/generator/core/src/engine/sdk-password-randomizer.ts
Normal file
103
libs/tools/generator/core/src/engine/sdk-password-randomizer.ts
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
import {
|
||||||
|
BitwardenClient,
|
||||||
|
PassphraseGeneratorRequest,
|
||||||
|
PasswordGeneratorRequest,
|
||||||
|
} from "@bitwarden/sdk-internal";
|
||||||
|
|
||||||
|
import { Type } from "../metadata";
|
||||||
|
import {
|
||||||
|
CredentialGenerator,
|
||||||
|
GenerateRequest,
|
||||||
|
GeneratedCredential,
|
||||||
|
PassphraseGenerationOptions,
|
||||||
|
PasswordGenerationOptions,
|
||||||
|
} from "../types";
|
||||||
|
|
||||||
|
/** Generation algorithms that produce randomized secrets by calling on functionality from the SDK */
|
||||||
|
export class SdkPasswordRandomizer
|
||||||
|
implements
|
||||||
|
CredentialGenerator<PassphraseGenerationOptions>,
|
||||||
|
CredentialGenerator<PasswordGenerationOptions>
|
||||||
|
{
|
||||||
|
/** Instantiates the password randomizer
|
||||||
|
* @param client access to SDK client to call upon password/passphrase generation
|
||||||
|
* @param currentTime gets the current datetime in epoch time
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
private client: BitwardenClient,
|
||||||
|
private currentTime: () => number,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
generate(
|
||||||
|
request: GenerateRequest,
|
||||||
|
settings: PasswordGenerationOptions,
|
||||||
|
): Promise<GeneratedCredential>;
|
||||||
|
generate(
|
||||||
|
request: GenerateRequest,
|
||||||
|
settings: PassphraseGenerationOptions,
|
||||||
|
): Promise<GeneratedCredential>;
|
||||||
|
async generate(
|
||||||
|
request: GenerateRequest,
|
||||||
|
settings: PasswordGenerationOptions | PassphraseGenerationOptions,
|
||||||
|
) {
|
||||||
|
if (isPasswordGenerationOptions(settings)) {
|
||||||
|
const password = await this.client.generator().password(convertPasswordRequest(settings));
|
||||||
|
|
||||||
|
return new GeneratedCredential(
|
||||||
|
password,
|
||||||
|
Type.password,
|
||||||
|
this.currentTime(),
|
||||||
|
request.source,
|
||||||
|
request.website,
|
||||||
|
);
|
||||||
|
} else if (isPassphraseGenerationOptions(settings)) {
|
||||||
|
const passphrase = await this.client
|
||||||
|
.generator()
|
||||||
|
.passphrase(convertPassphraseRequest(settings));
|
||||||
|
|
||||||
|
return new GeneratedCredential(
|
||||||
|
passphrase,
|
||||||
|
Type.password,
|
||||||
|
this.currentTime(),
|
||||||
|
request.source,
|
||||||
|
request.website,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("Invalid settings received by generator.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertPasswordRequest(settings: PasswordGenerationOptions): PasswordGeneratorRequest {
|
||||||
|
return {
|
||||||
|
lowercase: settings.lowercase!,
|
||||||
|
uppercase: settings.uppercase!,
|
||||||
|
numbers: settings.number!,
|
||||||
|
special: settings.special!,
|
||||||
|
length: settings.length!,
|
||||||
|
avoidAmbiguous: settings.ambiguous!,
|
||||||
|
minLowercase: settings.minLowercase!,
|
||||||
|
minUppercase: settings.minUppercase!,
|
||||||
|
minNumber: settings.minNumber!,
|
||||||
|
minSpecial: settings.minSpecial!,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertPassphraseRequest(
|
||||||
|
settings: PassphraseGenerationOptions,
|
||||||
|
): PassphraseGeneratorRequest {
|
||||||
|
return {
|
||||||
|
numWords: settings.numWords!,
|
||||||
|
wordSeparator: settings.wordSeparator!,
|
||||||
|
capitalize: settings.capitalize!,
|
||||||
|
includeNumber: settings.includeNumber!,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPasswordGenerationOptions(settings: any): settings is PasswordGenerationOptions {
|
||||||
|
return "length" in (settings ?? {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPassphraseGenerationOptions(settings: any): settings is PassphraseGenerationOptions {
|
||||||
|
return "numWords" in (settings ?? {});
|
||||||
|
}
|
||||||
@@ -8,6 +8,12 @@ export const Algorithm = Object.freeze({
|
|||||||
/** A password composed of random words from the EFF word list */
|
/** A password composed of random words from the EFF word list */
|
||||||
passphrase: "passphrase",
|
passphrase: "passphrase",
|
||||||
|
|
||||||
|
/** A password composed of random characters, retrieved from SDK */
|
||||||
|
sdkPassword: "sdkPassword",
|
||||||
|
|
||||||
|
/** A password composed of random words from the EFF word list, retrieved from SDK */
|
||||||
|
sdkPassphrase: "sdkPassphrase",
|
||||||
|
|
||||||
/** A username composed of words from the EFF word list */
|
/** A username composed of words from the EFF word list */
|
||||||
username: "username",
|
username: "username",
|
||||||
|
|
||||||
@@ -38,7 +44,12 @@ export const Profile = Object.freeze({
|
|||||||
/** Credential generation algorithms grouped by purpose. */
|
/** Credential generation algorithms grouped by purpose. */
|
||||||
export const AlgorithmsByType = deepFreeze({
|
export const AlgorithmsByType = deepFreeze({
|
||||||
/** Algorithms that produce passwords */
|
/** Algorithms that produce passwords */
|
||||||
[Type.password]: [Algorithm.password, Algorithm.passphrase] as const,
|
[Type.password]: [
|
||||||
|
Algorithm.password,
|
||||||
|
Algorithm.passphrase,
|
||||||
|
Algorithm.sdkPassword,
|
||||||
|
Algorithm.sdkPassphrase,
|
||||||
|
] as const,
|
||||||
|
|
||||||
/** Algorithms that produce usernames */
|
/** Algorithms that produce usernames */
|
||||||
[Type.username]: [Algorithm.username] as const,
|
[Type.username]: [Algorithm.username] as const,
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
import { mock } from "jest-mock-extended";
|
||||||
|
|
||||||
|
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||||
|
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
|
||||||
|
|
||||||
|
import { SdkPasswordRandomizer } from "../../engine";
|
||||||
|
import { PassphrasePolicyConstraints } from "../../policies";
|
||||||
|
import { PassphraseGenerationOptions, GeneratorDependencyProvider } from "../../types";
|
||||||
|
import { Profile } from "../data";
|
||||||
|
import { CoreProfileMetadata } from "../profile-metadata";
|
||||||
|
import { isCoreProfile } from "../util";
|
||||||
|
|
||||||
|
import sdkEffPassphrase from "./sdk-eff-word-list";
|
||||||
|
|
||||||
|
const dependencyProvider = mock<GeneratorDependencyProvider>();
|
||||||
|
|
||||||
|
describe("password - eff words generator metadata", () => {
|
||||||
|
describe("engine.create", () => {
|
||||||
|
it("returns an email randomizer", () => {
|
||||||
|
expect(sdkEffPassphrase.engine.create(dependencyProvider)).toBeInstanceOf(
|
||||||
|
SdkPasswordRandomizer,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("profiles[account]", () => {
|
||||||
|
let accountProfile: CoreProfileMetadata<PassphraseGenerationOptions> | null = null;
|
||||||
|
beforeEach(() => {
|
||||||
|
const profile = sdkEffPassphrase.profiles[Profile.account];
|
||||||
|
if (isCoreProfile(profile!)) {
|
||||||
|
accountProfile = profile;
|
||||||
|
} else {
|
||||||
|
accountProfile = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("storage.options.deserializer", () => {
|
||||||
|
it("returns its input", () => {
|
||||||
|
const value: PassphraseGenerationOptions = { ...accountProfile!.storage.initial };
|
||||||
|
|
||||||
|
const result = accountProfile!.storage.options.deserializer(value);
|
||||||
|
|
||||||
|
expect(result).toBe(value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("constraints.create", () => {
|
||||||
|
// these tests check that the wiring is correct by exercising the behavior
|
||||||
|
// of functionality encapsulated by `create`. These methods may fail if the
|
||||||
|
// enclosed behaviors change.
|
||||||
|
|
||||||
|
it("creates a passphrase policy constraints", () => {
|
||||||
|
const context = { defaultConstraints: accountProfile!.constraints.default };
|
||||||
|
|
||||||
|
const constraints = accountProfile!.constraints.create([], context);
|
||||||
|
|
||||||
|
expect(constraints).toBeInstanceOf(PassphrasePolicyConstraints);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("forwards the policy to the constraints", () => {
|
||||||
|
const context = { defaultConstraints: accountProfile!.constraints.default };
|
||||||
|
const policies = [
|
||||||
|
{
|
||||||
|
type: PolicyType.PasswordGenerator,
|
||||||
|
data: {
|
||||||
|
minNumberWords: 6,
|
||||||
|
capitalize: false,
|
||||||
|
includeNumber: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] as Policy[];
|
||||||
|
|
||||||
|
const constraints = accountProfile!.constraints.create(policies, context);
|
||||||
|
|
||||||
|
expect(constraints.constraints.numWords?.min).toEqual(6);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("combines multiple policies in the constraints", () => {
|
||||||
|
const context = { defaultConstraints: accountProfile!.constraints.default };
|
||||||
|
const policies = [
|
||||||
|
{
|
||||||
|
type: PolicyType.PasswordGenerator,
|
||||||
|
data: {
|
||||||
|
minNumberWords: 6,
|
||||||
|
capitalize: false,
|
||||||
|
includeNumber: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: PolicyType.PasswordGenerator,
|
||||||
|
data: {
|
||||||
|
minNumberWords: 3,
|
||||||
|
capitalize: true,
|
||||||
|
includeNumber: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] as Policy[];
|
||||||
|
|
||||||
|
const constraints = accountProfile!.constraints.create(policies, context);
|
||||||
|
|
||||||
|
expect(constraints.constraints.numWords?.min).toEqual(6);
|
||||||
|
expect(constraints.constraints.capitalize?.requiredValue).toEqual(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||||
|
import { GENERATOR_DISK } from "@bitwarden/common/platform/state";
|
||||||
|
import { PublicClassifier } from "@bitwarden/common/tools/public-classifier";
|
||||||
|
import { ObjectKey } from "@bitwarden/common/tools/state/object-key";
|
||||||
|
import { BitwardenClient } from "@bitwarden/sdk-internal";
|
||||||
|
|
||||||
|
import { SdkPasswordRandomizer } from "../../engine";
|
||||||
|
import { passphraseLeastPrivilege, PassphrasePolicyConstraints } from "../../policies";
|
||||||
|
import {
|
||||||
|
CredentialGenerator,
|
||||||
|
GeneratorDependencyProvider,
|
||||||
|
PassphraseGenerationOptions,
|
||||||
|
} from "../../types";
|
||||||
|
import { Algorithm, Profile, Type } from "../data";
|
||||||
|
import { GeneratorMetadata } from "../generator-metadata";
|
||||||
|
|
||||||
|
const sdkPassphrase: GeneratorMetadata<PassphraseGenerationOptions> = {
|
||||||
|
id: Algorithm.sdkPassphrase,
|
||||||
|
category: Type.password,
|
||||||
|
weight: 130,
|
||||||
|
i18nKeys: {
|
||||||
|
name: "passphrase",
|
||||||
|
credentialType: "passphrase",
|
||||||
|
generateCredential: "generatePassphrase",
|
||||||
|
credentialGenerated: "passphraseGenerated",
|
||||||
|
copyCredential: "copyPassphrase",
|
||||||
|
useCredential: "useThisPassphrase",
|
||||||
|
},
|
||||||
|
capabilities: {
|
||||||
|
autogenerate: false,
|
||||||
|
fields: [],
|
||||||
|
},
|
||||||
|
engine: {
|
||||||
|
create(
|
||||||
|
dependencies: GeneratorDependencyProvider,
|
||||||
|
): CredentialGenerator<PassphraseGenerationOptions> {
|
||||||
|
return new SdkPasswordRandomizer(new BitwardenClient(), Date.now); // @TODO hook up a real SDK client
|
||||||
|
},
|
||||||
|
},
|
||||||
|
profiles: {
|
||||||
|
[Profile.account]: {
|
||||||
|
type: "core",
|
||||||
|
storage: {
|
||||||
|
key: "passphraseGeneratorSettings",
|
||||||
|
target: "object",
|
||||||
|
format: "plain",
|
||||||
|
classifier: new PublicClassifier<PassphraseGenerationOptions>([
|
||||||
|
"numWords",
|
||||||
|
"wordSeparator",
|
||||||
|
"capitalize",
|
||||||
|
"includeNumber",
|
||||||
|
]),
|
||||||
|
state: GENERATOR_DISK,
|
||||||
|
initial: {
|
||||||
|
numWords: 6,
|
||||||
|
wordSeparator: "-",
|
||||||
|
capitalize: false,
|
||||||
|
includeNumber: false,
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
deserializer(value) {
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
clearOn: ["logout"],
|
||||||
|
},
|
||||||
|
} satisfies ObjectKey<PassphraseGenerationOptions>,
|
||||||
|
constraints: {
|
||||||
|
type: PolicyType.PasswordGenerator,
|
||||||
|
default: {
|
||||||
|
wordSeparator: { maxLength: 1 },
|
||||||
|
numWords: {
|
||||||
|
min: 3,
|
||||||
|
max: 20,
|
||||||
|
recommendation: 6,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
create(policies, context) {
|
||||||
|
const initial = {
|
||||||
|
minNumberWords: 0,
|
||||||
|
capitalize: false,
|
||||||
|
includeNumber: false,
|
||||||
|
};
|
||||||
|
const policy = policies.reduce(passphraseLeastPrivilege, initial);
|
||||||
|
const constraints = new PassphrasePolicyConstraints(policy, context.defaultConstraints);
|
||||||
|
return constraints;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default sdkPassphrase;
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
import { mock } from "jest-mock-extended";
|
||||||
|
|
||||||
|
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||||
|
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
|
||||||
|
|
||||||
|
import { SdkPasswordRandomizer } from "../../engine";
|
||||||
|
import { DynamicPasswordPolicyConstraints } from "../../policies";
|
||||||
|
import { PasswordGenerationOptions, GeneratorDependencyProvider } from "../../types";
|
||||||
|
import { Profile } from "../data";
|
||||||
|
import { CoreProfileMetadata } from "../profile-metadata";
|
||||||
|
import { isCoreProfile } from "../util";
|
||||||
|
|
||||||
|
import sdkPassword from "./sdk-random-password";
|
||||||
|
|
||||||
|
const dependencyProvider = mock<GeneratorDependencyProvider>();
|
||||||
|
|
||||||
|
describe("password - characters generator metadata", () => {
|
||||||
|
describe("engine.create", () => {
|
||||||
|
it("returns an email randomizer", () => {
|
||||||
|
expect(sdkPassword.engine.create(dependencyProvider)).toBeInstanceOf(SdkPasswordRandomizer);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("profiles[account]", () => {
|
||||||
|
let accountProfile: CoreProfileMetadata<PasswordGenerationOptions> = null!;
|
||||||
|
beforeEach(() => {
|
||||||
|
const profile = sdkPassword.profiles[Profile.account];
|
||||||
|
if (isCoreProfile(profile!)) {
|
||||||
|
accountProfile = profile;
|
||||||
|
} else {
|
||||||
|
throw new Error("this branch should never run");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("storage.options.deserializer", () => {
|
||||||
|
it("returns its input", () => {
|
||||||
|
const value: PasswordGenerationOptions = { ...accountProfile.storage.initial };
|
||||||
|
|
||||||
|
const result = accountProfile.storage.options.deserializer(value);
|
||||||
|
|
||||||
|
expect(result).toBe(value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("constraints.create", () => {
|
||||||
|
// these tests check that the wiring is correct by exercising the behavior
|
||||||
|
// of functionality encapsulated by `create`. These methods may fail if the
|
||||||
|
// enclosed behaviors change.
|
||||||
|
|
||||||
|
it("creates a passphrase policy constraints", () => {
|
||||||
|
const context = { defaultConstraints: accountProfile.constraints.default };
|
||||||
|
|
||||||
|
const constraints = accountProfile.constraints.create([], context);
|
||||||
|
|
||||||
|
expect(constraints).toBeInstanceOf(DynamicPasswordPolicyConstraints);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("forwards the policy to the constraints", () => {
|
||||||
|
const context = { defaultConstraints: accountProfile.constraints.default };
|
||||||
|
const policies = [
|
||||||
|
{
|
||||||
|
type: PolicyType.PasswordGenerator,
|
||||||
|
enabled: true,
|
||||||
|
data: {
|
||||||
|
minLength: 10,
|
||||||
|
capitalize: false,
|
||||||
|
useNumbers: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] as Policy[];
|
||||||
|
|
||||||
|
const constraints = accountProfile.constraints.create(policies, context);
|
||||||
|
|
||||||
|
expect(constraints.constraints.length?.min).toEqual(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("combines multiple policies in the constraints", () => {
|
||||||
|
const context = { defaultConstraints: accountProfile.constraints.default };
|
||||||
|
const policies = [
|
||||||
|
{
|
||||||
|
type: PolicyType.PasswordGenerator,
|
||||||
|
enabled: true,
|
||||||
|
data: {
|
||||||
|
minLength: 14,
|
||||||
|
useSpecial: false,
|
||||||
|
useNumbers: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: PolicyType.PasswordGenerator,
|
||||||
|
enabled: true,
|
||||||
|
data: {
|
||||||
|
minLength: 10,
|
||||||
|
useSpecial: true,
|
||||||
|
includeNumber: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] as Policy[];
|
||||||
|
|
||||||
|
const constraints = accountProfile.constraints.create(policies, context);
|
||||||
|
|
||||||
|
expect(constraints.constraints.length?.min).toEqual(14);
|
||||||
|
expect(constraints.constraints.special?.requiredValue).toEqual(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||||
|
import { GENERATOR_DISK } from "@bitwarden/common/platform/state";
|
||||||
|
import { PublicClassifier } from "@bitwarden/common/tools/public-classifier";
|
||||||
|
import { deepFreeze } from "@bitwarden/common/tools/util";
|
||||||
|
import { BitwardenClient } from "@bitwarden/sdk-internal";
|
||||||
|
|
||||||
|
import { SdkPasswordRandomizer } from "../../engine";
|
||||||
|
import { DynamicPasswordPolicyConstraints, passwordLeastPrivilege } from "../../policies";
|
||||||
|
import {
|
||||||
|
CredentialGenerator,
|
||||||
|
GeneratorDependencyProvider,
|
||||||
|
PasswordGeneratorSettings,
|
||||||
|
} from "../../types";
|
||||||
|
import { Algorithm, Profile, Type } from "../data";
|
||||||
|
import { GeneratorMetadata } from "../generator-metadata";
|
||||||
|
|
||||||
|
const sdkPassword: GeneratorMetadata<PasswordGeneratorSettings> = deepFreeze({
|
||||||
|
id: Algorithm.sdkPassword,
|
||||||
|
category: Type.password,
|
||||||
|
weight: 120,
|
||||||
|
i18nKeys: {
|
||||||
|
name: "password",
|
||||||
|
generateCredential: "generatePassword",
|
||||||
|
credentialGenerated: "passwordGenerated",
|
||||||
|
credentialType: "password",
|
||||||
|
copyCredential: "copyPassword",
|
||||||
|
useCredential: "useThisPassword",
|
||||||
|
},
|
||||||
|
capabilities: {
|
||||||
|
autogenerate: true,
|
||||||
|
fields: [],
|
||||||
|
},
|
||||||
|
engine: {
|
||||||
|
create(
|
||||||
|
dependencies: GeneratorDependencyProvider,
|
||||||
|
): CredentialGenerator<PasswordGeneratorSettings> {
|
||||||
|
return new SdkPasswordRandomizer(new BitwardenClient(), Date.now); // @TODO hook up a real SDK client
|
||||||
|
},
|
||||||
|
},
|
||||||
|
profiles: {
|
||||||
|
[Profile.account]: {
|
||||||
|
type: "core",
|
||||||
|
storage: {
|
||||||
|
key: "passwordGeneratorSettings",
|
||||||
|
target: "object",
|
||||||
|
format: "plain",
|
||||||
|
classifier: new PublicClassifier<PasswordGeneratorSettings>([
|
||||||
|
"length",
|
||||||
|
"ambiguous",
|
||||||
|
"uppercase",
|
||||||
|
"minUppercase",
|
||||||
|
"lowercase",
|
||||||
|
"minLowercase",
|
||||||
|
"number",
|
||||||
|
"minNumber",
|
||||||
|
"special",
|
||||||
|
"minSpecial",
|
||||||
|
]),
|
||||||
|
state: GENERATOR_DISK,
|
||||||
|
initial: {
|
||||||
|
length: 14,
|
||||||
|
ambiguous: true,
|
||||||
|
uppercase: true,
|
||||||
|
minUppercase: 1,
|
||||||
|
lowercase: true,
|
||||||
|
minLowercase: 1,
|
||||||
|
number: true,
|
||||||
|
minNumber: 1,
|
||||||
|
special: false,
|
||||||
|
minSpecial: 0,
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
deserializer(value) {
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
clearOn: ["logout"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
constraints: {
|
||||||
|
type: PolicyType.PasswordGenerator,
|
||||||
|
default: {
|
||||||
|
length: {
|
||||||
|
min: 5,
|
||||||
|
max: 128,
|
||||||
|
recommendation: 14,
|
||||||
|
},
|
||||||
|
minNumber: {
|
||||||
|
min: 0,
|
||||||
|
max: 9,
|
||||||
|
},
|
||||||
|
minSpecial: {
|
||||||
|
min: 0,
|
||||||
|
max: 9,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
create(policies, context) {
|
||||||
|
const initial = {
|
||||||
|
minLength: 0,
|
||||||
|
useUppercase: false,
|
||||||
|
useLowercase: false,
|
||||||
|
useNumbers: false,
|
||||||
|
numberCount: 0,
|
||||||
|
useSpecial: false,
|
||||||
|
specialCount: 0,
|
||||||
|
};
|
||||||
|
const policy = policies.reduce(passwordLeastPrivilege, initial);
|
||||||
|
const constraints = new DynamicPasswordPolicyConstraints(
|
||||||
|
policy,
|
||||||
|
context.defaultConstraints,
|
||||||
|
);
|
||||||
|
return constraints;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default sdkPassword;
|
||||||
Reference in New Issue
Block a user