From af9483d480514efb68398e254a7bbb24dd629f4f Mon Sep 17 00:00:00 2001 From: rr-bw <102181210+rr-bw@users.noreply.github.com> Date: Tue, 20 Aug 2024 15:30:15 -0700 Subject: [PATCH] setup new LoginComponent files in libs/auth --- .../web/src/app/auth/login/login.component.ts | 5 ++ apps/web/src/app/oss-routing.module.ts | 3 +- .../src/auth/components/login.component.ts | 2 + libs/auth/src/angular/index.ts | 33 +++++---- .../src/angular/login/login.component.html | 55 +++++++++++++++ .../auth/src/angular/login/login.component.ts | 69 +++++++++++++++++++ 6 files changed, 152 insertions(+), 15 deletions(-) create mode 100644 libs/auth/src/angular/login/login.component.html create mode 100644 libs/auth/src/angular/login/login.component.ts diff --git a/apps/web/src/app/auth/login/login.component.ts b/apps/web/src/app/auth/login/login.component.ts index d0a4376556..0f2ceca878 100644 --- a/apps/web/src/app/auth/login/login.component.ts +++ b/apps/web/src/app/auth/login/login.component.ts @@ -45,6 +45,7 @@ export class LoginComponent extends BaseLoginComponent implements OnInit { enforcedPasswordPolicyOptions: MasterPasswordPolicyOptions; policies: Policy[]; showPasswordless = false; + constructor( private acceptOrganizationInviteService: AcceptOrganizationInviteService, devicesApiService: DevicesApiServiceAbstraction, @@ -95,6 +96,7 @@ export class LoginComponent extends BaseLoginComponent implements OnInit { this.onSuccessfulLoginNavigate = this.goAfterLogIn; this.showPasswordless = flagEnabled("showPasswordless"); } + submitForm = async (showToast = true) => { return await this.submitFormHelper(showToast); }; @@ -102,6 +104,7 @@ export class LoginComponent extends BaseLoginComponent implements OnInit { private async submitFormHelper(showToast: boolean) { await super.submit(showToast); } + async ngOnInit() { // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe this.route.queryParams.pipe(first()).subscribe(async (qParams) => { @@ -202,10 +205,12 @@ export class LoginComponent extends BaseLoginComponent implements OnInit { if (this.policies == null) { return; } + const resetPasswordPolicy = this.policyService.getResetPasswordPolicyOptions( this.policies, invite.organizationId, ); + // Set to true if policy enabled and auto-enroll enabled this.showResetPasswordAutoEnrollWarning = resetPasswordPolicy[1] && resetPasswordPolicy[0].autoEnrollEnabled; diff --git a/apps/web/src/app/oss-routing.module.ts b/apps/web/src/app/oss-routing.module.ts index 32dcb695a8..135130d6e6 100644 --- a/apps/web/src/app/oss-routing.module.ts +++ b/apps/web/src/app/oss-routing.module.ts @@ -19,6 +19,7 @@ import { SetPasswordJitComponent, LockIcon, RegistrationLinkExpiredComponent, + LoginComponentV2, } from "@bitwarden/auth/angular"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; @@ -260,7 +261,7 @@ const routes: Routes = [ children: [ { path: "", - component: LoginComponent, + component: LoginComponentV2, }, { path: "", diff --git a/libs/angular/src/auth/components/login.component.ts b/libs/angular/src/auth/components/login.component.ts index 057d67b152..f94ed8aaa8 100644 --- a/libs/angular/src/auth/components/login.component.ts +++ b/libs/angular/src/auth/components/login.component.ts @@ -266,6 +266,7 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit, async validateEmail() { this.formGroup.controls.email.markAsTouched(); const emailValid = this.formGroup.get("email").valid; + if (emailValid) { this.toggleValidateEmail(true); await this.getLoginWithDevice(this.loggedEmail); @@ -299,6 +300,7 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit, // Try to load from memory first const email = this.loginEmailService.getEmail(); const rememberEmail = this.loginEmailService.getRememberEmail(); + if (email) { this.formGroup.controls.email.setValue(email); this.formGroup.controls.rememberEmail.setValue(rememberEmail); diff --git a/libs/auth/src/angular/index.ts b/libs/auth/src/angular/index.ts index f6a9ffde55..daab7a9c8e 100644 --- a/libs/auth/src/angular/index.ts +++ b/libs/auth/src/angular/index.ts @@ -2,9 +2,6 @@ * This barrel file should only contain Angular exports */ -// icons -export * from "./icons"; - // anon layout export * from "./anon-layout/anon-layout.component"; export * from "./anon-layout/anon-layout-wrapper.component"; @@ -14,14 +11,28 @@ export * from "./anon-layout/default-anon-layout-wrapper-data.service"; // fingerprint dialog export * from "./fingerprint-dialog/fingerprint-dialog.component"; -// password callout -export * from "./password-callout/password-callout.component"; -export * from "./vault-timeout-input/vault-timeout-input.component"; +// icons +export * from "./icons"; // input password export * from "./input-password/input-password.component"; export * from "./input-password/password-input-result"; +// login +export * from "./login/login.component"; + +// password callout +export * from "./password-callout/password-callout.component"; + +// registration +export * from "./registration/registration-start/registration-start.component"; +export * from "./registration/registration-finish/registration-finish.component"; +export * from "./registration/registration-link-expired/registration-link-expired.component"; +export * from "./registration/registration-start/registration-start-secondary.component"; +export * from "./registration/registration-env-selector/registration-env-selector.component"; +export * from "./registration/registration-finish/registration-finish.service"; +export * from "./registration/registration-finish/default-registration-finish.service"; + // set password (JIT user) export * from "./set-password-jit/set-password-jit.component"; export * from "./set-password-jit/set-password-jit.service.abstraction"; @@ -32,11 +43,5 @@ export * from "./user-verification/user-verification-dialog.component"; export * from "./user-verification/user-verification-dialog.types"; export * from "./user-verification/user-verification-form-input.component"; -// registration -export * from "./registration/registration-start/registration-start.component"; -export * from "./registration/registration-finish/registration-finish.component"; -export * from "./registration/registration-link-expired/registration-link-expired.component"; -export * from "./registration/registration-start/registration-start-secondary.component"; -export * from "./registration/registration-env-selector/registration-env-selector.component"; -export * from "./registration/registration-finish/registration-finish.service"; -export * from "./registration/registration-finish/default-registration-finish.service"; +// vault timeout input +export * from "./vault-timeout-input/vault-timeout-input.component"; diff --git a/libs/auth/src/angular/login/login.component.html b/libs/auth/src/angular/login/login.component.html new file mode 100644 index 0000000000..452cb2154c --- /dev/null +++ b/libs/auth/src/angular/login/login.component.html @@ -0,0 +1,55 @@ +
+ + + +
+ + {{ "emailAddress" | i18n }} + + +
+ + +
+ + + {{ "rememberEmail" | i18n }} + +
+ + +
+ +
+ + + + +
+
+ + +
diff --git a/libs/auth/src/angular/login/login.component.ts b/libs/auth/src/angular/login/login.component.ts new file mode 100644 index 0000000000..f69018a9aa --- /dev/null +++ b/libs/auth/src/angular/login/login.component.ts @@ -0,0 +1,69 @@ +import { CommonModule } from "@angular/common"; +import { Component, OnInit } from "@angular/core"; +import { FormBuilder, ReactiveFormsModule, Validators } from "@angular/forms"; +import { ActivatedRoute, RouterModule } from "@angular/router"; +import { Subject, takeUntil } from "rxjs"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { + AsyncActionsModule, + ButtonModule, + CheckboxModule, + FormFieldModule, +} from "@bitwarden/components"; + +@Component({ + standalone: true, + templateUrl: "./login.component.html", + imports: [ + AsyncActionsModule, + ButtonModule, + CheckboxModule, + CommonModule, + FormFieldModule, + JslibModule, + ReactiveFormsModule, + RouterModule, + ], +}) +export class LoginComponentV2 implements OnInit { + protected paramEmailSet = false; + + protected formGroup = this.formBuilder.group({ + email: ["", [Validators.required, Validators.email]], + rememberEmail: [false], + }); + + private destroy$ = new Subject(); + + constructor( + private activatedRoute: ActivatedRoute, + private formBuilder: FormBuilder, + ) {} + + async ngOnInit(): Promise { + this.activatedRoute.queryParams.pipe(takeUntil(this.destroy$)).subscribe((params) => { + if (!params) { + return; + } + + const qParamsEmail = params.email; + + if (qParamsEmail?.indexOf("@") > -1) { + this.formGroup.controls.email.setValue(qParamsEmail); + + this.paramEmailSet = true; + } + }); + + if (!this.paramEmailSet) { + await this.loadEmailSettings(); + } + } + + submit = async () => {}; + + async validateEmail() {} + + private async loadEmailSettings() {} +}