1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 16:23:44 +00:00

add validateEmail logic

This commit is contained in:
rr-bw
2024-08-30 14:36:22 -07:00
parent 669585a87f
commit 9b28a0e01e
2 changed files with 72 additions and 6 deletions

View File

@@ -47,6 +47,8 @@
</div> </div>
<hr /> <hr />
<!-- TODO-rr-bw: More here -->
</ng-container> </ng-container>
<!----------------------------------- <!-----------------------------------

View File

@@ -1,15 +1,18 @@
import { CommonModule } from "@angular/common"; import { CommonModule } from "@angular/common";
import { Component, OnInit } from "@angular/core"; import { Component, ElementRef, NgZone, OnDestroy, OnInit, ViewChild } from "@angular/core";
import { FormBuilder, ReactiveFormsModule, Validators } from "@angular/forms"; import { FormBuilder, ReactiveFormsModule, Validators } from "@angular/forms";
import { ActivatedRoute, Router, RouterModule } from "@angular/router"; import { ActivatedRoute, Router, RouterModule } from "@angular/router";
import { first, firstValueFrom, Subject, takeUntil } from "rxjs"; import { first, firstValueFrom, Subject, take, takeUntil } from "rxjs";
import { JslibModule } from "@bitwarden/angular/jslib.module"; import { JslibModule } from "@bitwarden/angular/jslib.module";
import { LoginEmailServiceAbstraction } from "@bitwarden/auth/common"; import { LoginEmailServiceAbstraction } from "@bitwarden/auth/common";
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
import { ClientType } from "@bitwarden/common/enums"; import { ClientType } from "@bitwarden/common/enums";
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { import {
AsyncActionsModule, AsyncActionsModule,
ButtonModule, ButtonModule,
@@ -33,15 +36,27 @@ import { LoginService } from "./login.service";
RouterModule, RouterModule,
], ],
}) })
export class LoginComponentV2 implements OnInit { export class LoginComponentV2 implements OnInit, OnDestroy {
@ViewChild("masterPasswordInput", { static: true }) masterPasswordInput: ElementRef;
private destroy$ = new Subject<void>();
clientType: ClientType; clientType: ClientType;
showLoginWithDevice = false;
validatedEmail = false;
formGroup = this.formBuilder.group({ formGroup = this.formBuilder.group({
email: ["", [Validators.required, Validators.email]], email: ["", [Validators.required, Validators.email]],
masterPassword: [
"",
[Validators.required, Validators.minLength(Utils.originalMinimumPasswordLength)],
],
rememberEmail: [false], rememberEmail: [false],
}); });
private destroy$ = new Subject<void>(); get loggedEmail() {
return this.formGroup.value.email;
}
// Web specific properties // Web specific properties
enforcedPasswordPolicyOptions: MasterPasswordPolicyOptions; enforcedPasswordPolicyOptions: MasterPasswordPolicyOptions;
@@ -50,9 +65,12 @@ export class LoginComponentV2 implements OnInit {
constructor( constructor(
private activatedRoute: ActivatedRoute, private activatedRoute: ActivatedRoute,
private appIdService: AppIdService,
private devicesApiService: DevicesApiServiceAbstraction,
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
private loginEmailService: LoginEmailServiceAbstraction, private loginEmailService: LoginEmailServiceAbstraction,
private loginService: LoginService, private loginService: LoginService,
private ngZone: NgZone,
private platformUtilsService: PlatformUtilsService, private platformUtilsService: PlatformUtilsService,
private router: Router, private router: Router,
) { ) {
@@ -96,11 +114,57 @@ export class LoginComponentV2 implements OnInit {
} }
} }
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
submit = async () => {}; submit = async () => {};
async validateEmail() {} protected async validateEmail(): Promise<void> {
this.formGroup.controls.email.markAsTouched();
const emailValid = this.formGroup.controls.email.valid;
private async loadEmailSettings() { if (emailValid) {
this.toggleValidateEmail(true);
await this.getLoginWithDevice(this.loggedEmail);
}
}
protected toggleValidateEmail(value: boolean): void {
this.validatedEmail = value;
if (!this.validatedEmail) {
// Reset master password only when going from validated to not validated so that autofill can work properly
this.formGroup.controls.masterPassword.reset();
} else {
// Mark MP as untouched so that, when users enter email and hit enter, the MP field doesn't load with validation errors
this.formGroup.controls.masterPassword.markAsUntouched();
// When email is validated, focus on master password after waiting for input to be rendered
if (this.ngZone.isStable) {
this.masterPasswordInput?.nativeElement?.focus();
} else {
this.ngZone.onStable.pipe(take(1), takeUntil(this.destroy$)).subscribe(() => {
this.masterPasswordInput?.nativeElement?.focus();
});
}
}
}
private async getLoginWithDevice(email: string): Promise<void> {
try {
const deviceIdentifier = await this.appIdService.getAppId();
this.showLoginWithDevice = await this.devicesApiService.getKnownDevice(
email,
deviceIdentifier,
);
} catch (e) {
this.showLoginWithDevice = false;
}
}
private async loadEmailSettings(): Promise<void> {
// Try to load the email from memory first // Try to load the email from memory first
const email = this.loginEmailService.getEmail(); const email = this.loginEmailService.getEmail();
const rememberEmail = this.loginEmailService.getRememberEmail(); const rememberEmail = this.loginEmailService.getRememberEmail();