1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-10-22 07:50:04 +02:00

fix credential generator tests and angular imports

This commit is contained in:
✨ Audrey ✨ 2024-10-16 12:21:36 -04:00
parent 51d29836e5
commit d5a19bab75
No known key found for this signature in database
GPG Key ID: 0CF8B4C0D9088B97
4 changed files with 134 additions and 29 deletions

View File

@ -8,6 +8,7 @@ import { SafeInjectionToken } from "@bitwarden/angular/services/injection-tokens
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { StateProvider } from "@bitwarden/common/platform/state";
import {
@ -69,7 +70,15 @@ const RANDOMIZER = new SafeInjectionToken<Randomizer>("Randomizer");
safeProvider({
provide: CredentialGeneratorService,
useClass: CredentialGeneratorService,
deps: [RANDOMIZER, StateProvider, PolicyService, ApiService, I18nService],
deps: [
RANDOMIZER,
StateProvider,
PolicyService,
ApiService,
I18nService,
EncryptService,
CryptoService,
],
}),
],
declarations: [

View File

@ -5,10 +5,13 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { PolicyType } from "@bitwarden/common/admin-console/enums";
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { GENERATOR_DISK, UserKeyDefinition } from "@bitwarden/common/platform/state";
import { StateConstraints } from "@bitwarden/common/tools/types";
import { OrganizationId, PolicyId, UserId } from "@bitwarden/common/types/guid";
import { UserKey } from "@bitwarden/common/types/key";
import {
FakeStateProvider,
@ -77,7 +80,7 @@ const SomeConfiguration: CredentialGeneratorConfiguration<SomeSettings, SomePoli
nameKey: SomeNameKey,
onlyOnRequest: false,
engine: {
create: (randomizer) => {
create: (_randomizer) => {
return {
generate: (request, settings) => {
const credential = request.website ? `${request.website}|${settings.foo}` : settings.foo;
@ -165,12 +168,18 @@ const i18nService = mock<I18nService>();
const apiService = mock<ApiService>();
const encryptService = mock<EncryptService>();
const cryptoService = mock<CryptoService>();
describe("CredentialGeneratorService", () => {
beforeEach(async () => {
await accountService.switchAccount(SomeUser);
policyService.getAll$.mockImplementation(() => new BehaviorSubject([]).asObservable());
i18nService.t.mockImplementation((key) => key);
apiService.fetch.mockImplementation(() => Promise.resolve(mock<Response>()));
const keyAvailable = new BehaviorSubject({} as UserKey);
cryptoService.userKey$.mockReturnValue(keyAvailable);
jest.clearAllMocks();
});
@ -184,6 +193,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const generated = new ObservableTracker(generator.generate$(SomeConfiguration));
@ -203,6 +214,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const generated = new ObservableTracker(generator.generate$(SomeConfiguration));
@ -226,6 +239,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const generated = new ObservableTracker(generator.generate$(SomeConfiguration));
@ -252,6 +267,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const website$ = new BehaviorSubject("some website");
const generated = new ObservableTracker(generator.generate$(SomeConfiguration, { website$ }));
@ -271,6 +288,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const website$ = new BehaviorSubject("some website");
let error = null;
@ -294,6 +313,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const website$ = new BehaviorSubject("some website");
let completed = false;
@ -318,6 +339,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId$ = new BehaviorSubject(AnotherUser).asObservable();
const generated = new ObservableTracker(generator.generate$(SomeConfiguration, { userId$ }));
@ -336,6 +359,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId = new BehaviorSubject(SomeUser);
const userId$ = userId.pipe(filter((u) => !!u));
@ -358,6 +383,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId$ = new BehaviorSubject(SomeUser);
let error = null;
@ -381,6 +408,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId$ = new BehaviorSubject(SomeUser);
let completed = false;
@ -405,6 +434,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const on$ = new Subject<void>();
const results: any[] = [];
@ -445,6 +476,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const on$ = new Subject<void>();
let error: any = null;
@ -469,6 +502,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const on$ = new Subject<void>();
let complete = false;
@ -498,6 +533,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const result = generator.algorithms("password");
@ -517,6 +554,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const result = generator.algorithms("username");
@ -535,6 +574,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const result = generator.algorithms("email");
@ -554,6 +595,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const result = generator.algorithms(["username", "email"]);
@ -577,6 +620,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const result = await firstValueFrom(generator.algorithms$("password"));
@ -592,6 +637,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const result = await firstValueFrom(generator.algorithms$("username"));
@ -606,6 +653,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const result = await firstValueFrom(generator.algorithms$("email"));
@ -621,6 +670,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const result = await firstValueFrom(generator.algorithms$(["username", "email"]));
@ -641,6 +692,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const result = await firstValueFrom(generator.algorithms$(["password"]));
@ -664,6 +717,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const results: any = [];
const sub = generator.algorithms$("password").subscribe((r) => results.push(r));
@ -699,6 +754,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId$ = new BehaviorSubject(AnotherUser).asObservable();
@ -718,6 +775,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId = new BehaviorSubject(SomeUser);
const userId$ = userId.asObservable();
@ -746,6 +805,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId = new BehaviorSubject(SomeUser);
const userId$ = userId.asObservable();
@ -770,6 +831,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId = new BehaviorSubject(SomeUser);
const userId$ = userId.asObservable();
@ -794,6 +857,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId = new BehaviorSubject(SomeUser);
const userId$ = userId.asObservable();
@ -824,6 +889,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const result = await firstValueFrom(generator.settings$(SomeConfiguration));
@ -840,6 +907,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const result = await firstValueFrom(generator.settings$(SomeConfiguration));
@ -858,6 +927,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const result = await firstValueFrom(generator.settings$(SomeConfiguration));
@ -866,7 +937,7 @@ describe("CredentialGeneratorService", () => {
});
it("follows changes to the active user", async () => {
// initialize local accound service and state provider because this test is sensitive
// initialize local account service and state provider because this test is sensitive
// to some shared data in `FakeAccountService`.
const accountService = new FakeAccountService(accounts);
const stateProvider = new FakeStateProvider(accountService);
@ -881,6 +952,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const results: any = [];
const sub = generator.settings$(SomeConfiguration).subscribe((r) => results.push(r));
@ -904,6 +977,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId$ = new BehaviorSubject(AnotherUser).asObservable();
@ -923,6 +998,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId = new BehaviorSubject(SomeUser);
const userId$ = userId.asObservable();
@ -948,6 +1025,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId = new BehaviorSubject(SomeUser);
const userId$ = userId.asObservable();
@ -972,6 +1051,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId = new BehaviorSubject(SomeUser);
const userId$ = userId.asObservable();
@ -996,6 +1077,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId = new BehaviorSubject(SomeUser);
const userId$ = userId.asObservable();
@ -1026,6 +1109,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const subject = await generator.settings(SomeConfiguration, { singleUserId$ });
@ -1045,6 +1130,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
let completed = false;
@ -1069,6 +1156,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId$ = new BehaviorSubject(SomeUser).asObservable();
@ -1084,6 +1173,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId$ = new BehaviorSubject(SomeUser).asObservable();
const policy$ = new BehaviorSubject([somePolicy]);
@ -1101,6 +1192,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId = new BehaviorSubject(SomeUser);
const userId$ = userId.asObservable();
@ -1128,6 +1221,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId = new BehaviorSubject(SomeUser);
const userId$ = userId.asObservable();
@ -1156,6 +1251,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId = new BehaviorSubject(SomeUser);
const userId$ = userId.asObservable();
@ -1180,6 +1277,8 @@ describe("CredentialGeneratorService", () => {
policyService,
apiService,
i18nService,
encryptService,
cryptoService,
);
const userId = new BehaviorSubject(SomeUser);
const userId$ = userId.asObservable();

View File

@ -11,7 +11,6 @@ import {
ignoreElements,
map,
Observable,
race,
share,
skipUntil,
switchMap,
@ -36,8 +35,8 @@ import {
} from "@bitwarden/common/tools/dependencies";
import { IntegrationId, IntegrationMetadata } from "@bitwarden/common/tools/integration";
import { RestClient } from "@bitwarden/common/tools/integration/rpc";
import { anyComplete } from "@bitwarden/common/tools/rx";
import { PaddedDataPacker } from "@bitwarden/common/tools/state/padded-data-packer";
import { isDynamic } from "@bitwarden/common/tools/state/state-constraints-dependency";
import { UserEncryptor } from "@bitwarden/common/tools/state/user-encryptor.abstraction";
import { UserKeyEncryptor } from "@bitwarden/common/tools/state/user-key-encryptor";
import { UserStateSubject } from "@bitwarden/common/tools/state/user-state-subject";
@ -86,13 +85,13 @@ const OPTIONS_FRAME_SIZE = 512;
export class CredentialGeneratorService {
constructor(
private randomizer: Randomizer,
private stateProvider: StateProvider,
private policyService: PolicyService,
private apiService: ApiService,
private i18nService: I18nService,
private readonly randomizer: Randomizer,
private readonly stateProvider: StateProvider,
private readonly policyService: PolicyService,
private readonly apiService: ApiService,
private readonly i18nService: I18nService,
private readonly encryptService: EncryptService,
private cryptoService: CryptoService,
private readonly cryptoService: CryptoService,
) {}
private getDependencyProvider(): GeneratorDependencyProvider {
@ -124,11 +123,6 @@ export class CredentialGeneratorService {
const request$ = website$.pipe(map((website) => ({ website })));
const settings$ = this.settings$(configuration, dependencies);
// monitor completion
const requestComplete$ = request$.pipe(ignoreElements(), endWith(true));
const settingsComplete$ = request$.pipe(ignoreElements(), endWith(true));
const complete$ = race(requestComplete$, settingsComplete$);
// if on$ triggers before settings are loaded, trigger as soon
// as they become available.
let readyOn$: Observable<any> = null;
@ -149,7 +143,7 @@ export class CredentialGeneratorService {
const generate$ = (readyOn$ ?? settings$).pipe(
withLatestFrom(request$, settings$),
concatMap(([, request, settings]) => engine.generate(request, settings)),
takeUntil(complete$),
takeUntil(anyComplete([request$, settings$])),
);
return generate$;
@ -287,27 +281,21 @@ export class CredentialGeneratorService {
dependencies?: Settings$Dependencies,
) {
const userId$ = dependencies?.userId$ ?? this.stateProvider.activeUserId$;
const constraints$ = this.policy$(configuration, { userId$ });
const state$ = userId$.pipe(
const settings$ = userId$.pipe(
filter((userId) => !!userId),
distinctUntilChanged(),
switchMap((userId) => {
const state$ = new UserStateSubject(
configuration.settings.account,
(key) => this.stateProvider.getUser(userId, key),
{ singleUserEncryptor$: this.encryptor$(userId) },
{ constraints$, singleUserEncryptor$: this.encryptor$(userId) },
);
return state$;
}),
map((settings) => settings ?? structuredClone(configuration.settings.initial)),
);
const settings$ = combineLatest([state$, this.policy$(configuration, { userId$ })]).pipe(
map(([settings, policy]) => {
const calibration = isDynamic(policy) ? policy.calibrate(settings) : policy;
const adjusted = calibration.adjust(settings);
return adjusted;
}),
takeUntil(anyComplete(userId$)),
);
return settings$;
@ -333,7 +321,7 @@ export class CredentialGeneratorService {
const subject = new UserStateSubject(
PREFERENCES,
(key) => this.stateProvider.getUser(userId, key),
{ ...dependencies },
{ singleUserEncryptor$: this.encryptor$(userId) },
);
return subject;

View File

@ -5,6 +5,7 @@ import { SafeInjectionToken } from "@bitwarden/angular/services/injection-tokens
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { StateProvider } from "@bitwarden/common/platform/state";
import {
@ -34,7 +35,15 @@ const RANDOMIZER = new SafeInjectionToken<Randomizer>("Randomizer");
safeProvider({
useClass: CredentialGeneratorService,
provide: CredentialGeneratorService,
deps: [RANDOMIZER, StateProvider, PolicyService, ApiService, I18nService],
deps: [
RANDOMIZER,
StateProvider,
PolicyService,
ApiService,
I18nService,
EncryptService,
CryptoService,
],
}),
],
exports: [SendFormComponent],