mirror of
https://github.com/bitwarden/browser
synced 2026-02-27 10:03:23 +00:00
[PM-32237] Add back functionality to email OTP auth flow (#19024)
* add back functionality to OTP auth flow * respond to review comments * hoist email value to parent component --------- Co-authored-by: Alex Dragovich <46065570+itsadrago@users.noreply.github.com>
This commit is contained in:
@@ -20,16 +20,18 @@
|
|||||||
<bit-label>{{ "verificationCode" | i18n }}</bit-label>
|
<bit-label>{{ "verificationCode" | i18n }}</bit-label>
|
||||||
<input bitInput type="text" [formControl]="otp" required appInputVerbatim appAutofocus />
|
<input bitInput type="text" [formControl]="otp" required appInputVerbatim appAutofocus />
|
||||||
</bit-form-field>
|
</bit-form-field>
|
||||||
<div class="tw-flex">
|
<button
|
||||||
<button
|
bitButton
|
||||||
bitButton
|
bitFormButton
|
||||||
bitFormButton
|
type="submit"
|
||||||
type="submit"
|
buttonType="primary"
|
||||||
buttonType="primary"
|
[loading]="loading()"
|
||||||
[loading]="loading()"
|
[block]="true"
|
||||||
[block]="true"
|
class="tw-mb-3"
|
||||||
>
|
>
|
||||||
<span>{{ "viewSend" | i18n }} </span>
|
<span>{{ "viewSend" | i18n }} </span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
<button bitButton type="button" buttonType="secondary" [block]="true" (click)="onBackClick()">
|
||||||
|
<span>{{ "back" | i18n }}</span>
|
||||||
|
</button>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
// FIXME: Update this file to be type safe and remove this and next line
|
// FIXME: Update this file to be type safe and remove this and next line
|
||||||
// @ts-strict-ignore
|
// @ts-strict-ignore
|
||||||
import { ChangeDetectionStrategy, Component, input, OnDestroy, OnInit } from "@angular/core";
|
import {
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
Component,
|
||||||
|
effect,
|
||||||
|
input,
|
||||||
|
OnDestroy,
|
||||||
|
OnInit,
|
||||||
|
output,
|
||||||
|
} from "@angular/core";
|
||||||
import { FormControl, FormGroup, Validators } from "@angular/forms";
|
import { FormControl, FormGroup, Validators } from "@angular/forms";
|
||||||
|
|
||||||
import { SharedModule } from "../../../shared";
|
import { SharedModule } from "../../../shared";
|
||||||
@@ -18,18 +26,45 @@ export class SendAccessEmailComponent implements OnInit, OnDestroy {
|
|||||||
protected otp: FormControl;
|
protected otp: FormControl;
|
||||||
|
|
||||||
readonly loading = input.required<boolean>();
|
readonly loading = input.required<boolean>();
|
||||||
|
readonly backToEmail = output<void>();
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.email = new FormControl("", Validators.required);
|
this.email = new FormControl("", Validators.required);
|
||||||
this.otp = new FormControl("", Validators.required);
|
this.otp = new FormControl("");
|
||||||
this.formGroup().addControl("email", this.email);
|
this.formGroup().addControl("email", this.email);
|
||||||
this.formGroup().addControl("otp", this.otp);
|
this.formGroup().addControl("otp", this.otp);
|
||||||
}
|
|
||||||
|
|
||||||
|
// Update validators when enterOtp changes
|
||||||
|
effect(() => {
|
||||||
|
const isOtpMode = this.enterOtp();
|
||||||
|
if (isOtpMode) {
|
||||||
|
// In OTP mode: email is not required (already entered), otp is required
|
||||||
|
this.email.clearValidators();
|
||||||
|
this.otp.setValidators([Validators.required]);
|
||||||
|
} else {
|
||||||
|
// In email mode: email is required, otp is not required
|
||||||
|
this.email.setValidators([Validators.required]);
|
||||||
|
this.otp.clearValidators();
|
||||||
|
}
|
||||||
|
this.email.updateValueAndValidity();
|
||||||
|
this.otp.updateValueAndValidity();
|
||||||
|
});
|
||||||
|
}
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.formGroup().removeControl("email");
|
this.formGroup().removeControl("email");
|
||||||
this.formGroup().removeControl("otp");
|
this.formGroup().removeControl("otp");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onBackClick() {
|
||||||
|
this.backToEmail.emit();
|
||||||
|
if (this.otp) {
|
||||||
|
this.otp.clearValidators();
|
||||||
|
this.otp.setValue("");
|
||||||
|
this.otp.setErrors(null);
|
||||||
|
this.otp.markAsUntouched();
|
||||||
|
this.otp.markAsPristine();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
[formGroup]="sendAccessForm"
|
[formGroup]="sendAccessForm"
|
||||||
[enterOtp]="enterOtp()"
|
[enterOtp]="enterOtp()"
|
||||||
[loading]="loading()"
|
[loading]="loading()"
|
||||||
|
(backToEmail)="onBackToEmail()"
|
||||||
></app-send-access-email>
|
></app-send-access-email>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,11 @@ export class SendAuthComponent implements OnInit {
|
|||||||
this.loading.set(false);
|
this.loading.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onBackToEmail() {
|
||||||
|
this.enterOtp.set(false);
|
||||||
|
this.updatePageTitle();
|
||||||
|
}
|
||||||
|
|
||||||
private async attemptV1Access() {
|
private async attemptV1Access() {
|
||||||
try {
|
try {
|
||||||
const accessRequest = new SendAccessRequest();
|
const accessRequest = new SendAccessRequest();
|
||||||
@@ -247,10 +252,12 @@ export class SendAuthComponent implements OnInit {
|
|||||||
if (this.enterOtp()) {
|
if (this.enterOtp()) {
|
||||||
this.anonLayoutWrapperDataService.setAnonLayoutWrapperData({
|
this.anonLayoutWrapperDataService.setAnonLayoutWrapperData({
|
||||||
pageTitle: { key: "enterTheCodeSentToYourEmail" },
|
pageTitle: { key: "enterTheCodeSentToYourEmail" },
|
||||||
|
pageSubtitle: this.sendAccessForm.value.email ?? null,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.anonLayoutWrapperDataService.setAnonLayoutWrapperData({
|
this.anonLayoutWrapperDataService.setAnonLayoutWrapperData({
|
||||||
pageTitle: { key: "verifyYourEmailToViewThisSend" },
|
pageTitle: { key: "verifyYourEmailToViewThisSend" },
|
||||||
|
pageSubtitle: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (authType === AuthType.Password) {
|
} else if (authType === AuthType.Password) {
|
||||||
|
|||||||
Reference in New Issue
Block a user