1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-21 10:43:35 +00:00

[PM-10741] Refactor biometrics interface & add dynamic status (#10973)

This commit is contained in:
Bernd Schoolmann
2025-01-08 10:46:00 +01:00
committed by GitHub
parent 0bd988dac8
commit 72121cda94
66 changed files with 1840 additions and 1459 deletions

View File

@@ -22,7 +22,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service"
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { KeySuffixOptions, ThemeType } from "@bitwarden/common/platform/enums";
import { ThemeType } from "@bitwarden/common/platform/enums/theme-type.enum";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service";
import { UserId } from "@bitwarden/common/types/guid";
@@ -32,10 +32,11 @@ import {
VaultTimeoutStringType,
} from "@bitwarden/common/types/vault-timeout.type";
import { DialogService } from "@bitwarden/components";
import { KeyService, BiometricsService, BiometricStateService } from "@bitwarden/key-management";
import { KeyService, BiometricStateService, BiometricsStatus } from "@bitwarden/key-management";
import { SetPinComponent } from "../../auth/components/set-pin.component";
import { DesktopAutofillSettingsService } from "../../autofill/services/desktop-autofill-settings.service";
import { DesktopBiometricsService } from "../../key-management/biometrics/desktop.biometrics.service";
import { DesktopSettingsService } from "../../platform/services/desktop-settings.service";
import { NativeMessagingManifestService } from "../services/native-messaging-manifest.service";
@@ -54,6 +55,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
themeOptions: any[];
clearClipboardOptions: any[];
supportsBiometric: boolean;
private timerId: any;
showAlwaysShowDock = false;
requireEnableTray = false;
showDuckDuckGoIntegrationOption = false;
@@ -139,7 +141,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
private userVerificationService: UserVerificationServiceAbstraction,
private desktopSettingsService: DesktopSettingsService,
private biometricStateService: BiometricStateService,
private biometricsService: BiometricsService,
private biometricsService: DesktopBiometricsService,
private desktopAutofillSettingsService: DesktopAutofillSettingsService,
private pinService: PinServiceAbstraction,
private logService: LogService,
@@ -297,7 +299,6 @@ export class SettingsComponent implements OnInit, OnDestroy {
// Non-form values
this.showMinToTray = this.platformUtilsService.getDevice() !== DeviceType.LinuxDesktop;
this.showAlwaysShowDock = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop;
this.supportsBiometric = await this.biometricsService.supportsBiometric();
this.previousVaultTimeout = this.form.value.vaultTimeout;
this.refreshTimeoutSettings$
@@ -360,6 +361,13 @@ export class SettingsComponent implements OnInit, OnDestroy {
this.form.controls.enableBrowserIntegrationFingerprint.disable();
}
});
this.supportsBiometric =
(await this.biometricsService.getBiometricsStatus()) === BiometricsStatus.Available;
this.timerId = setInterval(async () => {
this.supportsBiometric =
(await this.biometricsService.getBiometricsStatus()) === BiometricsStatus.Available;
}, 1000);
}
async saveVaultTimeout(newValue: VaultTimeout) {
@@ -476,23 +484,20 @@ export class SettingsComponent implements OnInit, OnDestroy {
return;
}
const needsSetup = await this.biometricsService.biometricsNeedsSetup();
const supportsBiometricAutoSetup = await this.biometricsService.biometricsSupportsAutoSetup();
const status = await this.biometricsService.getBiometricsStatus();
if (needsSetup) {
if (supportsBiometricAutoSetup) {
await this.biometricsService.biometricsSetup();
} else {
const confirmed = await this.dialogService.openSimpleDialog({
title: { key: "biometricsManualSetupTitle" },
content: { key: "biometricsManualSetupDesc" },
type: "warning",
});
if (confirmed) {
this.platformUtilsService.launchUri("https://bitwarden.com/help/biometrics/");
}
return;
if (status === BiometricsStatus.AutoSetupNeeded) {
await this.biometricsService.setupBiometrics();
} else if (status === BiometricsStatus.ManualSetupNeeded) {
const confirmed = await this.dialogService.openSimpleDialog({
title: { key: "biometricsManualSetupTitle" },
content: { key: "biometricsManualSetupDesc" },
type: "warning",
});
if (confirmed) {
this.platformUtilsService.launchUri("https://bitwarden.com/help/biometrics/");
}
return;
}
await this.biometricStateService.setBiometricUnlockEnabled(true);
@@ -513,8 +518,13 @@ export class SettingsComponent implements OnInit, OnDestroy {
}
await this.keyService.refreshAdditionalKeys();
const activeUserId = await firstValueFrom(
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
);
// Validate the key is stored in case biometrics fail.
const biometricSet = await this.keyService.hasUserKeyStored(KeySuffixOptions.Biometric);
const biometricSet =
(await this.biometricsService.getBiometricsStatusForUser(activeUserId)) ===
BiometricsStatus.Available;
this.form.controls.biometric.setValue(biometricSet, { emitEvent: false });
if (!biometricSet) {
await this.biometricStateService.setBiometricUnlockEnabled(false);
@@ -779,6 +789,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
clearInterval(this.timerId);
}
get biometricText() {