1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-12 22:33:35 +00:00

[PM-7978] Create ForegroundSyncService For Delegating fullSync Calls (#9192)

* Create ForegroundSyncService For Delegating `fullSync` calls to the background

* Relax `isExternalMessage` to Allow For Typed Payload

* Null Coalesce The `startListening` Method

* Filter To Only External Messages
This commit is contained in:
Justin Baur
2024-05-15 12:11:06 -04:00
committed by GitHub
parent 426bacfd67
commit 25f55e1368
7 changed files with 422 additions and 236 deletions

View File

@@ -230,6 +230,8 @@ import { BrowserPlatformUtilsService } from "../platform/services/platform-utils
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 { ForegroundSyncService } from "../platform/sync/foreground-sync.service";
import { SyncServiceListener } from "../platform/sync/sync-service.listener";
import { fromChromeRuntimeMessaging } from "../platform/utils/from-chrome-runtime-messaging";
import VaultTimeoutService from "../services/vault-timeout/vault-timeout.service";
import FilelessImporterBackground from "../tools/background/fileless-importer.background";
@@ -339,6 +341,7 @@ export default class MainBackground {
scriptInjectorService: BrowserScriptInjectorService;
kdfConfigService: kdfConfigServiceAbstraction;
offscreenDocumentService: OffscreenDocumentService;
syncServiceListener: SyncServiceListener;
onUpdatedRan: boolean;
onReplacedRan: boolean;
@@ -792,32 +795,52 @@ export default class MainBackground {
this.providerService = new ProviderService(this.stateProvider);
this.syncService = new SyncService(
this.masterPasswordService,
this.accountService,
this.apiService,
this.domainSettingsService,
this.folderService,
this.cipherService,
this.cryptoService,
this.collectionService,
this.messagingService,
this.policyService,
this.sendService,
this.logService,
this.keyConnectorService,
this.stateService,
this.providerService,
this.folderApiService,
this.organizationService,
this.sendApiService,
this.userDecryptionOptionsService,
this.avatarService,
logoutCallback,
this.billingAccountProfileStateService,
this.tokenService,
this.authService,
);
if (this.popupOnlyContext) {
this.syncService = new ForegroundSyncService(
this.stateService,
this.folderService,
this.folderApiService,
this.messagingService,
this.logService,
this.cipherService,
this.collectionService,
this.apiService,
this.accountService,
this.authService,
this.sendService,
this.sendApiService,
messageListener,
);
} else {
this.syncService = new SyncService(
this.masterPasswordService,
this.accountService,
this.apiService,
this.domainSettingsService,
this.folderService,
this.cipherService,
this.cryptoService,
this.collectionService,
this.messagingService,
this.policyService,
this.sendService,
this.logService,
this.keyConnectorService,
this.stateService,
this.providerService,
this.folderApiService,
this.organizationService,
this.sendApiService,
this.userDecryptionOptionsService,
this.avatarService,
logoutCallback,
this.billingAccountProfileStateService,
this.tokenService,
this.authService,
);
this.syncServiceListener = new SyncServiceListener(this.syncService, messageListener);
}
this.eventUploadService = new EventUploadService(
this.apiService,
this.stateProvider,
@@ -1141,6 +1164,7 @@ export default class MainBackground {
this.contextMenusBackground?.init();
await this.idleBackground.init();
this.webRequestBackground?.startListening();
this.syncServiceListener?.startListening();
return new Promise<void>((resolve) => {
setTimeout(async () => {

View File

@@ -0,0 +1,79 @@
import { firstValueFrom, timeout } from "rxjs";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import {
CommandDefinition,
MessageListener,
MessageSender,
} from "@bitwarden/common/platform/messaging";
import { CoreSyncService } from "@bitwarden/common/platform/sync/internal";
import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction";
import { InternalSendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service";
import { FolderApiServiceAbstraction } from "@bitwarden/common/vault/abstractions/folder/folder-api.service.abstraction";
import { InternalFolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
const SYNC_COMPLETED = new CommandDefinition<{ successfully: boolean }>("syncCompleted");
export const DO_FULL_SYNC = new CommandDefinition<{
forceSync: boolean;
allowThrowOnError: boolean;
}>("doFullSync");
export class ForegroundSyncService extends CoreSyncService {
constructor(
stateService: StateService,
folderService: InternalFolderService,
folderApiService: FolderApiServiceAbstraction,
messageSender: MessageSender,
logService: LogService,
cipherService: CipherService,
collectionService: CollectionService,
apiService: ApiService,
accountService: AccountService,
authService: AuthService,
sendService: InternalSendService,
sendApiService: SendApiService,
private readonly messageListener: MessageListener,
) {
super(
stateService,
folderService,
folderApiService,
messageSender,
logService,
cipherService,
collectionService,
apiService,
accountService,
authService,
sendService,
sendApiService,
);
}
async fullSync(forceSync: boolean, allowThrowOnError: boolean = false): Promise<boolean> {
this.syncInProgress = true;
try {
const syncCompletedPromise = firstValueFrom(
this.messageListener.messages$(SYNC_COMPLETED).pipe(
timeout({
first: 10_000,
with: () => {
throw new Error("Timeout while doing a fullSync call.");
},
}),
),
);
this.messageSender.send(DO_FULL_SYNC, { forceSync, allowThrowOnError });
const result = await syncCompletedPromise;
return result.successfully;
} finally {
this.syncInProgress = false;
}
}
}

View File

@@ -0,0 +1,25 @@
import { Subscription, concatMap, filter } from "rxjs";
import { MessageListener, isExternalMessage } from "@bitwarden/common/platform/messaging";
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
import { DO_FULL_SYNC } from "./foreground-sync.service";
export class SyncServiceListener {
constructor(
private readonly syncService: SyncService,
private readonly messageListener: MessageListener,
) {}
startListening(): Subscription {
return this.messageListener
.messages$(DO_FULL_SYNC)
.pipe(
filter((message) => isExternalMessage(message)),
concatMap(async ({ forceSync, allowThrowOnError }) => {
await this.syncService.fullSync(forceSync, allowThrowOnError);
}),
)
.subscribe();
}
}