1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-23 11:43:46 +00:00

Rework Desktop Biometrics (#5234)

This commit is contained in:
Matt Gibson
2023-04-18 09:09:47 -04:00
committed by GitHub
parent 4852992662
commit 830af7b06d
55 changed files with 2497 additions and 564 deletions

View File

@@ -9,15 +9,15 @@ import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { StateService } from "@bitwarden/common/abstractions/state.service";
import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { PolicyType } from "@bitwarden/common/admin-console/enums";
import { DeviceType, ThemeType, StorageLocation } from "@bitwarden/common/enums";
import { DeviceType, ThemeType, StorageLocation, KeySuffixOptions } from "@bitwarden/common/enums";
import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum";
import { Utils } from "@bitwarden/common/misc/utils";
import { flagEnabled } from "../../flags";
import { ElectronStateService } from "../../services/electron-state.service.abstraction";
import { isWindowsStore } from "../../utils";
import { SetPinComponent } from "../components/set-pin.component";
@@ -37,10 +37,12 @@ export class SettingsComponent implements OnInit {
clearClipboardOptions: any[];
supportsBiometric: boolean;
biometricText: string;
additionalBiometricSettingsText: string;
autoPromptBiometricsText: string;
showAlwaysShowDock = false;
requireEnableTray = false;
showDuckDuckGoIntegrationOption = false;
isWindows: boolean;
enableTrayText: string;
enableTrayDescText: string;
@@ -70,6 +72,7 @@ export class SettingsComponent implements OnInit {
pin: [null as boolean | null],
biometric: false,
autoPromptBiometrics: false,
requirePasswordOnStart: false,
approveLoginRequests: false,
// Account Preferences
clearClipboard: [null as number | null],
@@ -100,7 +103,7 @@ export class SettingsComponent implements OnInit {
private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService,
private vaultTimeoutSettingsService: VaultTimeoutSettingsService,
private stateService: StateService,
private stateService: ElectronStateService,
private messagingService: MessagingService,
private cryptoService: CryptoService,
private modalService: ModalService,
@@ -182,6 +185,8 @@ export class SettingsComponent implements OnInit {
}
async ngOnInit() {
this.isWindows = (await this.platformUtilsService.getDevice()) === DeviceType.WindowsDesktop;
if ((await this.stateService.getUserId()) == null) {
return;
}
@@ -216,7 +221,9 @@ export class SettingsComponent implements OnInit {
vaultTimeoutAction: await this.vaultTimeoutSettingsService.getVaultTimeoutAction(),
pin: pinSet[0] || pinSet[1],
biometric: await this.vaultTimeoutSettingsService.isBiometricLockSet(),
autoPromptBiometrics: !(await this.stateService.getNoAutoPromptBiometrics()),
autoPromptBiometrics: !(await this.stateService.getDisableAutoBiometricsPrompt()),
requirePasswordOnStart:
(await this.stateService.getBiometricRequirePasswordOnStart()) ?? false,
approveLoginRequests: (await this.stateService.getApproveLoginRequests()) ?? false,
clearClipboard: await this.stateService.getClearClipboard(),
minimizeOnCopyToClipboard: await this.stateService.getMinimizeOnCopyToClipboard(),
@@ -246,6 +253,10 @@ export class SettingsComponent implements OnInit {
this.showAlwaysShowDock = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop;
this.supportsBiometric = await this.platformUtilsService.supportsBiometric();
this.biometricText = await this.stateService.getBiometricText();
this.additionalBiometricSettingsText =
this.biometricText === "unlockWithTouchId"
? "additionalTouchIdSettings"
: "additionalWindowsHelloSettings";
this.autoPromptBiometricsText = await this.stateService.getNoAutoPromptBiometricsText();
this.previousVaultTimeout = this.form.value.vaultTimeout;
@@ -379,26 +390,52 @@ export class SettingsComponent implements OnInit {
return;
}
const authResult = await this.platformUtilsService.authenticateBiometric();
if (!authResult) {
this.form.controls.biometric.setValue(false);
return;
}
this.form.controls.biometric.setValue(true);
await this.stateService.setBiometricUnlock(true);
if (this.isWindows) {
// Recommended settings for Windows Hello
this.form.controls.requirePasswordOnStart.setValue(true);
this.form.controls.autoPromptBiometrics.setValue(false);
await this.stateService.setDisableAutoBiometricsPrompt(true);
await this.stateService.setBiometricRequirePasswordOnStart(true);
await this.stateService.setDismissedBiometricRequirePasswordOnStart();
}
await this.cryptoService.toggleKey();
// Validate the key is stored in case biometrics fail.
const biometricSet = await this.cryptoService.hasKeyStored(KeySuffixOptions.Biometric);
this.form.controls.biometric.setValue(biometricSet);
if (!biometricSet) {
await this.stateService.setBiometricUnlock(null);
}
}
async updateAutoPromptBiometrics() {
if (this.form.value.autoPromptBiometrics) {
await this.stateService.setNoAutoPromptBiometrics(null);
// require password on start must be disabled if auto prompt biometrics is enabled
this.form.controls.requirePasswordOnStart.setValue(false);
await this.updateRequirePasswordOnStart();
await this.stateService.setDisableAutoBiometricsPrompt(null);
} else {
await this.stateService.setNoAutoPromptBiometrics(true);
await this.stateService.setDisableAutoBiometricsPrompt(true);
}
}
async updateRequirePasswordOnStart() {
if (this.form.value.requirePasswordOnStart) {
// auto prompt biometrics must be disabled if require password on start is enabled
this.form.controls.autoPromptBiometrics.setValue(false);
await this.updateAutoPromptBiometrics();
await this.stateService.setBiometricRequirePasswordOnStart(true);
} else {
await this.stateService.setBiometricRequirePasswordOnStart(false);
await this.stateService.setBiometricEncryptionClientKeyHalf(null);
}
await this.stateService.setDismissedBiometricRequirePasswordOnStart();
await this.cryptoService.toggleKey();
}
async saveFavicons() {
await this.stateService.setDisableFavicon(!this.form.value.enableFavicons);
await this.stateService.setDisableFavicon(!this.form.value.enableFavicons, {