1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-15 15:53:27 +00:00

[PM-24677] Slim StateService down so it can be moved to state lib (#16021)

* Slim StateService down so it can be moved to state lib

* Fix accidental import changes

* Add `switchAccount` assertion

* Needs to use mock
This commit is contained in:
Justin Baur
2025-08-18 12:37:25 -04:00
committed by GitHub
parent ea305a0f71
commit 939fd402c3
49 changed files with 286 additions and 1274 deletions

View File

@@ -2,3 +2,4 @@
export * from "./core";
export * from "./state-migrations";
export * from "./types/state";
export * from "./legacy";

View File

@@ -0,0 +1,107 @@
import { firstValueFrom } from "rxjs";
import { StorageService } from "@bitwarden/storage-core";
import { UserId } from "@bitwarden/user-core";
import { ActiveUserAccessor } from "../core";
import { GlobalState } from "./global-state";
import { RequiredUserId, StateService } from "./state.service";
const keys = {
global: "global",
};
const partialKeys = {
userAutoKey: "_user_auto",
userBiometricKey: "_user_biometric",
};
const DDG_SHARED_KEY = "DuckDuckGoSharedKey";
export class DefaultStateService implements StateService {
constructor(
private readonly storageService: StorageService,
private readonly secureStorageService: StorageService,
private readonly activeUserAccessor: ActiveUserAccessor,
) {}
async clean(options: RequiredUserId): Promise<void> {
await this.setUserKeyAutoUnlock(null, options);
await this.clearUserKeyBiometric(options.userId);
}
/**
* user key when using the "never" option of vault timeout
*/
async getUserKeyAutoUnlock(options: RequiredUserId): Promise<string | null> {
if (options.userId == null) {
return null;
}
return await this.secureStorageService.get<string>(
`${options.userId}${partialKeys.userAutoKey}`,
{
userId: options.userId,
keySuffix: "auto",
},
);
}
/**
* user key when using the "never" option of vault timeout
*/
async setUserKeyAutoUnlock(value: string | null, options: RequiredUserId): Promise<void> {
if (options.userId == null) {
return;
}
await this.saveSecureStorageKey(partialKeys.userAutoKey, value, options.userId, "auto");
}
private async clearUserKeyBiometric(userId: UserId): Promise<void> {
if (userId == null) {
return;
}
await this.saveSecureStorageKey(partialKeys.userBiometricKey, null, userId, "biometric");
}
async getDuckDuckGoSharedKey(): Promise<string | null> {
const userId = await this.getActiveUserIdFromStorage();
if (userId == null) {
return null;
}
return await this.secureStorageService.get<string>(DDG_SHARED_KEY);
}
async setDuckDuckGoSharedKey(value: string): Promise<void> {
const userId = await this.getActiveUserIdFromStorage();
if (userId == null) {
return;
}
value == null
? await this.secureStorageService.remove(DDG_SHARED_KEY)
: await this.secureStorageService.save(DDG_SHARED_KEY, value);
}
async setEnableDuckDuckGoBrowserIntegration(value: boolean): Promise<void> {
const globals = (await this.storageService.get<GlobalState>(keys.global)) ?? new GlobalState();
globals.enableDuckDuckGoBrowserIntegration = value;
await this.storageService.save(keys.global, globals);
}
private async getActiveUserIdFromStorage(): Promise<UserId | null> {
return await firstValueFrom(this.activeUserAccessor.activeUserId$);
}
private async saveSecureStorageKey(
key: string,
value: string | null,
userId: UserId,
keySuffix: string,
) {
return value == null
? await this.secureStorageService.remove(`${userId}${key}`, { keySuffix: keySuffix })
: await this.secureStorageService.save(`${userId}${key}`, value, {
keySuffix: keySuffix,
});
}
}

View File

@@ -0,0 +1,3 @@
export class GlobalState {
enableDuckDuckGoBrowserIntegration?: boolean;
}

View File

@@ -0,0 +1,2 @@
export { StateService } from "./state.service";
export { DefaultStateService } from "./default-state.service";

View File

@@ -0,0 +1,25 @@
import { UserId } from "@bitwarden/user-core";
export type RequiredUserId = { userId: UserId };
/**
* This class exists for various legacy reasons, there are likely better things to use than this service.
*/
export abstract class StateService {
abstract clean(options: RequiredUserId): Promise<void>;
/**
* Gets the user's auto key
*/
abstract getUserKeyAutoUnlock(options: RequiredUserId): Promise<string | null>;
/**
* Sets the user's auto key
*/
abstract setUserKeyAutoUnlock(value: string | null, options: RequiredUserId): Promise<void>;
/**
* @deprecated For backwards compatible purposes only, use DesktopAutofillSettingsService
*/
abstract setEnableDuckDuckGoBrowserIntegration(value: boolean): Promise<void>;
abstract getDuckDuckGoSharedKey(): Promise<string | null>;
abstract setDuckDuckGoSharedKey(value: string): Promise<void>;
}