1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-19 10:54:00 +00:00

First pass of a working implementation. Need to remove the hard coded trues.

This commit is contained in:
Patrick Pimentel
2024-11-20 19:03:42 -05:00
parent 234a832fc4
commit 1032c9ce9f
4 changed files with 54 additions and 27 deletions

View File

@@ -119,49 +119,38 @@
</label>
</div>
</div>
<div class="form-group" *ngIf="supportsBiometric">
<div class="form-group" *ngIf="true">
<div class="checkbox">
<label for="biometric">
<input id="biometric" type="checkbox" formControlName="biometric" />
{{ biometricText | i18n }}
</label>
</div>
<small class="help-block" *ngIf="this.form.value.biometric && !this.isLinux">{{
<small class="help-block" *ngIf="true">{{
additionalBiometricSettingsText | i18n
}}</small>
</div>
<div
class="form-group"
*ngIf="supportsBiometric && this.form.value.biometric && !this.isLinux"
>
<div class="checkbox form-group-child">
<!-- WORKING HERE -->
<div class="form-group">
<div class="radio form-group-child [&:not(:last-of-type)]:tw-mb-5" *ngIf="true">
<label for="autoPromptBiometrics">
<input
id="autoPromptBiometrics"
type="checkbox"
formControlName="autoPromptBiometrics"
(change)="updateAutoPromptBiometrics()"
type="radio"
[value]="'autoPromptBiometrics'"
formControlName="startupBehavior"
/>
{{ autoPromptBiometricsText | i18n }}
</label>
</div>
</div>
<div
class="form-group"
*ngIf="
supportsBiometric &&
this.form.value.biometric &&
(userHasMasterPassword || (this.form.value.pin && userHasPinSet)) &&
!this.isLinux
"
>
<div class="checkbox form-group-child">
<div class="radio form-group-child [&:not(:last-of-type)]:tw-mb-5" *ngIf="true">
<label for="requirePasswordOnStart">
<input
id="requirePasswordOnStart"
type="checkbox"
formControlName="requirePasswordOnStart"
(change)="updateRequirePasswordOnStart()"
type="radio"
[value]="'requirePasswordOnStart'"
formControlName="startupBehavior"
/>
{{ "requirePasswordOnStart" | i18n }}
</label>
@@ -170,6 +159,7 @@
"recommendedForSecurity" | i18n
}}</small>
</div>
<!-- WORKING HERE -->
</ng-container>
</div>
</div>

View File

@@ -114,6 +114,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
enableDuckDuckGoBrowserIntegration: false,
theme: [null as ThemeType | null],
locale: [null as string | null],
startupBehavior: [null as "autoPromptBiometrics" | "requirePasswordOnStart" | null],
});
private refreshTimeoutSettings$ = new BehaviorSubject<void>(undefined);
@@ -143,7 +144,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
private nativeMessagingManifestService: NativeMessagingManifestService,
private configService: ConfigService,
) {
const isMac = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop;
const isMac = false;
// Workaround to avoid ghosting trays https://github.com/electron/electron/issues/17622
this.requireEnableTray = this.platformUtilsService.getDevice() === DeviceType.LinuxDesktop;
@@ -209,7 +210,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
this.showSshAgentOption = await this.configService.getFeatureFlag(FeatureFlag.SSHAgent);
this.userHasMasterPassword = await this.userVerificationService.hasMasterPassword();
this.isWindows = this.platformUtilsService.getDevice() === DeviceType.WindowsDesktop;
this.isWindows = true;
this.currentUserEmail = activeAccount.email;
this.currentUserId = activeAccount.id;
@@ -282,6 +283,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
enableSshAgent: await firstValueFrom(this.desktopSettingsService.sshAgentEnabled$),
theme: await firstValueFrom(this.themeStateService.selectedTheme$),
locale: await firstValueFrom(this.i18nService.userSetLocale$),
startupBehavior: await firstValueFrom(this.biometricStateService.startupBehavior$),
};
this.form.setValue(initialValues, { emitEvent: false });
@@ -355,6 +357,19 @@ export class SettingsComponent implements OnInit, OnDestroy {
this.form.controls.enableBrowserIntegrationFingerprint.disable();
}
});
this.form.controls.startupBehavior.valueChanges
.pipe(
concatMap(async (value) => {
if (value === "autoPromptBiometrics") {
await this.updateAutoPromptBiometrics();
} else if (value === "requirePasswordOnStart") {
await this.updateRequirePasswordOnStart();
}
}),
takeUntil(this.destroy$),
)
.subscribe();
}
async saveVaultTimeout(newValue: VaultTimeout) {
@@ -769,6 +784,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
}
get biometricText() {
return "unlockWithWindowsHello";
switch (this.platformUtilsService.getDevice()) {
case DeviceType.MacOsDesktop:
return "unlockWithTouchId";
@@ -782,6 +798,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
}
get autoPromptBiometricsText() {
return "autoPromptWindowsHello";
switch (this.platformUtilsService.getDevice()) {
case DeviceType.MacOsDesktop:
return "autoPromptTouchId";
@@ -795,6 +812,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
}
get additionalBiometricSettingsText() {
return "additionalWindowsHelloSettings";
switch (this.platformUtilsService.getDevice()) {
case DeviceType.MacOsDesktop:
return "additionalTouchIdSettings";

View File

@@ -7,7 +7,7 @@ import { NgModule } from "@angular/core";
import { ColorPasswordCountPipe } from "@bitwarden/angular/pipes/color-password-count.pipe";
import { ColorPasswordPipe } from "@bitwarden/angular/pipes/color-password.pipe";
import { DialogModule, CalloutModule } from "@bitwarden/components";
import { DialogModule, CalloutModule, RadioButtonModule } from "@bitwarden/components";
import { AccessibilityCookieComponent } from "../auth/accessibility-cookie.component";
import { DeleteAccountComponent } from "../auth/delete-account.component";
@@ -62,6 +62,7 @@ import { SendComponent } from "./tools/send/send.component";
CalloutModule,
DeleteAccountComponent,
UserVerificationComponent,
RadioButtonModule,
],
declarations: [
AccessibilityCookieComponent,

View File

@@ -55,6 +55,11 @@ export abstract class BiometricStateService {
*/
abstract fingerprintValidated$: Observable<boolean>;
/**
*
*/
abstract startupBehavior$: Observable<"autoPromptBiometrics" | "requirePasswordOnStart">;
/**
* Updates the require password on start state for the currently active user.
*
@@ -62,42 +67,54 @@ export abstract class BiometricStateService {
* @param value whether or not a password is required on first unlock after opening the application
*/
abstract setRequirePasswordOnStart(value: boolean): Promise<void>;
/**
* Updates the biometric unlock enabled state for the currently active user.
* @param enabled whether or not to store a biometric key to unlock the vault
*/
abstract setBiometricUnlockEnabled(enabled: boolean): Promise<void>;
/**
* Gets the biometric unlock enabled state for the given user.
* @param userId user Id to check
*/
abstract getBiometricUnlockEnabled(userId: UserId): Promise<boolean>;
abstract setEncryptedClientKeyHalf(encryptedKeyHalf: EncString, userId?: UserId): Promise<void>;
abstract getEncryptedClientKeyHalf(userId: UserId): Promise<EncString>;
abstract getRequirePasswordOnStart(userId: UserId): Promise<boolean>;
abstract removeEncryptedClientKeyHalf(userId: UserId): Promise<void>;
/**
* Updates the active user's state to reflect that they've been warned about requiring password on start.
*/
abstract setDismissedRequirePasswordOnStartCallout(): Promise<void>;
/**
* Updates the active user's state to reflect that they've cancelled the biometric prompt.
*/
abstract setUserPromptCancelled(): Promise<void>;
/**
* Resets the given user's state to reflect that they haven't cancelled the biometric prompt.
* @param userId the user to reset the prompt cancelled state for. If not provided, the currently active user will be used.
*/
abstract resetUserPromptCancelled(userId?: UserId): Promise<void>;
/**
* Resets all user's state to reflect that they haven't cancelled the biometric prompt.
*/
abstract resetAllPromptCancelled(): Promise<void>;
/**
* Updates the currently active user's setting for auto prompting for biometrics on application start and lock
* @param prompt Whether or not to prompt for biometrics on application start.
*/
abstract setPromptAutomatically(prompt: boolean): Promise<void>;
/**
* Updates whether or not IPC has been validated by the user this session
* @param validated the value to save
@@ -122,6 +139,7 @@ export class DefaultBiometricStateService implements BiometricStateService {
promptCancelled$: Observable<boolean>;
promptAutomatically$: Observable<boolean>;
fingerprintValidated$: Observable<boolean>;
startupBehavior$: Observable<"autoPromptBiometrics" | "requirePasswordOnStart">;
constructor(private stateProvider: StateProvider) {
this.biometricUnlockEnabledState = this.stateProvider.getActive(BIOMETRIC_UNLOCK_ENABLED);