diff --git a/apps/browser/src/key-management/lock/services/extension-lock-component.service.spec.ts b/apps/browser/src/key-management/lock/services/extension-lock-component.service.spec.ts index 4b0323d5ebe..92830c35aca 100644 --- a/apps/browser/src/key-management/lock/services/extension-lock-component.service.spec.ts +++ b/apps/browser/src/key-management/lock/services/extension-lock-component.service.spec.ts @@ -9,7 +9,12 @@ import { import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout-settings.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { UserId } from "@bitwarden/common/types/guid"; -import { KeyService, BiometricsService, BiometricsStatus } from "@bitwarden/key-management"; +import { + KeyService, + BiometricsService, + BiometricsStatus, + BiometricStateService, +} from "@bitwarden/key-management"; import { UnlockOptions } from "@bitwarden/key-management/angular"; import { BrowserRouterService } from "../../../platform/popup/services/browser-router.service"; @@ -26,6 +31,7 @@ describe("ExtensionLockComponentService", () => { let vaultTimeoutSettingsService: MockProxy; let keyService: MockProxy; let routerService: MockProxy; + let biometricStateService: MockProxy; beforeEach(() => { userDecryptionOptionsService = mock(); @@ -35,6 +41,7 @@ describe("ExtensionLockComponentService", () => { vaultTimeoutSettingsService = mock(); keyService = mock(); routerService = mock(); + biometricStateService = mock(); TestBed.configureTestingModule({ providers: [ @@ -67,6 +74,10 @@ describe("ExtensionLockComponentService", () => { provide: BrowserRouterService, useValue: routerService, }, + { + provide: BiometricStateService, + useValue: biometricStateService, + }, ], }); @@ -306,6 +317,7 @@ describe("ExtensionLockComponentService", () => { platformUtilsService.supportsSecureStorage.mockReturnValue( mockInputs.platformSupportsSecureStorage, ); + biometricStateService.biometricUnlockEnabled$ = of(true); // PIN pinService.isPinDecryptionAvailable.mockResolvedValue(mockInputs.pinDecryptionAvailable); diff --git a/apps/browser/src/key-management/lock/services/extension-lock-component.service.ts b/apps/browser/src/key-management/lock/services/extension-lock-component.service.ts index f21beb91cff..77c0fcaf50a 100644 --- a/apps/browser/src/key-management/lock/services/extension-lock-component.service.ts +++ b/apps/browser/src/key-management/lock/services/extension-lock-component.service.ts @@ -1,14 +1,18 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { inject } from "@angular/core"; -import { combineLatest, defer, map, Observable } from "rxjs"; +import { combineLatest, defer, firstValueFrom, map, Observable } from "rxjs"; import { PinServiceAbstraction, UserDecryptionOptionsServiceAbstraction, } from "@bitwarden/auth/common"; import { UserId } from "@bitwarden/common/types/guid"; -import { BiometricsService, BiometricsStatus } from "@bitwarden/key-management"; +import { + BiometricsService, + BiometricsStatus, + BiometricStateService, +} from "@bitwarden/key-management"; import { LockComponentService, UnlockOptions } from "@bitwarden/key-management/angular"; import { BiometricErrors, BiometricErrorTypes } from "../../../models/biometricErrors"; @@ -19,6 +23,7 @@ export class ExtensionLockComponentService implements LockComponentService { private readonly biometricsService = inject(BiometricsService); private readonly pinService = inject(PinServiceAbstraction); private readonly routerService = inject(BrowserRouterService); + private readonly biometricStateService = inject(BiometricStateService); getPreviousUrl(): string | null { return this.routerService.getPreviousUrl(); @@ -45,7 +50,13 @@ export class ExtensionLockComponentService implements LockComponentService { getAvailableUnlockOptions$(userId: UserId): Observable { return combineLatest([ // Note: defer is preferable b/c it delays the execution of the function until the observable is subscribed to - defer(async () => await this.biometricsService.getBiometricsStatusForUser(userId)), + defer(async () => { + if (!(await firstValueFrom(this.biometricStateService.biometricUnlockEnabled$))) { + return BiometricsStatus.NotEnabledLocally; + } else { + return await this.biometricsService.getBiometricsStatusForUser(userId); + } + }), this.userDecryptionOptionsService.userDecryptionOptionsById$(userId), defer(() => this.pinService.isPinDecryptionAvailable(userId)), ]).pipe(