Skip to content

Commit

Permalink
[PM-7541] Move Last Desktop Settings (#9310)
Browse files Browse the repository at this point in the history
* Clone Initial Data In `runMigrator`

- When using test cases, mutating the input data causes problems.

* Migrate `minimizeOnCopy` & `browserIntegrationEnabled`

* Update From Main

* Move Fingerprint Setting

- No Migration Yet

* Add Fingerprint to Migrations

* Convert Messaging to `async`

* Switch to calling `Boolean` for Map Function

* Catch Errors

* Remove LogService
  • Loading branch information
justindbaur committed Jun 6, 2024
1 parent 79968c2 commit ba3d210
Show file tree
Hide file tree
Showing 13 changed files with 394 additions and 164 deletions.
22 changes: 15 additions & 7 deletions apps/desktop/src/app/accounts/settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,17 +278,20 @@ export class SettingsComponent implements OnInit {
approveLoginRequests:
(await this.authRequestService.getAcceptAuthRequests(this.currentUserId)) ?? false,
clearClipboard: await firstValueFrom(this.autofillSettingsService.clearClipboardDelay$),
minimizeOnCopyToClipboard: await this.stateService.getMinimizeOnCopyToClipboard(),
minimizeOnCopyToClipboard: await firstValueFrom(this.desktopSettingsService.minimizeOnCopy$),
enableFavicons: await firstValueFrom(this.domainSettingsService.showFavicons$),
enableTray: await firstValueFrom(this.desktopSettingsService.trayEnabled$),
enableMinToTray: await firstValueFrom(this.desktopSettingsService.minimizeToTray$),
enableCloseToTray: await firstValueFrom(this.desktopSettingsService.closeToTray$),
startToTray: await firstValueFrom(this.desktopSettingsService.startToTray$),
openAtLogin: await firstValueFrom(this.desktopSettingsService.openAtLogin$),
alwaysShowDock: await firstValueFrom(this.desktopSettingsService.alwaysShowDock$),
enableBrowserIntegration: await this.stateService.getEnableBrowserIntegration(),
enableBrowserIntegrationFingerprint:
await this.stateService.getEnableBrowserIntegrationFingerprint(),
enableBrowserIntegration: await firstValueFrom(
this.desktopSettingsService.browserIntegrationEnabled$,
),
enableBrowserIntegrationFingerprint: await firstValueFrom(
this.desktopSettingsService.browserIntegrationFingerprintEnabled$,
),
enableDuckDuckGoBrowserIntegration: await firstValueFrom(
this.desktopAutofillSettingsService.enableDuckDuckGoBrowserIntegration$,
),
Expand Down Expand Up @@ -598,7 +601,10 @@ export class SettingsComponent implements OnInit {
}

async saveMinOnCopyToClipboard() {
await this.stateService.setMinimizeOnCopyToClipboard(this.form.value.minimizeOnCopyToClipboard);
await this.desktopSettingsService.setMinimizeOnCopy(
this.form.value.minimizeOnCopyToClipboard,
this.currentUserId,
);
}

async saveClearClipboard() {
Expand Down Expand Up @@ -656,7 +662,9 @@ export class SettingsComponent implements OnInit {
return;
}

await this.stateService.setEnableBrowserIntegration(this.form.value.enableBrowserIntegration);
await this.desktopSettingsService.setBrowserIntegrationEnabled(
this.form.value.enableBrowserIntegration,
);

const errorResult = await this.nativeMessagingManifestService.generate(
this.form.value.enableBrowserIntegration,
Expand Down Expand Up @@ -703,7 +711,7 @@ export class SettingsComponent implements OnInit {
}

async saveBrowserIntegrationFingerprint() {
await this.stateService.setEnableBrowserIntegrationFingerprint(
await this.desktopSettingsService.setBrowserIntegrationFingerprintEnabled(
this.form.value.enableBrowserIntegrationFingerprint,
);
}
Expand Down
73 changes: 9 additions & 64 deletions apps/desktop/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,13 @@ import * as path from "path";
import { app } from "electron";
import { Subject, firstValueFrom } from "rxjs";

import { LogoutReason } from "@bitwarden/auth/common";
import { TokenService as TokenServiceAbstraction } from "@bitwarden/common/auth/abstractions/token.service";
import { AccountServiceImplementation } from "@bitwarden/common/auth/services/account.service";
import { TokenService } from "@bitwarden/common/auth/services/token.service";
import { ClientType } from "@bitwarden/common/enums";
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
import { KeyGenerationService as KeyGenerationServiceAbstraction } from "@bitwarden/common/platform/abstractions/key-generation.service";
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { DefaultBiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service";
import { StateFactory } from "@bitwarden/common/platform/factories/state-factory";
import { Message, MessageSender } from "@bitwarden/common/platform/messaging";
// eslint-disable-next-line no-restricted-imports -- For dependency creation
import { SubjectMessageSender } from "@bitwarden/common/platform/messaging/internal";
import { GlobalState } from "@bitwarden/common/platform/models/domain/global-state";
import { EncryptServiceImplementation } from "@bitwarden/common/platform/services/cryptography/encrypt.service.implementation";
import { DefaultEnvironmentService } from "@bitwarden/common/platform/services/default-environment.service";
import { KeyGenerationService } from "@bitwarden/common/platform/services/key-generation.service";
import { MemoryStorageService } from "@bitwarden/common/platform/services/memory-storage.service";
import { MigrationBuilderService } from "@bitwarden/common/platform/services/migration-builder.service";
import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner";
Expand All @@ -32,7 +22,6 @@ import { DefaultSingleUserStateProvider } from "@bitwarden/common/platform/state
import { DefaultStateProvider } from "@bitwarden/common/platform/state/implementations/default-state.provider";
import { StateEventRegistrarService } from "@bitwarden/common/platform/state/state-event-registrar.service";
import { MemoryStorageService as MemoryStorageServiceForStateProviders } from "@bitwarden/common/platform/state/storage/memory-storage.service";
import { UserId } from "@bitwarden/common/types/guid";
/* eslint-enable import/no-restricted-paths */

import { DesktopAutofillSettingsService } from "./autofill/services/desktop-autofill-settings.service";
Expand All @@ -43,18 +32,13 @@ import { PowerMonitorMain } from "./main/power-monitor.main";
import { TrayMain } from "./main/tray.main";
import { UpdaterMain } from "./main/updater.main";
import { WindowMain } from "./main/window.main";
import { Account } from "./models/account";
import { BiometricsService, BiometricsServiceAbstraction } from "./platform/main/biometric/index";
import { ClipboardMain } from "./platform/main/clipboard.main";
import { DesktopCredentialStorageListener } from "./platform/main/desktop-credential-storage-listener";
import { MainCryptoFunctionService } from "./platform/main/main-crypto-function.service";
import { DesktopSettingsService } from "./platform/services/desktop-settings.service";
import { ElectronLogMainService } from "./platform/services/electron-log.main.service";
import { ELECTRON_SUPPORTS_SECURE_STORAGE } from "./platform/services/electron-platform-utils.service";
import { ElectronStateService } from "./platform/services/electron-state.service";
import { ElectronStorageService } from "./platform/services/electron-storage.service";
import { I18nMainService } from "./platform/services/i18n.main.service";
import { IllegalSecureStorageService } from "./platform/services/illegal-secure-storage.service";
import { ElectronMainMessagingService } from "./services/electron-main-messaging.service";
import { isMacAppStore } from "./utils";

Expand All @@ -65,15 +49,10 @@ export class Main {
memoryStorageService: MemoryStorageService;
memoryStorageForStateProviders: MemoryStorageServiceForStateProviders;
messagingService: MessageSender;
stateService: StateService;
environmentService: DefaultEnvironmentService;
mainCryptoFunctionService: MainCryptoFunctionService;
desktopCredentialStorageListener: DesktopCredentialStorageListener;
desktopSettingsService: DesktopSettingsService;
migrationRunner: MigrationRunner;
tokenService: TokenServiceAbstraction;
keyGenerationService: KeyGenerationServiceAbstraction;
encryptService: EncryptService;

windowMain: WindowMain;
messagingMain: MessagingMain;
Expand Down Expand Up @@ -162,53 +141,13 @@ export class Main {

this.environmentService = new DefaultEnvironmentService(stateProvider, accountService);

this.mainCryptoFunctionService = new MainCryptoFunctionService();
this.mainCryptoFunctionService.init();

this.keyGenerationService = new KeyGenerationService(this.mainCryptoFunctionService);

this.encryptService = new EncryptServiceImplementation(
this.mainCryptoFunctionService,
this.logService,
true, // log mac failures
);

// Note: secure storage service is not available and should not be called in the main background process.
const illegalSecureStorageService = new IllegalSecureStorageService();

this.tokenService = new TokenService(
singleUserStateProvider,
globalStateProvider,
ELECTRON_SUPPORTS_SECURE_STORAGE,
illegalSecureStorageService,
this.keyGenerationService,
this.encryptService,
this.logService,
async (logoutReason: LogoutReason, userId?: UserId) => {},
);

this.migrationRunner = new MigrationRunner(
this.storageService,
this.logService,
new MigrationBuilderService(),
ClientType.Desktop,
);

// TODO: this state service will have access to on disk storage, but not in memory storage.
// If we could get this to work using the stateService singleton that the rest of the app uses we could save
// ourselves from some hacks, like having to manually update the app menu vs. the menu subscribing to events.
this.stateService = new ElectronStateService(
this.storageService,
null,
this.memoryStorageService,
this.logService,
new StateFactory(GlobalState, Account),
accountService, // will not broadcast logouts. This is a hack until we can remove messaging dependency
this.environmentService,
this.tokenService,
this.migrationRunner,
);

this.desktopSettingsService = new DesktopSettingsService(stateProvider);
const biometricStateService = new DefaultBiometricStateService(stateProvider);

Expand All @@ -220,7 +159,7 @@ export class Main {
(arg) => this.processDeepLink(arg),
(win) => this.trayMain.setupWindowListeners(win),
);
this.messagingMain = new MessagingMain(this, this.stateService, this.desktopSettingsService);
this.messagingMain = new MessagingMain(this, this.desktopSettingsService);
this.updaterMain = new UpdaterMain(this.i18nService, this.windowMain);
this.trayMain = new TrayMain(this.windowMain, this.i18nService, this.desktopSettingsService);

Expand All @@ -231,7 +170,13 @@ export class Main {
);

messageSubject.asObservable().subscribe((message) => {
this.messagingMain.onMessage(message);
void this.messagingMain.onMessage(message).catch((err) => {
this.logService.error(
"Error while handling message",
message?.command ?? "Unknown command",
err,
);
});
});

this.powerMonitorMain = new PowerMonitorMain(this.messagingService);
Expand Down Expand Up @@ -299,7 +244,7 @@ export class Main {
await this.updaterMain.init();

const [browserIntegrationEnabled, ddgIntegrationEnabled] = await Promise.all([
this.stateService.getEnableBrowserIntegration(),
firstValueFrom(this.desktopSettingsService.browserIntegrationEnabled$),
firstValueFrom(this.desktopAutofillSettingsService.enableDuckDuckGoBrowserIntegration$),
]);

Expand Down
22 changes: 12 additions & 10 deletions apps/desktop/src/main/messaging.main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import * as fs from "fs";
import * as path from "path";

import { app, ipcMain } from "electron";

import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { firstValueFrom } from "rxjs";

import { Main } from "../main";
import { DesktopSettingsService } from "../platform/services/desktop-settings.service";
Expand All @@ -17,7 +16,6 @@ export class MessagingMain {

constructor(
private main: Main,
private stateService: StateService,
private desktopSettingsService: DesktopSettingsService,
) {}

Expand All @@ -29,10 +27,13 @@ export class MessagingMain {
const loginSettings = app.getLoginItemSettings();
await this.desktopSettingsService.setOpenAtLogin(loginSettings.openAtLogin);
}
ipcMain.on("messagingService", async (event: any, message: any) => this.onMessage(message));
ipcMain.on(
"messagingService",
async (event: any, message: any) => await this.onMessage(message),
);
}

onMessage(message: any) {
async onMessage(message: any) {
switch (message.command) {
case "scheduleNextSync":
this.scheduleNextSync();
Expand All @@ -44,13 +45,14 @@ export class MessagingMain {
this.updateTrayMenu(message.updateRequest);
break;
case "minimizeOnCopy":
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.stateService.getMinimizeOnCopyToClipboard().then((shouldMinimize) => {
if (shouldMinimize && this.main.windowMain.win !== null) {
{
const shouldMinimizeOnCopy = await firstValueFrom(
this.desktopSettingsService.minimizeOnCopy$,
);
if (shouldMinimizeOnCopy && this.main.windowMain.win !== null) {
this.main.windowMain.win.minimize();
}
});
}
break;
case "showTray":
this.main.trayMain.showTray();
Expand Down
Loading

0 comments on commit ba3d210

Please sign in to comment.