Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DO NOT MERGE] QA Test branch for biometrics fixes #12801

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ export class AccountSecurityComponent implements OnInit, OnDestroy {
switchMap(async () => {
const status = await this.biometricsService.getBiometricsStatusForUser(activeAccount.id);
const biometricSettingAvailable =
!(await BrowserApi.permissionsGranted(["nativeMessaging"])) ||
(status !== BiometricsStatus.DesktopDisconnected &&
status !== BiometricsStatus.NotEnabledInConnectedDesktopApp) ||
(await this.vaultTimeoutSettingsService.isBiometricLockSet());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -26,6 +31,7 @@ describe("ExtensionLockComponentService", () => {
let vaultTimeoutSettingsService: MockProxy<VaultTimeoutSettingsService>;
let keyService: MockProxy<KeyService>;
let routerService: MockProxy<BrowserRouterService>;
let biometricStateService: MockProxy<BiometricStateService>;

beforeEach(() => {
userDecryptionOptionsService = mock<UserDecryptionOptionsServiceAbstraction>();
Expand All @@ -35,6 +41,7 @@ describe("ExtensionLockComponentService", () => {
vaultTimeoutSettingsService = mock<VaultTimeoutSettingsService>();
keyService = mock<KeyService>();
routerService = mock<BrowserRouterService>();
biometricStateService = mock<BiometricStateService>();

TestBed.configureTestingModule({
providers: [
Expand Down Expand Up @@ -67,6 +74,10 @@ describe("ExtensionLockComponentService", () => {
provide: BrowserRouterService,
useValue: routerService,
},
{
provide: BiometricStateService,
useValue: biometricStateService,
},
],
});

Expand Down Expand Up @@ -306,6 +317,7 @@ describe("ExtensionLockComponentService", () => {
platformUtilsService.supportsSecureStorage.mockReturnValue(
mockInputs.platformSupportsSecureStorage,
);
biometricStateService.biometricUnlockEnabled$ = of(true);

// PIN
pinService.isPinDecryptionAvailable.mockResolvedValue(mockInputs.pinDecryptionAvailable);
Expand Down
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -19,6 +23,7 @@
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();
Expand All @@ -45,7 +50,20 @@
getAvailableUnlockOptions$(userId: UserId): Observable<UnlockOptions> {
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;

Check warning on line 55 in apps/browser/src/key-management/lock/services/extension-lock-component.service.ts

View check run for this annotation

Codecov / codecov/patch

apps/browser/src/key-management/lock/services/extension-lock-component.service.ts#L55

Added line #L55 was not covered by tests
} else {
// remove after backward compatibility code for old biometrics ipc protocol is removed
const result: BiometricsStatus = (await Promise.race([
this.biometricsService.getBiometricsStatusForUser(userId),
new Promise((resolve) =>
setTimeout(() => resolve(BiometricsStatus.DesktopDisconnected), 1000),
),
])) as BiometricsStatus;
return result;
}
}),
this.userDecryptionOptionsService.userDecryptionOptionsById$(userId),
defer(() => this.pinService.isPinDecryptionAvailable(userId)),
]).pipe(
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/app/accounts/settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
const skipSupportedPlatformCheck =
ipc.platform.allowBrowserintegrationOverride || ipc.platform.isDev;

if (skipSupportedPlatformCheck) {
if (!skipSupportedPlatformCheck) {
if (
ipc.platform.deviceType === DeviceType.MacOsDesktop &&
!this.platformUtilsService.isMacAppStore()
Expand Down
Loading