From 6fadee7cb4391da0d55e7c298f324faf6f719d1d Mon Sep 17 00:00:00 2001 From: KiruthigaManivannan <162679756+KiruthigaManivannan@users.noreply.github.com> Date: Thu, 6 Jun 2024 19:23:29 +0530 Subject: [PATCH] PM-2055 Update Two Factor Authenticator Dialog (#8972) * PM-2055 Update Two Factor Authenticator Dialog * PM-2055 Added close to disable two factor * PM-2055 Added a event emitter to capture enabled status --- .../two-factor-authenticator.component.html | 189 ++++++++---------- .../two-factor-authenticator.component.ts | 43 +++- .../settings/two-factor-setup.component.html | 1 - .../settings/two-factor-setup.component.ts | 11 +- 4 files changed, 119 insertions(+), 125 deletions(-) diff --git a/apps/web/src/app/auth/settings/two-factor-authenticator.component.html b/apps/web/src/app/auth/settings/two-factor-authenticator.component.html index e17714cca7..a7efaed731 100644 --- a/apps/web/src/app/auth/settings/two-factor-authenticator.component.html +++ b/apps/web/src/app/auth/settings/two-factor-authenticator.component.html @@ -1,109 +1,80 @@ - +
+ + {{ "twoStepLogin" | i18n }} + {{ "authenticatorAppTitle" | i18n }} + + + + Authenticator app logo +

{{ "twoStepAuthenticatorDesc" | i18n }}

+

+ 1. {{ "twoStepAuthenticatorDownloadApp" | i18n }} +

+
+ + +

{{ "twoStepLoginProviderEnabled" | i18n }}

+ {{ "twoStepAuthenticatorReaddDesc" | i18n }} +
+ Authenticator app logo +

{{ "twoStepAuthenticatorNeedApp" | i18n }}

+
+ +

{{ "twoStepAuthenticatorAppsRecommended" | i18n }}

+

+ 2. {{ "twoStepAuthenticatorScanCode" | i18n }} +

+
+

+
+ {{ key }} +

+ + + 3. {{ "twoStepAuthenticatorEnterCode" | i18n }} + + + +
+ + + + +
+
diff --git a/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts b/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts index 88b695eb72..17cdbb595f 100644 --- a/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts +++ b/apps/web/src/app/auth/settings/two-factor-authenticator.component.ts @@ -1,4 +1,6 @@ -import { Component, OnDestroy, OnInit } from "@angular/core"; +import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog"; +import { Component, EventEmitter, Inject, OnDestroy, OnInit, Output } from "@angular/core"; +import { FormControl, FormGroup, Validators } from "@angular/forms"; import { firstValueFrom, map } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; @@ -38,15 +40,21 @@ export class TwoFactorAuthenticatorComponent extends TwoFactorBaseComponent implements OnInit, OnDestroy { + @Output() onChangeStatus = new EventEmitter(); type = TwoFactorProviderType.Authenticator; key: string; - token: string; formPromise: Promise; override componentName = "app-two-factor-authenticator"; private qrScript: HTMLScriptElement; + protected formGroup = new FormGroup({ + token: new FormControl(null, [Validators.required]), + }); + constructor( + @Inject(DIALOG_DATA) protected data: AuthResponse, + private dialogRef: DialogRef, apiService: ApiService, i18nService: I18nService, userVerificationService: UserVerificationService, @@ -68,8 +76,9 @@ export class TwoFactorAuthenticatorComponent this.qrScript.async = true; } - ngOnInit() { + async ngOnInit() { window.document.body.appendChild(this.qrScript); + await this.auth(this.data); } ngOnDestroy() { @@ -81,17 +90,24 @@ export class TwoFactorAuthenticatorComponent return this.processResponse(authResponse.response); } - submit() { + submit = async () => { if (this.enabled) { - return super.disable(this.formPromise); + await this.disableAuthentication(this.formPromise); + this.onChangeStatus.emit(this.enabled); + this.close(); } else { - return this.enable(); + await this.enable(); + this.onChangeStatus.emit(this.enabled); } + }; + + private async disableAuthentication(promise: Promise) { + return super.disable(promise); } protected async enable() { const request = await this.buildRequestModel(UpdateTwoFactorAuthenticatorRequest); - request.token = this.token; + request.token = this.formGroup.value.token; request.key = this.key; return super.enable(async () => { @@ -102,7 +118,7 @@ export class TwoFactorAuthenticatorComponent } private async processResponse(response: TwoFactorAuthenticatorResponse) { - this.token = null; + this.formGroup.get("token").setValue(null); this.enabled = response.enabled; this.key = response.key; const email = await firstValueFrom( @@ -121,4 +137,15 @@ export class TwoFactorAuthenticatorComponent }); }, 100); } + + close = () => { + this.dialogRef.close(this.enabled); + }; + + static open( + dialogService: DialogService, + config: DialogConfig>, + ) { + return dialogService.open(TwoFactorAuthenticatorComponent, config); + } } diff --git a/apps/web/src/app/auth/settings/two-factor-setup.component.html b/apps/web/src/app/auth/settings/two-factor-setup.component.html index a20bb34566..28baf72f88 100644 --- a/apps/web/src/app/auth/settings/two-factor-setup.component.html +++ b/apps/web/src/app/auth/settings/two-factor-setup.component.html @@ -80,7 +80,6 @@ - diff --git a/apps/web/src/app/auth/settings/two-factor-setup.component.ts b/apps/web/src/app/auth/settings/two-factor-setup.component.ts index dd4c69aa27..34a7e32089 100644 --- a/apps/web/src/app/auth/settings/two-factor-setup.component.ts +++ b/apps/web/src/app/auth/settings/two-factor-setup.component.ts @@ -34,8 +34,6 @@ import { TwoFactorYubiKeyComponent } from "./two-factor-yubikey.component"; templateUrl: "two-factor-setup.component.html", }) export class TwoFactorSetupComponent implements OnInit, OnDestroy { - @ViewChild("authenticatorTemplate", { read: ViewContainerRef, static: true }) - authenticatorModalRef: ViewContainerRef; @ViewChild("yubikeyTemplate", { read: ViewContainerRef, static: true }) yubikeyModalRef: ViewContainerRef; @ViewChild("duoTemplate", { read: ViewContainerRef, static: true }) duoModalRef: ViewContainerRef; @@ -137,12 +135,11 @@ export class TwoFactorSetupComponent implements OnInit, OnDestroy { if (!result) { return; } - const authComp = await this.openModal( - this.authenticatorModalRef, - TwoFactorAuthenticatorComponent, + const authComp: DialogRef = TwoFactorAuthenticatorComponent.open( + this.dialogService, + { data: result }, ); - await authComp.auth(result); - authComp.onUpdated.pipe(takeUntil(this.destroy$)).subscribe((enabled: boolean) => { + authComp.componentInstance.onChangeStatus.subscribe((enabled: boolean) => { this.updateStatus(enabled, TwoFactorProviderType.Authenticator); }); break;