mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 21:33:27 +00:00
[PM-7084] 4/6: Introduce shared email two-factor component (#9770)
* Add shared email two-factor component * Update apps/browser/src/auth/popup/two-factor-auth-email.component.ts Co-authored-by: Jake Fink <jfink@bitwarden.com> --------- Co-authored-by: Jake Fink <jfink@bitwarden.com>
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
<p bitTypography="body1">
|
||||
{{ "enterVerificationCodeEmail" | i18n: twoFactorEmail }}
|
||||
</p>
|
||||
<bit-form-field>
|
||||
<bit-label>{{ "verificationCode" | i18n }}</bit-label>
|
||||
<input
|
||||
bitInput
|
||||
type="text"
|
||||
appAutofocus
|
||||
appInputVerbatim
|
||||
[(ngModel)]="tokenValue"
|
||||
(input)="token.emit(tokenValue)"
|
||||
/>
|
||||
<bit-hint>
|
||||
<a bitLink href="#" appStopClick (click)="sendEmail(true)">
|
||||
{{ "sendVerificationCodeEmailAgain" | i18n }}
|
||||
</a></bit-hint
|
||||
>
|
||||
</bit-form-field>
|
||||
@@ -0,0 +1,109 @@
|
||||
import { DialogModule } from "@angular/cdk/dialog";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component, EventEmitter, Output } from "@angular/core";
|
||||
import { ReactiveFormsModule, FormsModule } from "@angular/forms";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { I18nPipe } from "@bitwarden/angular/platform/pipes/i18n.pipe";
|
||||
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service";
|
||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||
import { TwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/two-factor-email.request";
|
||||
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import {
|
||||
ButtonModule,
|
||||
LinkModule,
|
||||
TypographyModule,
|
||||
FormFieldModule,
|
||||
AsyncActionsModule,
|
||||
} from "@bitwarden/components";
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: "app-two-factor-auth-email",
|
||||
templateUrl: "two-factor-auth-email.component.html",
|
||||
imports: [
|
||||
CommonModule,
|
||||
JslibModule,
|
||||
DialogModule,
|
||||
ButtonModule,
|
||||
LinkModule,
|
||||
TypographyModule,
|
||||
ReactiveFormsModule,
|
||||
FormFieldModule,
|
||||
AsyncActionsModule,
|
||||
FormsModule,
|
||||
],
|
||||
providers: [I18nPipe],
|
||||
})
|
||||
export class TwoFactorAuthEmailComponent {
|
||||
@Output() token = new EventEmitter<string>();
|
||||
|
||||
twoFactorEmail: string = null;
|
||||
emailPromise: Promise<any>;
|
||||
tokenValue: string = "";
|
||||
|
||||
constructor(
|
||||
protected i18nService: I18nService,
|
||||
protected twoFactorService: TwoFactorService,
|
||||
protected loginStrategyService: LoginStrategyServiceAbstraction,
|
||||
protected platformUtilsService: PlatformUtilsService,
|
||||
protected logService: LogService,
|
||||
protected apiService: ApiService,
|
||||
protected appIdService: AppIdService,
|
||||
) {}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
const providerData = await this.twoFactorService.getProviders().then((providers) => {
|
||||
return providers.get(TwoFactorProviderType.Email);
|
||||
});
|
||||
this.twoFactorEmail = providerData.Email;
|
||||
|
||||
if ((await this.twoFactorService.getProviders()).size > 1) {
|
||||
await this.sendEmail(false);
|
||||
}
|
||||
}
|
||||
|
||||
async sendEmail(doToast: boolean) {
|
||||
if (this.emailPromise != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((await this.loginStrategyService.getEmail()) == null) {
|
||||
this.platformUtilsService.showToast(
|
||||
"error",
|
||||
this.i18nService.t("errorOccurred"),
|
||||
this.i18nService.t("sessionTimeout"),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const request = new TwoFactorEmailRequest();
|
||||
request.email = await this.loginStrategyService.getEmail();
|
||||
request.masterPasswordHash = await this.loginStrategyService.getMasterPasswordHash();
|
||||
request.ssoEmail2FaSessionToken =
|
||||
await this.loginStrategyService.getSsoEmail2FaSessionToken();
|
||||
request.deviceIdentifier = await this.appIdService.getAppId();
|
||||
request.authRequestAccessCode = await this.loginStrategyService.getAccessCode();
|
||||
request.authRequestId = await this.loginStrategyService.getAuthRequestId();
|
||||
this.emailPromise = this.apiService.postTwoFactorEmail(request);
|
||||
await this.emailPromise;
|
||||
if (doToast) {
|
||||
this.platformUtilsService.showToast(
|
||||
"success",
|
||||
null,
|
||||
this.i18nService.t("verificationCodeEmailSent", this.twoFactorEmail),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
this.logService.error(e);
|
||||
}
|
||||
|
||||
this.emailPromise = null;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
<form [bitSubmit]="submitForm" [formGroup]="formGroup" autocomplete="off">
|
||||
<div class="tw-min-w-96">
|
||||
<app-two-factor-auth-email
|
||||
(token)="token = $event"
|
||||
*ngIf="selectedProviderType === providerType.Email"
|
||||
/>
|
||||
<app-two-factor-auth-authenticator
|
||||
(token)="token = $event"
|
||||
*ngIf="selectedProviderType === providerType.Authenticator"
|
||||
|
||||
@@ -39,6 +39,7 @@ import {
|
||||
import { CaptchaProtectedComponent } from "../captcha-protected.component";
|
||||
|
||||
import { TwoFactorAuthAuthenticatorComponent } from "./two-factor-auth-authenticator.component";
|
||||
import { TwoFactorAuthEmailComponent } from "./two-factor-auth-email.component";
|
||||
import { TwoFactorAuthYubikeyComponent } from "./two-factor-auth-yubikey.component";
|
||||
import {
|
||||
TwoFactorOptionsDialogResult,
|
||||
@@ -60,6 +61,7 @@ import {
|
||||
ButtonModule,
|
||||
TwoFactorOptionsComponent,
|
||||
TwoFactorAuthAuthenticatorComponent,
|
||||
TwoFactorAuthEmailComponent,
|
||||
TwoFactorAuthYubikeyComponent,
|
||||
],
|
||||
providers: [I18nPipe],
|
||||
|
||||
Reference in New Issue
Block a user