|
@ -226,12 +226,15 @@ export class UserAccountSettingsComponent implements OnDestroy, OnInit { |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public onSignInWithFingerprintChange(aEvent: MatSlideToggleChange) { |
|
|
public async onSignInWithFingerprintChange(aEvent: MatSlideToggleChange) { |
|
|
if (aEvent.checked) { |
|
|
if (aEvent.checked) { |
|
|
this.registerDevice().catch(() => { |
|
|
try { |
|
|
|
|
|
await this.registerDevice(); |
|
|
|
|
|
} catch { |
|
|
aEvent.source.checked = false; |
|
|
aEvent.source.checked = false; |
|
|
|
|
|
|
|
|
this.changeDetectorRef.markForCheck(); |
|
|
this.changeDetectorRef.markForCheck(); |
|
|
}); |
|
|
} |
|
|
} 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?` |
|
@ -272,41 +275,38 @@ export class UserAccountSettingsComponent implements OnDestroy, OnInit { |
|
|
this.webAuthnService |
|
|
this.webAuthnService |
|
|
.deregister() |
|
|
.deregister() |
|
|
.pipe( |
|
|
.pipe( |
|
|
takeUntil(this.unsubscribeSubject), |
|
|
|
|
|
catchError(() => { |
|
|
catchError(() => { |
|
|
this.update(); |
|
|
this.update(); |
|
|
|
|
|
|
|
|
return EMPTY; |
|
|
return EMPTY; |
|
|
}) |
|
|
}), |
|
|
|
|
|
takeUntil(this.unsubscribeSubject) |
|
|
) |
|
|
) |
|
|
.subscribe(() => { |
|
|
.subscribe(() => { |
|
|
this.update(); |
|
|
this.update(); |
|
|
}); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private doesBrowserSupportAuthn() { |
|
|
|
|
|
// Authn is built on top of PublicKeyCredential: https://stackoverflow.com/a/55868189
|
|
|
|
|
|
return typeof PublicKeyCredential !== 'undefined'; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
private registerDevice(): Promise<void> { |
|
|
private registerDevice(): Promise<void> { |
|
|
return new Promise((resolve, reject) => { |
|
|
return new Promise((resolve, reject) => { |
|
|
this.webAuthnService |
|
|
this.webAuthnService |
|
|
.register() |
|
|
.register() |
|
|
.pipe( |
|
|
.pipe( |
|
|
takeUntil(this.unsubscribeSubject), |
|
|
|
|
|
catchError((error: Error) => { |
|
|
catchError((error: Error) => { |
|
|
let errorMessage: string; |
|
|
this.snackBar.open( |
|
|
|
|
|
$localize`Oops! There was an error setting up biometric authentication.`, |
|
|
if ( |
|
|
undefined, |
|
|
error.message.includes( |
|
|
{ duration: 3000 } |
|
|
'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 throwError(() => error); |
|
|
return throwError(() => error); |
|
|
}) |
|
|
}), |
|
|
|
|
|
takeUntil(this.unsubscribeSubject) |
|
|
) |
|
|
) |
|
|
.subscribe({ |
|
|
.subscribe({ |
|
|
next: () => { |
|
|
next: () => { |
|
@ -328,9 +328,4 @@ 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'; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|