diff --git a/src/abstractions/auth.service.ts b/src/abstractions/auth.service.ts index 08ca102729..4b2b2434d0 100644 --- a/src/abstractions/auth.service.ts +++ b/src/abstractions/auth.service.ts @@ -6,6 +6,7 @@ export abstract class AuthService { email: string; masterPasswordHash: string; twoFactorProviders: Map; + selectedTwoFactorProviderType: TwoFactorProviderType; logIn: (email: string, masterPassword: string) => Promise; logInTwoFactor: (twoFactorProvider: TwoFactorProviderType, twoFactorToken: string, diff --git a/src/angular/directives/box-row.directive.ts b/src/angular/directives/box-row.directive.ts new file mode 100644 index 0000000000..241a5b3f82 --- /dev/null +++ b/src/angular/directives/box-row.directive.ts @@ -0,0 +1,49 @@ +import { + Directive, + ElementRef, + HostListener, + OnInit, +} from '@angular/core'; + +@Directive({ + selector: '[appBoxRow]', +}) +export class BoxRowDirective implements OnInit { + el: HTMLElement = null; + formEls: NodeListOf; + + constructor(private elRef: ElementRef) { + this.el = elRef.nativeElement; + } + + ngOnInit(): void { + this.formEls = this.el.querySelectorAll('input:not([type="hidden"]), select, textarea'); + this.formEls.forEach((formEl) => { + formEl.addEventListener('focus', (event: Event) => { + this.el.classList.add('active'); + }, false); + + formEl.addEventListener('blur', (event: Event) => { + this.el.classList.remove('active'); + }, false); + }); + } + + @HostListener('click', ['$event']) onClick(event: Event) { + if (event.target !== this.el) { + return; + } + + if (this.formEls.length > 0) { + const formEl = (this.formEls[0] as HTMLElement); + if (formEl.tagName.toLowerCase() === 'input') { + const inputEl = (formEl as HTMLInputElement); + if (inputEl.type != null && inputEl.type.toLowerCase() === 'checkbox') { + inputEl.click(); + return; + } + } + formEl.focus(); + } + } +} diff --git a/src/services/auth.service.ts b/src/services/auth.service.ts index 7395e7c420..348c2c1d84 100644 --- a/src/services/auth.service.ts +++ b/src/services/auth.service.ts @@ -63,6 +63,7 @@ export class AuthService { email: string; masterPasswordHash: string; twoFactorProviders: Map; + selectedTwoFactorProviderType: TwoFactorProviderType = null; private key: SymmetricCryptoKey; @@ -95,6 +96,7 @@ export class AuthService { } async logIn(email: string, masterPassword: string): Promise { + this.selectedTwoFactorProviderType = null; email = email.toLowerCase(); const key = this.cryptoService.makeKey(masterPassword, email); const hashedPassword = await this.cryptoService.hashPassword(masterPassword, key); @@ -117,6 +119,11 @@ export class AuthService { return null; } + if (this.selectedTwoFactorProviderType != null && + this.twoFactorProviders.has(this.selectedTwoFactorProviderType)) { + return this.selectedTwoFactorProviderType; + } + let providerType: TwoFactorProviderType = null; let providerPriority = -1; this.twoFactorProviders.forEach((value, type) => { @@ -188,5 +195,6 @@ export class AuthService { this.email = null; this.masterPasswordHash = null; this.twoFactorProviders = null; + this.selectedTwoFactorProviderType = null; } }