diff --git a/apps/browser/src/auth/popup/login/extension-login-component.service.spec.ts b/apps/browser/src/auth/popup/login/extension-login-component.service.spec.ts index a2d703cb031..a967ec9cad3 100644 --- a/apps/browser/src/auth/popup/login/extension-login-component.service.spec.ts +++ b/apps/browser/src/auth/popup/login/extension-login-component.service.spec.ts @@ -10,6 +10,7 @@ import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legac import { flagEnabled } from "../../../platform/flags"; import { BrowserPlatformUtilsService } from "../../../platform/services/platform-utils/browser-platform-utils.service"; +import { ExtensionAnonLayoutWrapperDataService } from "../extension-anon-layout-wrapper/extension-anon-layout-wrapper-data.service"; import { ExtensionLoginComponentService } from "./extension-login-component.service"; @@ -24,14 +25,14 @@ describe("ExtensionLoginComponentService", () => { let passwordGenerationService: MockProxy; let platformUtilsService: MockProxy; let ssoLoginService: MockProxy; - + let extensionAnonLayoutWrapperDataService: MockProxy; beforeEach(() => { cryptoFunctionService = mock(); environmentService = mock(); passwordGenerationService = mock(); platformUtilsService = mock(); ssoLoginService = mock(); - + extensionAnonLayoutWrapperDataService = mock(); TestBed.configureTestingModule({ providers: [ { @@ -43,6 +44,7 @@ describe("ExtensionLoginComponentService", () => { passwordGenerationService, platformUtilsService, ssoLoginService, + extensionAnonLayoutWrapperDataService, ), }, { provide: DefaultLoginComponentService, useExisting: ExtensionLoginComponentService }, diff --git a/apps/browser/src/auth/popup/login/extension-login-component.service.ts b/apps/browser/src/auth/popup/login/extension-login-component.service.ts index a050bf131d8..00de3d14d84 100644 --- a/apps/browser/src/auth/popup/login/extension-login-component.service.ts +++ b/apps/browser/src/auth/popup/login/extension-login-component.service.ts @@ -8,6 +8,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { flagEnabled } from "../../../platform/flags"; +import { ExtensionAnonLayoutWrapperDataService } from "../extension-anon-layout-wrapper/extension-anon-layout-wrapper-data.service"; @Injectable() export class ExtensionLoginComponentService @@ -20,6 +21,7 @@ export class ExtensionLoginComponentService passwordGenerationService: PasswordGenerationServiceAbstraction, platformUtilsService: PlatformUtilsService, ssoLoginService: SsoLoginServiceAbstraction, + private extensionAnonLayoutWrapperDataService: ExtensionAnonLayoutWrapperDataService, ) { super( cryptoFunctionService, @@ -34,4 +36,8 @@ export class ExtensionLoginComponentService isLoginViaAuthRequestSupported(): boolean { return flagEnabled("showPasswordless"); } + + showBackButton(): void { + this.extensionAnonLayoutWrapperDataService.setAnonLayoutWrapperData({ showBackButton: true }); + } } diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index eeb93c3d453..d32084bbfd4 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -602,6 +602,7 @@ const safeProviders: SafeProvider[] = [ PasswordGenerationServiceAbstraction, PlatformUtilsServiceAbstraction, SsoLoginServiceAbstraction, + ExtensionAnonLayoutWrapperDataService, ], }), safeProvider({ @@ -619,6 +620,11 @@ const safeProviders: SafeProvider[] = [ useClass: LoginEmailService, deps: [AccountService, AuthService, StateProvider], }), + safeProvider({ + provide: ExtensionAnonLayoutWrapperDataService, + useClass: ExtensionAnonLayoutWrapperDataService, + deps: [], + }), ]; @NgModule({ diff --git a/libs/auth/src/angular/login/default-login-component.service.ts b/libs/auth/src/angular/login/default-login-component.service.ts index 418dce1132a..17b182f24b8 100644 --- a/libs/auth/src/angular/login/default-login-component.service.ts +++ b/libs/auth/src/angular/login/default-login-component.service.ts @@ -89,4 +89,11 @@ export class DefaultLoginComponentService implements LoginComponentService { encodeURIComponent(email), ); } + + /** + * No-op implementation of showBackButton + */ + showBackButton(): void { + return; + } } diff --git a/libs/auth/src/angular/login/login-component.service.ts b/libs/auth/src/angular/login/login-component.service.ts index aa7f24cf0a4..eb55c92d612 100644 --- a/libs/auth/src/angular/login/login-component.service.ts +++ b/libs/auth/src/angular/login/login-component.service.ts @@ -38,4 +38,9 @@ export abstract class LoginComponentService { * - Used by: Browser, Desktop */ launchSsoBrowserWindow: (email: string, clientId: "browser" | "desktop") => Promise; + + /** + * Shows the back button. + */ + showBackButton: () => void; } diff --git a/libs/auth/src/angular/login/login.component.html b/libs/auth/src/angular/login/login.component.html index 0d5952678d6..edbd193adf3 100644 --- a/libs/auth/src/angular/login/login.component.html +++ b/libs/auth/src/angular/login/login.component.html @@ -11,7 +11,7 @@ -->
- + {{ "emailAddress" | i18n }} @@ -84,7 +84,7 @@ - + {{ "masterPass" | i18n }} @@ -132,13 +132,13 @@ - + diff --git a/libs/auth/src/angular/login/login.component.ts b/libs/auth/src/angular/login/login.component.ts index 81268d6cf69..6ddb4127f62 100644 --- a/libs/auth/src/angular/login/login.component.ts +++ b/libs/auth/src/angular/login/login.component.ts @@ -80,7 +80,7 @@ export class LoginComponent implements OnInit, OnDestroy { LoginUiState = LoginUiState; registerRoute$ = this.registerRouteService.registerRoute$(); // TODO: remove when email verification flag is removed isKnownDevice = false; - validatedEmail = false; + loginUiState: LoginUiState = LoginUiState.EMAIL_ENTRY; formGroup = this.formBuilder.group( { @@ -98,10 +98,6 @@ export class LoginComponent implements OnInit, OnDestroy { return this.formGroup.controls.email; } - get uiState(): LoginUiState { - return this.validatedEmail ? LoginUiState.MASTER_PASSWORD_ENTRY : LoginUiState.EMAIL_ENTRY; - } - // Web properties enforcedPasswordPolicyOptions: MasterPasswordPolicyOptions; policies: Policy[]; @@ -164,7 +160,7 @@ export class LoginComponent implements OnInit, OnDestroy { submit = async (): Promise => { if (this.clientType === ClientType.Desktop) { - if (!this.validatedEmail) { + if (this.loginUiState !== LoginUiState.MASTER_PASSWORD_ENTRY) { return; } } @@ -323,7 +319,7 @@ export class LoginComponent implements OnInit, OnDestroy { const emailValid = this.formGroup.controls.email.valid; if (emailValid) { - this.toggleValidateEmail(true); + this.toggleLoginUiState(LoginUiState.MASTER_PASSWORD_ENTRY); await this.getLoginWithDevice(this.emailFormControl.value); this.anonLayoutWrapperDataService.setAnonLayoutWrapperData({ @@ -334,10 +330,10 @@ export class LoginComponent implements OnInit, OnDestroy { } } - protected toggleValidateEmail(value: boolean): void { - this.validatedEmail = value; + protected toggleLoginUiState(value: LoginUiState): void { + this.loginUiState = value; - if (!this.validatedEmail) { + if (this.loginUiState !== LoginUiState.MASTER_PASSWORD_ENTRY) { // Reset master password only when going from validated to not validated so that autofill can work properly this.formGroup.controls.masterPassword.reset(); } else { @@ -352,6 +348,8 @@ export class LoginComponent implements OnInit, OnDestroy { this.masterPasswordInputRef?.nativeElement?.focus(); }); } + + this.loginComponentService.showBackButton(); } } @@ -551,7 +549,10 @@ export class LoginComponent implements OnInit, OnDestroy { * Helper function to determine if the back button should be shown. * @returns true if the back button should be shown. */ - protected showBackButton(): boolean { - return this.validatedEmail && this.clientType !== ClientType.Browser; + protected shouldShowBackButton(): boolean { + return ( + this.loginUiState === LoginUiState.MASTER_PASSWORD_ENTRY && + this.clientType !== ClientType.Browser + ); } }