From a32f745c99ca3a088d634fc5a0e2e4f97b539e9c Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Fri, 11 Jul 2025 19:43:10 +0200 Subject: [PATCH] [PM-22781] Implement autoconnect to desktop app on app start (#15266) * Implement autoconnect to desktop app on app start * Update apps/browser/src/background/nativeMessaging.background.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Silence errors and only connect while popup is not open * Run autoconnect regardless of popup being open --------- Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> --- .../background/nativeMessaging.background.ts | 10 ++++++++ .../background-browser-biometrics.service.ts | 25 +++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/apps/browser/src/background/nativeMessaging.background.ts b/apps/browser/src/background/nativeMessaging.background.ts index 03876dba673..66a929c47a1 100644 --- a/apps/browser/src/background/nativeMessaging.background.ts +++ b/apps/browser/src/background/nativeMessaging.background.ts @@ -105,6 +105,16 @@ export class NativeMessagingBackground { } async connect() { + if (!(await BrowserApi.permissionsGranted(["nativeMessaging"]))) { + this.logService.warning( + "[Native Messaging IPC] Native messaging permission is missing for biometrics", + ); + return; + } + if (this.connected || this.connecting) { + return; + } + this.logService.info("[Native Messaging IPC] Connecting to Bitwarden Desktop app..."); const appId = await this.appIdService.getAppId(); this.appId = appId; diff --git a/apps/browser/src/key-management/biometrics/background-browser-biometrics.service.ts b/apps/browser/src/key-management/biometrics/background-browser-biometrics.service.ts index 677f58dee11..8f755cfeda6 100644 --- a/apps/browser/src/key-management/biometrics/background-browser-biometrics.service.ts +++ b/apps/browser/src/key-management/biometrics/background-browser-biometrics.service.ts @@ -1,3 +1,6 @@ +import { combineLatest, timer } from "rxjs"; +import { filter, concatMap } from "rxjs/operators"; + import { VaultTimeoutSettingsService } from "@bitwarden/common/key-management/vault-timeout"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; @@ -17,6 +20,8 @@ import { NativeMessagingBackground } from "../../background/nativeMessaging.back import { BrowserApi } from "../../platform/browser/browser-api"; export class BackgroundBrowserBiometricsService extends BiometricsService { + BACKGROUND_POLLING_INTERVAL = 30_000; + constructor( private nativeMessagingBackground: () => NativeMessagingBackground, private logService: LogService, @@ -26,6 +31,24 @@ export class BackgroundBrowserBiometricsService extends BiometricsService { private vaultTimeoutSettingsService: VaultTimeoutSettingsService, ) { super(); + // Always connect to the native messaging background if biometrics are enabled, not just when it is used + // so that there is no wait when used. + const biometricsEnabled = this.biometricStateService.biometricUnlockEnabled$; + + combineLatest([timer(0, this.BACKGROUND_POLLING_INTERVAL), biometricsEnabled]) + .pipe( + filter(([_, enabled]) => enabled), + filter(([_]) => !this.nativeMessagingBackground().connected), + concatMap(async () => { + try { + await this.nativeMessagingBackground().connect(); + await this.getBiometricsStatus(); + } catch { + // Ignore + } + }), + ) + .subscribe(); } async authenticateWithBiometrics(): Promise { @@ -48,8 +71,6 @@ export class BackgroundBrowserBiometricsService extends BiometricsService { } try { - await this.ensureConnected(); - const response = await this.nativeMessagingBackground().callCommand({ command: BiometricsCommands.GetBiometricsStatus, });