mirror of
https://github.com/bitwarden/browser
synced 2025-12-16 16:23:44 +00:00
add validateEmail logic
This commit is contained in:
@@ -47,6 +47,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
|
<!-- TODO-rr-bw: More here -->
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-----------------------------------
|
<!-----------------------------------
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user