diff --git a/apps/web/src/app/auth/two-factor.component.html b/apps/web/src/app/auth/two-factor.component.html index df86db99ee..7c63553e43 100644 --- a/apps/web/src/app/auth/two-factor.component.html +++ b/apps/web/src/app/auth/two-factor.component.html @@ -1,173 +1,124 @@ -
-
-
+
+ -

{{ title }}

-
-
- + {{ "enterVerificationCodeApp" | i18n }} +

+

+ {{ "enterVerificationCodeEmail" | i18n: twoFactorEmail }} +

+ + {{ "verificationCode" | i18n }} + + + -

- {{ "enterVerificationCodeApp" | i18n }} -

-

- {{ "enterVerificationCodeEmail" | i18n: twoFactorEmail }} -

-
-
- -

{{ "insertYubiKey" | i18n }}

- - - - - -
- - -
-
- -
- -
-
- - - -

- {{ "duoRequiredByOrgForAccount" | i18n }} -

-

{{ "launchDuoAndFollowStepsToFinishLoggingIn" | i18n }}

-
- - -
- -
-
-
- -
- - -
- -

{{ "noTwoStepProviders" | i18n }}

-

{{ "noTwoStepProviders2" | i18n }}

-
-
-
- -
- -
- - - - {{ "cancel" | i18n }} - -
- -
+ {{ "sendVerificationCodeEmailAgain" | i18n }} + + + + +

{{ "insertYubiKey" | i18n }}

+ + + + + + + {{ "verificationCode" | i18n }} + + +
+ +
+
+
+ + + +

+ {{ "duoRequiredByOrgForAccount" | i18n }} +

+

{{ "launchDuoAndFollowStepsToFinishLoggingIn" | i18n }}

+
+ + +
+ +
+
+
+ + {{ "rememberMe" | i18n }} + + + +

{{ "noTwoStepProviders" | i18n }}

+

{{ "noTwoStepProviders2" | i18n }}

+
+
+
+ +
+ +
+ + + + {{ "cancel" | i18n }} + +
+
diff --git a/apps/web/src/app/auth/two-factor.component.ts b/apps/web/src/app/auth/two-factor.component.ts index c91ae4674d..741037cc30 100644 --- a/apps/web/src/app/auth/two-factor.component.ts +++ b/apps/web/src/app/auth/two-factor.component.ts @@ -1,6 +1,7 @@ import { Component, Inject, OnDestroy, ViewChild, ViewContainerRef } from "@angular/core"; +import { FormBuilder, Validators } from "@angular/forms"; import { ActivatedRoute, Router } from "@angular/router"; -import { lastValueFrom } from "rxjs"; +import { Subject, takeUntil, lastValueFrom } from "rxjs"; import { TwoFactorComponent as BaseTwoFactorComponent } from "@bitwarden/angular/auth/components/two-factor.component"; import { WINDOW } from "@bitwarden/angular/services/injection-tokens"; @@ -38,7 +39,17 @@ import { export class TwoFactorComponent extends BaseTwoFactorComponent implements OnDestroy { @ViewChild("twoFactorOptions", { read: ViewContainerRef, static: true }) twoFactorOptionsModal: ViewContainerRef; - + formGroup = this.formBuilder.group({ + token: [ + "", + { + validators: [Validators.required], + updateOn: "submit", + }, + ], + remember: [false], + }); + private destroy$ = new Subject(); constructor( loginStrategyService: LoginStrategyServiceAbstraction, router: Router, @@ -58,6 +69,7 @@ export class TwoFactorComponent extends BaseTwoFactorComponent implements OnDest configService: ConfigService, masterPasswordService: InternalMasterPasswordServiceAbstraction, accountService: AccountService, + private formBuilder: FormBuilder, @Inject(WINDOW) protected win: Window, ) { super( @@ -82,6 +94,16 @@ export class TwoFactorComponent extends BaseTwoFactorComponent implements OnDest ); this.onSuccessfulLoginNavigate = this.goAfterLogIn; } + async ngOnInit() { + await super.ngOnInit(); + this.formGroup.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((value) => { + this.token = value.token; + this.remember = value.remember; + }); + } + submitForm = async () => { + await this.submit(); + }; async anotherMethod() { const dialogRef = TwoFactorOptionsComponent.open(this.dialogService); diff --git a/apps/web/src/app/oss-routing.module.ts b/apps/web/src/app/oss-routing.module.ts index 1115a60bf9..44cfc10873 100644 --- a/apps/web/src/app/oss-routing.module.ts +++ b/apps/web/src/app/oss-routing.module.ts @@ -82,7 +82,6 @@ const routes: Routes = [ component: LoginViaAuthRequestComponent, data: { titleId: "adminApprovalRequested" } satisfies DataProperties, }, - { path: "2fa", component: TwoFactorComponent, canActivate: [UnauthGuard] }, { path: "login-initiated", component: LoginDecryptionOptionsComponent, @@ -189,6 +188,33 @@ const routes: Routes = [ path: "", component: AnonLayoutWrapperComponent, children: [ + { + path: "2fa", + component: TwoFactorComponent, + canActivate: [unauthGuardFn()], + data: { + pageTitle: "verifyIdentity", + }, + }, + { + path: "recover-2fa", + canActivate: [unauthGuardFn()], + children: [ + { + path: "", + component: RecoverTwoFactorComponent, + }, + { + path: "", + component: EnvironmentSelectorComponent, + outlet: "environment-selector", + }, + ], + data: { + pageTitle: "recoverAccountTwoStep", + titleId: "recoverAccountTwoStep", + } satisfies DataProperties & AnonLayoutWrapperData, + }, { path: "accept-emergency", canActivate: [deepLinkGuard()], diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 9cbd44a963..964cfe7536 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -722,6 +722,9 @@ "logIn": { "message": "Log in" }, + "verifyIdentity": { + "message": "Verify your Identity" + }, "logInInitiated": { "message": "Log in initiated" },