Automatic biometrics prompt (#2065)

Co-authored-by: Michael Cho <mcho@tutanota.com>
This commit is contained in:
Dane Powell 2021-09-17 01:22:46 -07:00 committed by GitHub
parent bb99af6e24
commit 7d797f73fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 2 deletions

2
jslib

@ -1 +1 @@
Subproject commit da132217da553365538bbb66a21c40d3966610c1 Subproject commit da6fde4b151e7d154c7eb16d8f81926ad2f3ca22

View File

@ -776,6 +776,9 @@
"disableAutoTotpCopyDesc": { "disableAutoTotpCopyDesc": {
"message": "If your login has an authenticator key attached to it, the TOTP verification code is automatically copied to your clipboard whenever you auto-fill the login." "message": "If your login has an authenticator key attached to it, the TOTP verification code is automatically copied to your clipboard whenever you auto-fill the login."
}, },
"disableAutoBiometricsPrompt": {
"message": "Do not prompt for biometrics on launch"
},
"premiumRequired": { "premiumRequired": {
"message": "Premium Required" "message": "Premium Required"
}, },

View File

@ -1,6 +1,8 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { ConstantsService } from 'jslib-common/services/constants.service';
import { ApiService } from 'jslib-common/abstractions/api.service'; import { ApiService } from 'jslib-common/abstractions/api.service';
import { CryptoService } from 'jslib-common/abstractions/crypto.service'; import { CryptoService } from 'jslib-common/abstractions/crypto.service';
import { EnvironmentService } from 'jslib-common/abstractions/environment.service'; import { EnvironmentService } from 'jslib-common/abstractions/environment.service';
@ -20,6 +22,8 @@ import Swal from 'sweetalert2';
templateUrl: 'lock.component.html', templateUrl: 'lock.component.html',
}) })
export class LockComponent extends BaseLockComponent { export class LockComponent extends BaseLockComponent {
private isInitialLockScreen: boolean;
constructor(router: Router, i18nService: I18nService, constructor(router: Router, i18nService: I18nService,
platformUtilsService: PlatformUtilsService, messagingService: MessagingService, platformUtilsService: PlatformUtilsService, messagingService: MessagingService,
userService: UserService, cryptoService: CryptoService, userService: UserService, cryptoService: CryptoService,
@ -29,12 +33,21 @@ export class LockComponent extends BaseLockComponent {
super(router, i18nService, platformUtilsService, messagingService, userService, cryptoService, super(router, i18nService, platformUtilsService, messagingService, userService, cryptoService,
storageService, vaultTimeoutService, environmentService, stateService, apiService); storageService, vaultTimeoutService, environmentService, stateService, apiService);
this.successRoute = '/tabs/current'; this.successRoute = '/tabs/current';
this.isInitialLockScreen = (window as any).previousPopupUrl == null;
} }
async ngOnInit() { async ngOnInit() {
await super.ngOnInit(); await super.ngOnInit();
window.setTimeout(() => { const disableAutoBiometricsPrompt = await this.storageService.get<boolean>(
ConstantsService.disableAutoBiometricsPromptKey) ?? true;
window.setTimeout(async () => {
document.getElementById(this.pinLock ? 'pin' : 'masterPassword').focus(); document.getElementById(this.pinLock ? 'pin' : 'masterPassword').focus();
if (this.biometricLock && !disableAutoBiometricsPrompt && this.isInitialLockScreen) {
if (await this.vaultTimeoutService.isLocked()) {
await this.unlockBiometric();
}
}
}, 100); }, 100);
} }

View File

@ -44,6 +44,10 @@
<label for="biometric">{{'unlockWithBiometrics' | i18n}}</label> <label for="biometric">{{'unlockWithBiometrics' | i18n}}</label>
<input id="biometric" type="checkbox" (change)="updateBiometric()" [(ngModel)]="biometric"> <input id="biometric" type="checkbox" (change)="updateBiometric()" [(ngModel)]="biometric">
</div> </div>
<div class="box-content-row box-content-row-checkbox" appBoxRow *ngIf="supportsBiometric">
<label for="autoBiometricsPrompt">{{'disableAutoBiometricsPrompt' | i18n}}</label>
<input id="autoBiometricsPrompt" type="checkbox" (change)="updateAutoBiometricsPrompt()" [disabled]="!biometric" [(ngModel)]="disableAutoBiometricsPrompt">
</div>
<a class="box-content-row box-content-row-flex text-default" href="#" appStopClick appBlurClick <a class="box-content-row box-content-row-flex text-default" href="#" appStopClick appBlurClick
(click)="lock()"> (click)="lock()">
<div class="row-main">{{'lockNow' | i18n}}</div> <div class="row-main">{{'lockNow' | i18n}}</div>

View File

@ -56,6 +56,7 @@ export class SettingsComponent implements OnInit {
pin: boolean = null; pin: boolean = null;
supportsBiometric: boolean; supportsBiometric: boolean;
biometric: boolean = false; biometric: boolean = false;
disableAutoBiometricsPrompt = true;
previousVaultTimeout: number = null; previousVaultTimeout: number = null;
vaultTimeout: FormControl = new FormControl(null); vaultTimeout: FormControl = new FormControl(null);
@ -115,6 +116,8 @@ export class SettingsComponent implements OnInit {
this.supportsBiometric = await this.platformUtilsService.supportsBiometric(); this.supportsBiometric = await this.platformUtilsService.supportsBiometric();
this.biometric = await this.vaultTimeoutService.isBiometricLockSet(); this.biometric = await this.vaultTimeoutService.isBiometricLockSet();
this.disableAutoBiometricsPrompt = await this.storageService.get<boolean>(
ConstantsService.disableAutoBiometricsPromptKey) ?? true;
} }
async saveVaultTimeout(newValue: number) { async saveVaultTimeout(newValue: number) {
@ -250,6 +253,10 @@ export class SettingsComponent implements OnInit {
} }
} }
async updateAutoBiometricsPrompt() {
await this.storageService.save(ConstantsService.disableAutoBiometricsPromptKey, this.disableAutoBiometricsPrompt);
}
async lock() { async lock() {
await this.vaultTimeoutService.lock(true); await this.vaultTimeoutService.lock(true);
} }