1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 08:13:42 +00:00

[PM-10754] Store DeviceKey In Backup Storage Location (#10469)

* Implement Backup Storage Location For Browser Disk

* Remove Testing Change

* Remove Comment

* Add Comment For `disk-backup-local-storage`

* Require Matching `valuesRequireDeserialization` values
This commit is contained in:
Justin Baur
2024-08-12 13:29:22 -04:00
committed by GitHub
parent 334601e74f
commit a7adf952db
12 changed files with 164 additions and 8 deletions

View File

@@ -143,6 +143,8 @@ import { DefaultStateProvider } from "@bitwarden/common/platform/state/implement
import { InlineDerivedStateProvider } from "@bitwarden/common/platform/state/implementations/inline-derived-state";
import { StateEventRegistrarService } from "@bitwarden/common/platform/state/state-event-registrar.service";
/* eslint-enable import/no-restricted-paths */
import { PrimarySecondaryStorageService } from "@bitwarden/common/platform/storage/primary-secondary-storage.service";
import { WindowStorageService } from "@bitwarden/common/platform/storage/window-storage.service";
import { SyncService } from "@bitwarden/common/platform/sync";
// eslint-disable-next-line no-restricted-imports -- Needed for service creation
import { DefaultSyncService } from "@bitwarden/common/platform/sync/internal";
@@ -239,6 +241,7 @@ import { ForegroundTaskSchedulerService } from "../platform/services/task-schedu
import { BackgroundMemoryStorageService } from "../platform/storage/background-memory-storage.service";
import { BrowserStorageServiceProvider } from "../platform/storage/browser-storage-service.provider";
import { ForegroundMemoryStorageService } from "../platform/storage/foreground-memory-storage.service";
import { OffscreenStorageService } from "../platform/storage/offscreen-storage.service";
import { ForegroundSyncService } from "../platform/sync/foreground-sync.service";
import { SyncServiceListener } from "../platform/sync/sync-service.listener";
import { fromChromeRuntimeMessaging } from "../platform/utils/from-chrome-runtime-messaging";
@@ -485,10 +488,15 @@ export default class MainBackground {
? mv3MemoryStorageCreator() // mv3 stores to local-backed session storage
: this.memoryStorageForStateProviders; // mv2 stores to the same location
const localStorageStorageService = BrowserApi.isManifestVersion(3)
? new OffscreenStorageService(this.offscreenDocumentService)
: new WindowStorageService(self.localStorage);
const storageServiceProvider = new BrowserStorageServiceProvider(
this.storageService,
this.memoryStorageForStateProviders,
this.largeObjectMemoryStorageForStateProviders,
new PrimarySecondaryStorageService(this.storageService, localStorageStorageService),
);
this.globalStateProvider = new DefaultGlobalStateProvider(

View File

@@ -14,6 +14,9 @@ class OffscreenDocument implements OffscreenDocumentInterface {
private readonly extensionMessageHandlers: OffscreenDocumentExtensionMessageHandlers = {
offscreenCopyToClipboard: ({ message }) => this.handleOffscreenCopyToClipboard(message),
offscreenReadFromClipboard: () => this.handleOffscreenReadFromClipboard(),
localStorageGet: ({ message }) => this.handleLocalStorageGet(message.key),
localStorageSave: ({ message }) => this.handleLocalStorageSave(message.key, message.value),
localStorageRemove: ({ message }) => this.handleLocalStorageRemove(message.key),
};
/**
@@ -39,6 +42,18 @@ class OffscreenDocument implements OffscreenDocumentInterface {
return await BrowserClipboardService.read(self);
}
private handleLocalStorageGet(key: string) {
return self.localStorage.getItem(key);
}
private handleLocalStorageSave(key: string, value: string) {
self.localStorage.setItem(key, value);
}
private handleLocalStorageRemove(key: string) {
self.localStorage.removeItem(key);
}
/**
* Sets up the listener for extension messages.
*/

View File

@@ -14,6 +14,7 @@ export class BrowserStorageServiceProvider extends StorageServiceProvider {
diskStorageService: AbstractStorageService & ObservableStorageService,
limitedMemoryStorageService: AbstractStorageService & ObservableStorageService,
private largeObjectMemoryStorageService: AbstractStorageService & ObservableStorageService,
private readonly diskBackupLocalStorage: AbstractStorageService & ObservableStorageService,
) {
super(diskStorageService, limitedMemoryStorageService);
}
@@ -26,6 +27,8 @@ export class BrowserStorageServiceProvider extends StorageServiceProvider {
switch (location) {
case "memory-large-object":
return ["memory-large-object", this.largeObjectMemoryStorageService];
case "disk-backup-local-storage":
return ["disk-backup-local-storage", this.diskBackupLocalStorage];
default:
// Pass in computed location to super because they could have
// override default "disk" with web "memory".

View File

@@ -0,0 +1,55 @@
import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service";
import { StorageOptions } from "@bitwarden/common/platform/models/domain/storage-options";
import { BrowserApi } from "../browser/browser-api";
import { OffscreenDocumentService } from "../offscreen-document/abstractions/offscreen-document";
export class OffscreenStorageService implements AbstractStorageService {
constructor(private readonly offscreenDocumentService: OffscreenDocumentService) {}
get valuesRequireDeserialization(): boolean {
return true;
}
async get<T>(key: string, options?: StorageOptions): Promise<T> {
return await this.offscreenDocumentService.withDocument<T>(
[chrome.offscreen.Reason.LOCAL_STORAGE],
"backup storage of user data",
async () => {
const response = await BrowserApi.sendMessageWithResponse<string>("localStorageGet", {
key,
});
if (response != null) {
return JSON.parse(response);
}
return response;
},
);
}
async has(key: string, options?: StorageOptions): Promise<boolean> {
return (await this.get(key, options)) != null;
}
async save<T>(key: string, obj: T, options?: StorageOptions): Promise<void> {
await this.offscreenDocumentService.withDocument(
[chrome.offscreen.Reason.LOCAL_STORAGE],
"backup storage of user data",
async () =>
await BrowserApi.sendMessageWithResponse<void>("localStorageSave", {
key,
value: JSON.stringify(obj),
}),
);
}
async remove(key: string, options?: StorageOptions): Promise<void> {
await this.offscreenDocumentService.withDocument(
[chrome.offscreen.Reason.LOCAL_STORAGE],
"backup storage of user data",
async () =>
await BrowserApi.sendMessageWithResponse<void>("localStorageRemove", {
key,
}),
);
}
}

View File

@@ -73,6 +73,8 @@ import {
} from "@bitwarden/common/platform/state";
// eslint-disable-next-line import/no-restricted-paths -- Used for dependency injection
import { InlineDerivedStateProvider } from "@bitwarden/common/platform/state/implementations/inline-derived-state";
import { PrimarySecondaryStorageService } from "@bitwarden/common/platform/storage/primary-secondary-storage.service";
import { WindowStorageService } from "@bitwarden/common/platform/storage/window-storage.service";
import { SyncService } from "@bitwarden/common/platform/sync";
import { VaultTimeoutStringType } from "@bitwarden/common/types/vault-timeout.type";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
@@ -122,6 +124,10 @@ const OBSERVABLE_LARGE_OBJECT_MEMORY_STORAGE = new SafeInjectionToken<
AbstractStorageService & ObservableStorageService
>("OBSERVABLE_LARGE_OBJECT_MEMORY_STORAGE");
const DISK_BACKUP_LOCAL_STORAGE = new SafeInjectionToken<
AbstractStorageService & ObservableStorageService
>("DISK_BACKUP_LOCAL_STORAGE");
const needsBackgroundInit = BrowserPopupUtils.backgroundInitializationRequired();
const mainBackground: MainBackground = needsBackgroundInit
? createLocalBgService()
@@ -496,6 +502,12 @@ const safeProviders: SafeProvider[] = [
},
deps: [],
}),
safeProvider({
provide: DISK_BACKUP_LOCAL_STORAGE,
useFactory: (diskStorage: AbstractStorageService & ObservableStorageService) =>
new PrimarySecondaryStorageService(diskStorage, new WindowStorageService(self.localStorage)),
deps: [OBSERVABLE_DISK_STORAGE],
}),
safeProvider({
provide: StorageServiceProvider,
useClass: BrowserStorageServiceProvider,
@@ -503,6 +515,7 @@ const safeProviders: SafeProvider[] = [
OBSERVABLE_DISK_STORAGE,
OBSERVABLE_MEMORY_STORAGE,
OBSERVABLE_LARGE_OBJECT_MEMORY_STORAGE,
DISK_BACKUP_LOCAL_STORAGE,
],
}),
safeProvider({