mirror of
https://github.com/bitwarden/browser
synced 2025-12-21 18:53:29 +00:00
[PM-6818] legacy generator service adapter (#8582)
* introduce legacy generators * introduce generator navigation service * Introduce default options. These accept a userId so that they can be policy-defined * replace `GeneratorOptions` with backwards compatible `GeneratorNavigation`
This commit is contained in:
@@ -6,6 +6,6 @@ export { PasswordGeneratorStrategy } from "./password-generator-strategy";
|
||||
|
||||
// legacy interfaces
|
||||
export { PasswordGeneratorOptions } from "./password-generator-options";
|
||||
export { PasswordGenerationServiceAbstraction } from "./password-generation.service.abstraction";
|
||||
export { PasswordGenerationServiceAbstraction } from "../abstractions/password-generation.service.abstraction";
|
||||
export { PasswordGenerationService } from "./password-generation.service";
|
||||
export { GeneratedPasswordHistory } from "./generated-password-history";
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import { PasswordGeneratorPolicyOptions } from "../../../admin-console/models/domain/password-generator-policy-options";
|
||||
|
||||
import { GeneratedPasswordHistory } from "./generated-password-history";
|
||||
import { PasswordGeneratorOptions } from "./password-generator-options";
|
||||
|
||||
export abstract class PasswordGenerationServiceAbstraction {
|
||||
generatePassword: (options: PasswordGeneratorOptions) => Promise<string>;
|
||||
generatePassphrase: (options: PasswordGeneratorOptions) => Promise<string>;
|
||||
getOptions: () => Promise<[PasswordGeneratorOptions, PasswordGeneratorPolicyOptions]>;
|
||||
enforcePasswordGeneratorPoliciesOnOptions: (
|
||||
options: PasswordGeneratorOptions,
|
||||
) => Promise<[PasswordGeneratorOptions, PasswordGeneratorPolicyOptions]>;
|
||||
getPasswordGeneratorPolicyOptions: () => Promise<PasswordGeneratorPolicyOptions>;
|
||||
saveOptions: (options: PasswordGeneratorOptions) => Promise<void>;
|
||||
getHistory: () => Promise<GeneratedPasswordHistory[]>;
|
||||
addHistory: (password: string) => Promise<void>;
|
||||
clear: (userId?: string) => Promise<void>;
|
||||
normalizeOptions: (
|
||||
options: PasswordGeneratorOptions,
|
||||
enforcedPolicyOptions: PasswordGeneratorPolicyOptions,
|
||||
) => void;
|
||||
}
|
||||
@@ -5,10 +5,10 @@ import { CryptoService } from "../../../platform/abstractions/crypto.service";
|
||||
import { StateService } from "../../../platform/abstractions/state.service";
|
||||
import { EFFLongWordList } from "../../../platform/misc/wordlist";
|
||||
import { EncString } from "../../../platform/models/domain/enc-string";
|
||||
import { PasswordGenerationServiceAbstraction } from "../abstractions/password-generation.service.abstraction";
|
||||
import { PassphraseGeneratorOptionsEvaluator } from "../passphrase/passphrase-generator-options-evaluator";
|
||||
|
||||
import { GeneratedPasswordHistory } from "./generated-password-history";
|
||||
import { PasswordGenerationServiceAbstraction } from "./password-generation.service.abstraction";
|
||||
import { PasswordGeneratorOptions } from "./password-generator-options";
|
||||
import { PasswordGeneratorOptionsEvaluator } from "./password-generator-options-evaluator";
|
||||
|
||||
@@ -341,24 +341,6 @@ export class PasswordGenerationService implements PasswordGenerationServiceAbstr
|
||||
await this.stateService.setDecryptedPasswordGenerationHistory(null, { userId: userId });
|
||||
}
|
||||
|
||||
normalizeOptions(
|
||||
options: PasswordGeneratorOptions,
|
||||
enforcedPolicyOptions: PasswordGeneratorPolicyOptions,
|
||||
) {
|
||||
const evaluator =
|
||||
options.type == "password"
|
||||
? new PasswordGeneratorOptionsEvaluator(enforcedPolicyOptions)
|
||||
: new PassphraseGeneratorOptionsEvaluator(enforcedPolicyOptions);
|
||||
|
||||
const evaluatedOptions = evaluator.applyPolicy(options);
|
||||
const santizedOptions = evaluator.sanitize(evaluatedOptions);
|
||||
|
||||
// callers assume this function updates the options parameter
|
||||
Object.assign(options, santizedOptions);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
private capitalize(str: string) {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { GeneratorNavigation } from "../navigation/generator-navigation";
|
||||
import { PassphraseGenerationOptions } from "../passphrase/passphrase-generation-options";
|
||||
|
||||
import { PasswordGenerationOptions } from "./password-generation-options";
|
||||
@@ -6,12 +7,5 @@ import { PasswordGenerationOptions } from "./password-generation-options";
|
||||
* This type includes all properties suitable for reactive data binding.
|
||||
*/
|
||||
export type PasswordGeneratorOptions = PasswordGenerationOptions &
|
||||
PassphraseGenerationOptions & {
|
||||
/** The algorithm to use for credential generation.
|
||||
* Properties on @see PasswordGenerationOptions should be processed
|
||||
* only when `type === "password"`.
|
||||
* Properties on @see PassphraseGenerationOptions should be processed
|
||||
* only when `type === "passphrase"`.
|
||||
*/
|
||||
type?: "password" | "passphrase";
|
||||
};
|
||||
PassphraseGenerationOptions &
|
||||
GeneratorNavigation;
|
||||
|
||||
@@ -17,6 +17,7 @@ import { PASSWORD_SETTINGS } from "../key-definitions";
|
||||
import { DisabledPasswordGeneratorPolicy } from "./password-generator-policy";
|
||||
|
||||
import {
|
||||
DefaultPasswordGenerationOptions,
|
||||
PasswordGenerationServiceAbstraction,
|
||||
PasswordGeneratorOptionsEvaluator,
|
||||
PasswordGeneratorStrategy,
|
||||
@@ -82,6 +83,16 @@ describe("Password generation strategy", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("defaults$", () => {
|
||||
it("should return the default subaddress options", async () => {
|
||||
const strategy = new PasswordGeneratorStrategy(null, null);
|
||||
|
||||
const result = await firstValueFrom(strategy.defaults$(SomeUser));
|
||||
|
||||
expect(result).toEqual(DefaultPasswordGenerationOptions);
|
||||
});
|
||||
});
|
||||
|
||||
describe("cache_ms", () => {
|
||||
it("should be a positive non-zero number", () => {
|
||||
const legacy = mock<PasswordGenerationServiceAbstraction>();
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import { map, pipe } from "rxjs";
|
||||
import { BehaviorSubject, map, pipe } from "rxjs";
|
||||
|
||||
import { GeneratorStrategy } from "..";
|
||||
import { PolicyType } from "../../../admin-console/enums";
|
||||
import { StateProvider } from "../../../platform/state";
|
||||
import { UserId } from "../../../types/guid";
|
||||
import { PasswordGenerationServiceAbstraction } from "../abstractions/password-generation.service.abstraction";
|
||||
import { PASSWORD_SETTINGS } from "../key-definitions";
|
||||
import { reduceCollection } from "../reduce-collection.operator";
|
||||
|
||||
import { PasswordGenerationOptions } from "./password-generation-options";
|
||||
import { PasswordGenerationServiceAbstraction } from "./password-generation.service.abstraction";
|
||||
import {
|
||||
DefaultPasswordGenerationOptions,
|
||||
PasswordGenerationOptions,
|
||||
} from "./password-generation-options";
|
||||
import { PasswordGeneratorOptionsEvaluator } from "./password-generator-options-evaluator";
|
||||
import {
|
||||
DisabledPasswordGeneratorPolicy,
|
||||
@@ -35,6 +38,11 @@ export class PasswordGeneratorStrategy
|
||||
return this.stateProvider.getUser(id, PASSWORD_SETTINGS);
|
||||
}
|
||||
|
||||
/** Gets the default options. */
|
||||
defaults$(_: UserId) {
|
||||
return new BehaviorSubject({ ...DefaultPasswordGenerationOptions }).asObservable();
|
||||
}
|
||||
|
||||
/** {@link GeneratorStrategy.policy} */
|
||||
get policy() {
|
||||
return PolicyType.PasswordGenerator;
|
||||
|
||||
Reference in New Issue
Block a user