diff --git a/apps/browser/src/key-management/biometrics/foreground-browser-biometrics.ts b/apps/browser/src/key-management/biometrics/foreground-browser-biometrics.ts index 43cc25e4dad..d248a630cc6 100644 --- a/apps/browser/src/key-management/biometrics/foreground-browser-biometrics.ts +++ b/apps/browser/src/key-management/biometrics/foreground-browser-biometrics.ts @@ -1,3 +1,4 @@ +import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { UserId } from "@bitwarden/common/types/guid"; import { UserKey } from "@bitwarden/common/types/key"; import { BiometricsCommands, BiometricsService, BiometricsStatus } from "@bitwarden/key-management"; @@ -34,7 +35,7 @@ export class ForegroundBrowserBiometricsService extends BiometricsService { if (!response.result) { return null; } - return response.result; + return SymmetricCryptoKey.fromString(response.result.keyB64) as UserKey; } async getBiometricsStatusForUser(id: UserId): Promise { diff --git a/apps/browser/src/popup/app.component.ts b/apps/browser/src/popup/app.component.ts index e8a660620a9..7b6e402a90f 100644 --- a/apps/browser/src/popup/app.component.ts +++ b/apps/browser/src/popup/app.component.ts @@ -21,7 +21,7 @@ import { ToastOptions, ToastService, } from "@bitwarden/components"; -import { BiometricStateService } from "@bitwarden/key-management"; +import { BiometricsService, BiometricStateService } from "@bitwarden/key-management"; import { PopupCompactModeService } from "../platform/popup/layout/popup-compact-mode.service"; import { PopupViewCacheService } from "../platform/popup/view-cache/popup-view-cache.service"; @@ -66,6 +66,7 @@ export class AppComponent implements OnInit, OnDestroy { private accountService: AccountService, private animationControlService: AnimationControlService, private biometricStateService: BiometricStateService, + private biometricsService: BiometricsService, ) {} async ngOnInit() { @@ -102,7 +103,7 @@ export class AppComponent implements OnInit, OnDestroy { this.messageListener.allMessages$ .pipe( - tap((msg: any) => { + tap(async (msg: any) => { if (msg.command === "doneLoggingOut") { // TODO: PM-8544 - why do we call logout in the popup after receiving the doneLoggingOut message? Hasn't this already completeted logout? this.authService.logOut(async () => { @@ -119,6 +120,7 @@ export class AppComponent implements OnInit, OnDestroy { msg.command === "locked" && (msg.userId == null || msg.userId == this.activeUserId) ) { + await this.biometricsService.setShouldAutopromptNow(false); // 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.router.navigate(["lock"]); diff --git a/libs/common/src/key-management/services/default-process-reload.service.ts b/libs/common/src/key-management/services/default-process-reload.service.ts index 3f099b77328..9f97e0a94c1 100644 --- a/libs/common/src/key-management/services/default-process-reload.service.ts +++ b/libs/common/src/key-management/services/default-process-reload.service.ts @@ -39,6 +39,9 @@ export class DefaultProcessReloadService implements ProcessReloadServiceAbstract let status = await firstValueFrom(authService.authStatusFor$(userId as UserId)); status = await authService.getAuthStatus(userId); if (status === AuthenticationStatus.Unlocked) { + this.logService.info( + "[Process Reload Service] User unlocked, preventing process reload", + ); return; } } @@ -55,6 +58,9 @@ export class DefaultProcessReloadService implements ProcessReloadServiceAbstract if (userId != null) { const ephemeralPin = await this.pinService.getPinKeyEncryptedUserKeyEphemeral(userId); if (ephemeralPin != null) { + this.logService.info( + "[Process Reload Service] Ephemeral pin active, preventing process reload", + ); return; } } @@ -97,7 +103,12 @@ export class DefaultProcessReloadService implements ProcessReloadServiceAbstract await this.reloadCallback(); } return; + } else { + this.logService.info( + "[Process Reload Service] Desktop ipc fingerprint validated, preventing process reload", + ); } + if (this.reloadInterval == null) { this.reloadInterval = setInterval(async () => await this.executeProcessReload(), 1000); } diff --git a/libs/key-management/src/angular/lock/components/lock.component.ts b/libs/key-management/src/angular/lock/components/lock.component.ts index 23f1a7a4330..6c912b0eaae 100644 --- a/libs/key-management/src/angular/lock/components/lock.component.ts +++ b/libs/key-management/src/angular/lock/components/lock.component.ts @@ -307,10 +307,12 @@ export class LockComponent implements OnInit, OnDestroy { (await this.biometricService.getShouldAutopromptNow()) ) { await this.biometricService.setShouldAutopromptNow(false); + + const lastProcessReload = await this.biometricStateService.getLastProcessReload(); if ( - (await this.biometricStateService.getLastProcessReload()) == null || - Date.now() - (await this.biometricStateService.getLastProcessReload()).getTime() > - AUTOPROMPT_BIOMETRICS_PROCESS_RELOAD_DELAY + lastProcessReload == null || + isNaN(lastProcessReload.getTime()) || + Date.now() - lastProcessReload.getTime() > AUTOPROMPT_BIOMETRICS_PROCESS_RELOAD_DELAY ) { await this.unlockViaBiometrics(); }