diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index a76050fe44f..7e10337acb3 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -64,7 +64,6 @@ import { TokenService } from "@bitwarden/common/auth/services/token.service"; import { TwoFactorService } from "@bitwarden/common/auth/services/two-factor.service"; import { UserVerificationApiService } from "@bitwarden/common/auth/services/user-verification/user-verification-api.service"; import { UserVerificationService } from "@bitwarden/common/auth/services/user-verification/user-verification.service"; -import { ActiveUserStateProvider } from "@bitwarden/common/platform/abstractions/active-user-state.provider"; import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/platform/abstractions/app-id.service"; import { BroadcasterService as BroadcasterServiceAbstraction } from "@bitwarden/common/platform/abstractions/broadcaster.service"; import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction"; @@ -80,6 +79,7 @@ import { MessagingService as MessagingServiceAbstraction } from "@bitwarden/comm import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service"; import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service"; +import { UserStateProvider } from "@bitwarden/common/platform/abstractions/user-state.provider"; import { ValidationService as ValidationServiceAbstraction } from "@bitwarden/common/platform/abstractions/validation.service"; import { StateFactory } from "@bitwarden/common/platform/factories/state-factory"; import { flagEnabled } from "@bitwarden/common/platform/misc/flags"; @@ -92,7 +92,7 @@ import { ConsoleLogService } from "@bitwarden/common/platform/services/console-l import { CryptoService } from "@bitwarden/common/platform/services/crypto.service"; import { EncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/encrypt.service.implementation"; import { MultithreadEncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/multithread-encrypt.service.implementation"; -import { DefaultActiveUserStateProvider } from "@bitwarden/common/platform/services/default-active-user-state.provider"; +import { DefaultUserStateProvider } from "@bitwarden/common/platform/services/default-user-state.provider"; import { EnvironmentService } from "@bitwarden/common/platform/services/environment.service"; import { FileUploadService } from "@bitwarden/common/platform/services/file-upload/file-upload.service"; import { StateService } from "@bitwarden/common/platform/services/state.service"; @@ -303,7 +303,7 @@ import { AbstractThemingService } from "./theming/theming.service.abstraction"; CryptoServiceAbstraction, I18nServiceAbstraction, CipherServiceAbstraction, - ActiveUserStateProvider, + UserStateProvider, StateServiceAbstraction, ], }, @@ -722,8 +722,8 @@ import { AbstractThemingService } from "./theming/theming.service.abstraction"; deps: [CryptoServiceAbstraction], }, { - provide: ActiveUserStateProvider, - useClass: DefaultActiveUserStateProvider, + provide: UserStateProvider, + useClass: DefaultUserStateProvider, deps: [ // TODO: Do other storage services AccountServiceAbstraction, diff --git a/libs/common/spec/test-active-user-state.ts b/libs/common/spec/test-user-state.ts similarity index 83% rename from libs/common/spec/test-active-user-state.ts rename to libs/common/spec/test-user-state.ts index 9c646e8f1c0..6b8c2985a23 100644 --- a/libs/common/spec/test-active-user-state.ts +++ b/libs/common/spec/test-user-state.ts @@ -1,8 +1,8 @@ import { BehaviorSubject, firstValueFrom } from "rxjs"; -import { ActiveUserState } from "../src/platform/interfaces/active-user-state"; +import { UserState } from "../src/platform/interfaces/user-state"; -export class TestUserState implements ActiveUserState { +export class TestUserState implements UserState { private _state$: BehaviorSubject; get state$() { return this._state$.asObservable(); diff --git a/libs/common/src/platform/abstractions/active-user-state.provider.ts b/libs/common/src/platform/abstractions/active-user-state.provider.ts deleted file mode 100644 index 97fa46d26ab..00000000000 --- a/libs/common/src/platform/abstractions/active-user-state.provider.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { ActiveUserState } from "../interfaces/active-user-state"; -import { KeyDefinition } from "../types/key-definition"; - -export abstract class ActiveUserStateProvider { - create: (keyDefinition: KeyDefinition) => ActiveUserState; -} diff --git a/libs/common/src/platform/abstractions/user-state.provider.ts b/libs/common/src/platform/abstractions/user-state.provider.ts new file mode 100644 index 00000000000..8c2c2b4e363 --- /dev/null +++ b/libs/common/src/platform/abstractions/user-state.provider.ts @@ -0,0 +1,6 @@ +import { UserState } from "../interfaces/user-state"; +import { KeyDefinition } from "../types/key-definition"; + +export abstract class UserStateProvider { + create: (keyDefinition: KeyDefinition) => UserState; +} diff --git a/libs/common/src/platform/interfaces/active-user-state.ts b/libs/common/src/platform/interfaces/user-state.ts similarity index 74% rename from libs/common/src/platform/interfaces/active-user-state.ts rename to libs/common/src/platform/interfaces/user-state.ts index e1bb7a34c65..187ea332281 100644 --- a/libs/common/src/platform/interfaces/active-user-state.ts +++ b/libs/common/src/platform/interfaces/user-state.ts @@ -1,9 +1,9 @@ import { Observable } from "rxjs"; -import { DerivedActiveUserState } from "../services/default-active-user-state.provider"; +import { DerivedUserState } from "../services/default-user-state.provider"; import { DerivedStateDefinition } from "../types/derived-state-definition"; -export interface ActiveUserState { +export interface UserState { readonly state$: Observable; readonly getFromState: () => Promise; /** @@ -14,5 +14,5 @@ export interface ActiveUserState { readonly update: (configureState: (state: T) => T) => Promise; createDerived: ( derivedStateDefinition: DerivedStateDefinition - ) => DerivedActiveUserState; + ) => DerivedUserState; } diff --git a/libs/common/src/platform/services/default-active-user-state.provider.spec.ts b/libs/common/src/platform/services/default-user-state.provider.spec.ts similarity index 91% rename from libs/common/src/platform/services/default-active-user-state.provider.spec.ts rename to libs/common/src/platform/services/default-user-state.provider.spec.ts index 5a8b6378c83..664a93573ad 100644 --- a/libs/common/src/platform/services/default-active-user-state.provider.spec.ts +++ b/libs/common/src/platform/services/default-user-state.provider.spec.ts @@ -9,7 +9,7 @@ import { AbstractMemoryStorageService } from "../abstractions/storage.service"; import { KeyDefinition } from "../types/key-definition"; import { StateDefinition } from "../types/state-definition"; -import { DefaultActiveUserStateProvider } from "./default-active-user-state.provider"; +import { DefaultUserStateProvider } from "./default-user-state.provider"; class TestState { date: Date; @@ -42,7 +42,7 @@ describe("DefaultStateProvider", () => { const activeAccountSubject = new BehaviorSubject<{ id: UserId } & AccountInfo>(undefined); - let activeUserStateProvider: DefaultActiveUserStateProvider; + let userStateProvider: DefaultUserStateProvider; beforeEach(() => { mockReset(accountService); @@ -51,7 +51,7 @@ describe("DefaultStateProvider", () => { accountService.activeAccount$ = activeAccountSubject; - activeUserStateProvider = new DefaultActiveUserStateProvider( + userStateProvider = new DefaultUserStateProvider( accountService, null, // Not testing derived state null, // Not testing memory storage @@ -68,7 +68,7 @@ describe("DefaultStateProvider", () => { } as Jsonify); }); - const fakeDomainState = activeUserStateProvider.create(testKeyDefinition); + const fakeDomainState = userStateProvider.create(testKeyDefinition); const subscribeCallback = jest.fn(); const subscription = fakeDomainState.state$.subscribe(subscribeCallback); diff --git a/libs/common/src/platform/services/default-active-user-state.provider.ts b/libs/common/src/platform/services/default-user-state.provider.ts similarity index 84% rename from libs/common/src/platform/services/default-active-user-state.provider.ts rename to libs/common/src/platform/services/default-user-state.provider.ts index abbe2b8ea1c..0c33147773b 100644 --- a/libs/common/src/platform/services/default-active-user-state.provider.ts +++ b/libs/common/src/platform/services/default-user-state.provider.ts @@ -11,13 +11,13 @@ import { import { Jsonify } from "type-fest"; import { AccountService } from "../../auth/abstractions/account.service"; -import { ActiveUserStateProvider } from "../abstractions/active-user-state.provider"; import { EncryptService } from "../abstractions/encrypt.service"; import { AbstractMemoryStorageService, AbstractStorageService, } from "../abstractions/storage.service"; -import { ActiveUserState } from "../interfaces/active-user-state"; +import { UserStateProvider } from "../abstractions/user-state.provider"; +import { UserState } from "../interfaces/user-state"; import { userKeyBuilder } from "../misc/key-builders"; import { UserKey } from "../models/domain/symmetric-crypto-key"; import { KeyDefinition } from "../types/key-definition"; @@ -32,7 +32,7 @@ class DerivedStateDefinition { constructor(readonly converter: (data: TFrom, context: ConverterContext) => Promise) {} } -export class DerivedActiveUserState { +export class DerivedUserState { state$: Observable; // TODO: Probably needs to take state service @@ -42,9 +42,9 @@ export class DerivedActiveUserState { constructor( private derivedStateDefinition: DerivedStateDefinition, private encryptService: EncryptService, - private activeUserState: ActiveUserState + private userState: UserState ) { - this.state$ = activeUserState.state$.pipe( + this.state$ = userState.state$.pipe( switchMap(async (from) => { // TODO: How do I get the key? const convertedData = await derivedStateDefinition.converter( @@ -57,7 +57,7 @@ export class DerivedActiveUserState { } async getFromState(): Promise { - const encryptedFromState = await this.activeUserState.getFromState(); + const encryptedFromState = await this.userState.getFromState(); const context = new ConverterContext(null, this.encryptService); @@ -66,7 +66,7 @@ export class DerivedActiveUserState { } } -class DefaultActiveUserState implements ActiveUserState { +class DefaultUserState implements UserState { private seededInitial = false; private formattedKey$: Observable; @@ -154,8 +154,8 @@ class DefaultActiveUserState implements ActiveUserState { createDerived( derivedStateDefinition: DerivedStateDefinition - ): DerivedActiveUserState { - return new DerivedActiveUserState(derivedStateDefinition, this.encryptService, this); + ): DerivedUserState { + return new DerivedUserState(derivedStateDefinition, this.encryptService, this); } private async createKey(): Promise { @@ -184,8 +184,8 @@ class DefaultActiveUserState implements ActiveUserState { } } -export class DefaultActiveUserStateProvider implements ActiveUserStateProvider { - private userStateCache: Record> = {}; +export class DefaultUserStateProvider implements UserStateProvider { + private userStateCache: Record> = {}; constructor( private accountService: AccountService, // Inject the lightest weight service that provides accountUserId$ @@ -195,16 +195,16 @@ export class DefaultActiveUserStateProvider implements ActiveUserStateProvider { private secureStorage: AbstractStorageService ) {} - create(keyDefinition: KeyDefinition): DefaultActiveUserState { + create(keyDefinition: KeyDefinition): DefaultUserState { const locationDomainKey = `${keyDefinition.stateDefinition.storageLocation}_${keyDefinition.stateDefinition.name}_${keyDefinition.key}`; - const existingActiveUserState = this.userStateCache[locationDomainKey]; - if (existingActiveUserState != null) { + const existingUserState = this.userStateCache[locationDomainKey]; + if (existingUserState != null) { // I have to cast out of the unknown generic but this should be safe if rules // around domain token are made - return existingActiveUserState as DefaultActiveUserState; + return existingUserState as DefaultUserState; } - const newActiveUserState = new DefaultActiveUserState( + const newUserState = new DefaultUserState( keyDefinition, this.accountService, this.encryptService, @@ -212,7 +212,7 @@ export class DefaultActiveUserStateProvider implements ActiveUserStateProvider { this.secureStorage, this.diskStorage ); - this.userStateCache[locationDomainKey] = newActiveUserState; - return newActiveUserState; + this.userStateCache[locationDomainKey] = newUserState; + return newUserState; } } diff --git a/libs/common/src/vault/services/folder/folder.service.spec.ts b/libs/common/src/vault/services/folder/folder.service.spec.ts index c82d6f8b48d..376ee52d7d6 100644 --- a/libs/common/src/vault/services/folder/folder.service.spec.ts +++ b/libs/common/src/vault/services/folder/folder.service.spec.ts @@ -3,14 +3,14 @@ import { Arg, Substitute, SubstituteOf } from "@fluffy-spoon/substitute"; import { mock } from "jest-mock-extended"; import { BehaviorSubject, firstValueFrom } from "rxjs"; -import { TestUserState as TestActiveUserState } from "../../../../spec/test-active-user-state"; -import { ActiveUserStateProvider } from "../../../platform/abstractions/active-user-state.provider"; +import { TestUserState } from "../../../../spec/test-active-user-state"; import { CryptoService } from "../../../platform/abstractions/crypto.service"; import { EncryptService } from "../../../platform/abstractions/encrypt.service"; import { I18nService } from "../../../platform/abstractions/i18n.service"; +import { UserStateProvider } from "../../../platform/abstractions/user-state.provider"; import { EncString } from "../../../platform/models/domain/enc-string"; import { ContainerService } from "../../../platform/services/container.service"; -import { DerivedActiveUserState } from "../../../platform/services/default-active-user-state.provider"; +import { DerivedUserState } from "../../../platform/services/default-user-state.provider"; import { StateService } from "../../../platform/services/state.service"; import { CipherService } from "../../abstractions/cipher.service"; import { FolderData } from "../../models/data/folder.data"; @@ -28,10 +28,9 @@ describe("Folder Service", () => { let stateService: SubstituteOf; let activeAccount: BehaviorSubject; let activeAccountUnlocked: BehaviorSubject; - const activeUserStateProvider = mock(); - let activeUserState: TestActiveUserState>; - const derivedActiveUserState = - mock, FolderView[]>>(); + const userStateProvider = mock(); + let userState: TestUserState>; + const derivedUserState = mock, FolderView[]>>(); let folderViews$: BehaviorSubject; beforeEach(() => { @@ -51,19 +50,19 @@ describe("Folder Service", () => { stateService.activeAccountUnlocked$.returns(activeAccountUnlocked); (window as any).bitwardenContainerService = new ContainerService(cryptoService, encryptService); - activeUserState = new TestActiveUserState({}); - activeUserState.next(initialState); - activeUserStateProvider.create.mockReturnValue(activeUserState); - activeUserState.createDerived.mockReturnValue(derivedActiveUserState); + userState = new TestUserState({}); + userState.next(initialState); + userStateProvider.create.mockReturnValue(userState); + userState.createDerived.mockReturnValue(derivedUserState); folderViews$ = new BehaviorSubject([]); - derivedActiveUserState.state$ = folderViews$; + derivedUserState.state$ = folderViews$; folderService = new FolderService( cryptoService, i18nService, cipherService, - activeUserStateProvider, + userStateProvider, stateService ); }); @@ -71,7 +70,7 @@ describe("Folder Service", () => { afterEach(() => { jest.resetAllMocks(); folderViews$.complete(); - activeUserState.complete(); + userState.complete(); }); test("encrypt", async () => { diff --git a/libs/common/src/vault/services/folder/folder.service.ts b/libs/common/src/vault/services/folder/folder.service.ts index 2a74af53969..3930bd11b20 100644 --- a/libs/common/src/vault/services/folder/folder.service.ts +++ b/libs/common/src/vault/services/folder/folder.service.ts @@ -1,13 +1,13 @@ import { Observable, firstValueFrom, map } from "rxjs"; -import { ActiveUserStateProvider } from "../../../platform/abstractions/active-user-state.provider"; import { CryptoService } from "../../../platform/abstractions/crypto.service"; import { I18nService } from "../../../platform/abstractions/i18n.service"; import { StateService } from "../../../platform/abstractions/state.service"; -import { ActiveUserState } from "../../../platform/interfaces/active-user-state"; +import { UserStateProvider } from "../../../platform/abstractions/user-state.provider"; +import { UserState } from "../../../platform/interfaces/user-state"; import { Utils } from "../../../platform/misc/utils"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; -import { DerivedActiveUserState } from "../../../platform/services/default-active-user-state.provider"; +import { DerivedUserState } from "../../../platform/services/default-user-state.provider"; import { CipherService } from "../../../vault/abstractions/cipher.service"; import { InternalFolderService as InternalFolderServiceAbstraction } from "../../../vault/abstractions/folder/folder.service.abstraction"; import { CipherData } from "../../../vault/models/data/cipher.data"; @@ -17,8 +17,8 @@ import { FolderView } from "../../../vault/models/view/folder.view"; import { FOLDERS } from "../../types/key-definitions"; export class FolderService implements InternalFolderServiceAbstraction { - folderState: ActiveUserState>; - decryptedFolderState: DerivedActiveUserState, FolderView[]>; + folderState: UserState>; + decryptedFolderState: DerivedUserState, FolderView[]>; folders$: Observable; folderViews$: Observable; @@ -27,7 +27,7 @@ export class FolderService implements InternalFolderServiceAbstraction { private cryptoService: CryptoService, private i18nService: I18nService, private cipherService: CipherService, - private activeUserStateProvider: ActiveUserStateProvider, + private userStateProvider: UserStateProvider, private stateService: StateService ) { (window as any).services ||= {}; @@ -41,7 +41,7 @@ export class FolderService implements InternalFolderServiceAbstraction { } ); - this.folderState = this.activeUserStateProvider.create(FOLDERS); + this.folderState = this.userStateProvider.create(FOLDERS); this.folders$ = this.folderState.state$.pipe( map((foldersMap) => {