mirror of
https://github.com/bitwarden/browser
synced 2025-12-20 10:13:31 +00:00
[bug] Allow for GlobalState to be extended and modified in clients (#646)
Some clients have unique global setting defaults (and unique global settings) For example: the web vault defaults to light theme, but most clients with theme support default to system theme. The current way we handle GlobalState is buried in jslib and not easily extendible in clients. To fix this, we need to treat GlobalState as a generic in the StateService and StateMigration service and allow for its extension in those methods and anywhere GlobalState is inited.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { StateService as StateServiceAbstraction } from "../abstractions/state.service";
|
||||
|
||||
import { Account, AccountData, AccountFactory } from "../models/domain/account";
|
||||
import { Account, AccountData } from "../models/domain/account";
|
||||
|
||||
import { LogService } from "../abstractions/log.service";
|
||||
import { StorageService } from "../abstractions/storage.service";
|
||||
@@ -39,6 +39,8 @@ import { StateMigrationService } from "../abstractions/stateMigration.service";
|
||||
import { EnvironmentUrls } from "../models/domain/environmentUrls";
|
||||
import { WindowState } from "../models/domain/windowState";
|
||||
|
||||
import { StateFactory } from "../factories/stateFactory";
|
||||
|
||||
const keys = {
|
||||
global: "global",
|
||||
authenticatedAccounts: "authenticatedAccounts",
|
||||
@@ -52,13 +54,17 @@ const partialKeys = {
|
||||
masterKey: "_masterkey",
|
||||
};
|
||||
|
||||
export class StateService<TAccount extends Account = Account>
|
||||
implements StateServiceAbstraction<TAccount>
|
||||
export class StateService<
|
||||
TAccount extends Account = Account,
|
||||
TGlobalState extends GlobalState = GlobalState
|
||||
> implements StateServiceAbstraction<TAccount>
|
||||
{
|
||||
accounts = new BehaviorSubject<{ [userId: string]: TAccount }>({});
|
||||
activeAccount = new BehaviorSubject<string>(null);
|
||||
|
||||
protected state: State<TAccount> = new State<TAccount>();
|
||||
protected state: State<TAccount, TGlobalState> = new State<TAccount, TGlobalState>(
|
||||
this.createGlobals()
|
||||
);
|
||||
|
||||
private hasBeenInited: boolean = false;
|
||||
|
||||
@@ -67,7 +73,7 @@ export class StateService<TAccount extends Account = Account>
|
||||
protected secureStorageService: StorageService,
|
||||
protected logService: LogService,
|
||||
protected stateMigrationService: StateMigrationService,
|
||||
protected accountFactory: AccountFactory<TAccount>
|
||||
protected stateFactory: StateFactory<TAccount, TGlobalState>
|
||||
) {}
|
||||
|
||||
async init(): Promise<void> {
|
||||
@@ -2086,8 +2092,8 @@ export class StateService<TAccount extends Account = Account>
|
||||
);
|
||||
}
|
||||
|
||||
protected async getGlobals(options: StorageOptions): Promise<GlobalState> {
|
||||
let globals: GlobalState;
|
||||
protected async getGlobals(options: StorageOptions): Promise<TGlobalState> {
|
||||
let globals: TGlobalState;
|
||||
if (this.useMemory(options.storageLocation)) {
|
||||
globals = this.getGlobalsFromMemory();
|
||||
}
|
||||
@@ -2096,28 +2102,28 @@ export class StateService<TAccount extends Account = Account>
|
||||
globals = await this.getGlobalsFromDisk(options);
|
||||
}
|
||||
|
||||
return globals ?? new GlobalState();
|
||||
return globals ?? this.createGlobals();
|
||||
}
|
||||
|
||||
protected async saveGlobals(globals: GlobalState, options: StorageOptions) {
|
||||
protected async saveGlobals(globals: TGlobalState, options: StorageOptions) {
|
||||
return this.useMemory(options.storageLocation)
|
||||
? this.saveGlobalsToMemory(globals)
|
||||
: await this.saveGlobalsToDisk(globals, options);
|
||||
}
|
||||
|
||||
protected getGlobalsFromMemory(): GlobalState {
|
||||
protected getGlobalsFromMemory(): TGlobalState {
|
||||
return this.state.globals;
|
||||
}
|
||||
|
||||
protected async getGlobalsFromDisk(options: StorageOptions): Promise<GlobalState> {
|
||||
return await this.storageService.get<GlobalState>(keys.global, options);
|
||||
protected async getGlobalsFromDisk(options: StorageOptions): Promise<TGlobalState> {
|
||||
return await this.storageService.get<TGlobalState>(keys.global, options);
|
||||
}
|
||||
|
||||
protected saveGlobalsToMemory(globals: GlobalState): void {
|
||||
protected saveGlobalsToMemory(globals: TGlobalState): void {
|
||||
this.state.globals = globals;
|
||||
}
|
||||
|
||||
protected async saveGlobalsToDisk(globals: GlobalState, options: StorageOptions): Promise<void> {
|
||||
protected async saveGlobalsToDisk(globals: TGlobalState, options: StorageOptions): Promise<void> {
|
||||
if (options.useSecureStorage) {
|
||||
await this.secureStorageService.save(keys.global, globals, options);
|
||||
} else {
|
||||
@@ -2412,7 +2418,11 @@ export class StateService<TAccount extends Account = Account>
|
||||
}
|
||||
|
||||
protected createAccount(init: Partial<TAccount> = null): TAccount {
|
||||
return this.accountFactory.create(init);
|
||||
return this.stateFactory.createAccount(init);
|
||||
}
|
||||
|
||||
protected createGlobals(init: Partial<TGlobalState> = null): TGlobalState {
|
||||
return this.stateFactory.createGlobal(init);
|
||||
}
|
||||
|
||||
protected async deAuthenticateAccount(userId: string) {
|
||||
|
||||
Reference in New Issue
Block a user