Browse Source

Fix issue with biometric auth toggle

pull/3496/head
Juan 1 year ago
parent
commit
cb43f83a4a
  1. 34
      apps/client/src/app/components/user-account-settings/user-account-settings.component.ts
  2. 4
      apps/client/src/app/components/user-account-settings/user-account-settings.html

34
apps/client/src/app/components/user-account-settings/user-account-settings.component.ts

@ -20,6 +20,7 @@ import {
} from '@angular/core'; } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms'; import { FormBuilder, Validators } from '@angular/forms';
import { MatSlideToggleChange } from '@angular/material/slide-toggle'; import { MatSlideToggleChange } from '@angular/material/slide-toggle';
import { MatSnackBar } from '@angular/material/snack-bar';
import { format, parseISO } from 'date-fns'; import { format, parseISO } from 'date-fns';
import { uniq } from 'lodash'; import { uniq } from 'lodash';
import { EMPTY, Subject } from 'rxjs'; import { EMPTY, Subject } from 'rxjs';
@ -42,6 +43,7 @@ export class UserAccountSettingsComponent implements OnDestroy, OnInit {
public hasPermissionToUpdateViewMode: boolean; public hasPermissionToUpdateViewMode: boolean;
public hasPermissionToUpdateUserSettings: boolean; public hasPermissionToUpdateUserSettings: boolean;
public isAccessTokenHidden = true; public isAccessTokenHidden = true;
public isFingerprintSupported: boolean;
public isWebAuthnEnabled: boolean; public isWebAuthnEnabled: boolean;
public language = document.documentElement.lang; public language = document.documentElement.lang;
public locales = [ public locales = [
@ -69,12 +71,14 @@ export class UserAccountSettingsComponent implements OnDestroy, OnInit {
private settingsStorageService: SettingsStorageService, private settingsStorageService: SettingsStorageService,
private tokenStorageService: TokenStorageService, private tokenStorageService: TokenStorageService,
private userService: UserService, private userService: UserService,
private snackBar: MatSnackBar,
public webAuthnService: WebAuthnService public webAuthnService: WebAuthnService
) { ) {
const { baseCurrency, currencies } = this.dataService.fetchInfo(); const { baseCurrency, currencies } = this.dataService.fetchInfo();
this.baseCurrency = baseCurrency; this.baseCurrency = baseCurrency;
this.currencies = currencies; this.currencies = currencies;
this.isFingerprintSupported = this.doesBrowserSupportAuthn();
this.userService.stateChanged this.userService.stateChanged
.pipe(takeUntil(this.unsubscribeSubject)) .pipe(takeUntil(this.unsubscribeSubject))
@ -224,7 +228,7 @@ export class UserAccountSettingsComponent implements OnDestroy, OnInit {
public onSignInWithFingerprintChange(aEvent: MatSlideToggleChange) { public onSignInWithFingerprintChange(aEvent: MatSlideToggleChange) {
if (aEvent.checked) { if (aEvent.checked) {
this.registerDevice(); this.registerDevice(aEvent);
} else { } else {
const confirmation = confirm( const confirmation = confirm(
$localize`Do you really want to remove this sign in method?` $localize`Do you really want to remove this sign in method?`
@ -277,13 +281,30 @@ export class UserAccountSettingsComponent implements OnDestroy, OnInit {
}); });
} }
private registerDevice() { private registerDevice(aEvent: MatSlideToggleChange) {
this.webAuthnService this.webAuthnService
.register() .register()
.pipe( .pipe(
takeUntil(this.unsubscribeSubject), takeUntil(this.unsubscribeSubject),
catchError(() => { catchError((error: Error) => {
this.update(); aEvent.source.checked = false;
this.changeDetectorRef.markForCheck();
let errorMessage: string;
if (
error.message.includes(
'The operation either timed out or was not allowed.'
)
) {
errorMessage = $localize`The operation either timed out or was not allowed.`;
} else {
errorMessage = $localize`Oops! There was an unknown error setting up biometric authentication.`;
}
this.snackBar.open(errorMessage, undefined, {
duration: 4000
});
return EMPTY; return EMPTY;
}) })
@ -301,4 +322,9 @@ export class UserAccountSettingsComponent implements OnDestroy, OnInit {
this.changeDetectorRef.markForCheck(); this.changeDetectorRef.markForCheck();
} }
private doesBrowserSupportAuthn() {
// Authn is built on top of PublicKeyCredential: https://stackoverflow.com/a/55868189
return typeof PublicKeyCredential !== 'undefined';
}
} }

4
apps/client/src/app/components/user-account-settings/user-account-settings.html

@ -189,7 +189,9 @@
color="primary" color="primary"
hideIcon="true" hideIcon="true"
[checked]="isWebAuthnEnabled === true" [checked]="isWebAuthnEnabled === true"
[disabled]="!hasPermissionToUpdateUserSettings" [disabled]="
!hasPermissionToUpdateUserSettings || !isFingerprintSupported
"
(change)="onSignInWithFingerprintChange($event)" (change)="onSignInWithFingerprintChange($event)"
/> />
</div> </div>

Loading…
Cancel
Save