mirror of
https://github.com/bitwarden/browser
synced 2026-01-02 16:43:19 +00:00
PM-4945 Update Two Factor verify dialog (#8580)
* PM-4945 Update Two Factor verify dialog * PM-4945 Addressed review comments * PM-4945 Removed legacy User verification component and used new one
This commit is contained in:
committed by
GitHub
parent
11ba8d188d
commit
2fa4c6e4f9
@@ -1,5 +1,5 @@
|
||||
import { Component, OnDestroy, OnInit, Type, ViewChild, ViewContainerRef } from "@angular/core";
|
||||
import { firstValueFrom, Observable, Subject, takeUntil } from "rxjs";
|
||||
import { firstValueFrom, lastValueFrom, Observable, Subject, takeUntil } from "rxjs";
|
||||
|
||||
import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref";
|
||||
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||
@@ -8,15 +8,23 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||
import { TwoFactorAuthenticatorResponse } from "@bitwarden/common/auth/models/response/two-factor-authenticator.response";
|
||||
import { TwoFactorDuoResponse } from "@bitwarden/common/auth/models/response/two-factor-duo.response";
|
||||
import { TwoFactorEmailResponse } from "@bitwarden/common/auth/models/response/two-factor-email.response";
|
||||
import { TwoFactorWebAuthnResponse } from "@bitwarden/common/auth/models/response/two-factor-web-authn.response";
|
||||
import { TwoFactorYubiKeyResponse } from "@bitwarden/common/auth/models/response/two-factor-yubi-key.response";
|
||||
import { TwoFactorProviders } from "@bitwarden/common/auth/services/two-factor.service";
|
||||
import { AuthResponse } from "@bitwarden/common/auth/types/auth-response";
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { ProductType } from "@bitwarden/common/enums";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
|
||||
import { TwoFactorAuthenticatorComponent } from "./two-factor-authenticator.component";
|
||||
import { TwoFactorDuoComponent } from "./two-factor-duo.component";
|
||||
import { TwoFactorEmailComponent } from "./two-factor-email.component";
|
||||
import { TwoFactorRecoveryComponent } from "./two-factor-recovery.component";
|
||||
import { TwoFactorVerifyComponent } from "./two-factor-verify.component";
|
||||
import { TwoFactorWebAuthnComponent } from "./two-factor-webauthn.component";
|
||||
import { TwoFactorYubiKeyComponent } from "./two-factor-yubikey.component";
|
||||
|
||||
@@ -52,6 +60,7 @@ export class TwoFactorSetupComponent implements OnInit, OnDestroy {
|
||||
private twoFactorAuthPolicyAppliesToActiveUser: boolean;
|
||||
|
||||
constructor(
|
||||
protected dialogService: DialogService,
|
||||
protected apiService: ApiService,
|
||||
protected modalService: ModalService,
|
||||
protected messagingService: MessagingService,
|
||||
@@ -114,50 +123,82 @@ export class TwoFactorSetupComponent implements OnInit, OnDestroy {
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
async callTwoFactorVerifyDialog(type?: TwoFactorProviderType) {
|
||||
const twoFactorVerifyDialogRef = TwoFactorVerifyComponent.open(this.dialogService, {
|
||||
data: { type: type, organizationId: this.organizationId },
|
||||
});
|
||||
return await lastValueFrom(twoFactorVerifyDialogRef.closed);
|
||||
}
|
||||
|
||||
async manage(type: TwoFactorProviderType) {
|
||||
switch (type) {
|
||||
case TwoFactorProviderType.Authenticator: {
|
||||
const result: AuthResponse<TwoFactorAuthenticatorResponse> =
|
||||
await this.callTwoFactorVerifyDialog(type);
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
const authComp = await this.openModal(
|
||||
this.authenticatorModalRef,
|
||||
TwoFactorAuthenticatorComponent,
|
||||
);
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
||||
authComp.onUpdated.subscribe((enabled: boolean) => {
|
||||
await authComp.auth(result);
|
||||
authComp.onUpdated.pipe(takeUntil(this.destroy$)).subscribe((enabled: boolean) => {
|
||||
this.updateStatus(enabled, TwoFactorProviderType.Authenticator);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case TwoFactorProviderType.Yubikey: {
|
||||
const result: AuthResponse<TwoFactorYubiKeyResponse> =
|
||||
await this.callTwoFactorVerifyDialog(type);
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
const yubiComp = await this.openModal(this.yubikeyModalRef, TwoFactorYubiKeyComponent);
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
||||
yubiComp.onUpdated.subscribe((enabled: boolean) => {
|
||||
yubiComp.auth(result);
|
||||
yubiComp.onUpdated.pipe(takeUntil(this.destroy$)).subscribe((enabled: boolean) => {
|
||||
this.updateStatus(enabled, TwoFactorProviderType.Yubikey);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case TwoFactorProviderType.Duo: {
|
||||
const result: AuthResponse<TwoFactorDuoResponse> =
|
||||
await this.callTwoFactorVerifyDialog(type);
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
const duoComp = await this.openModal(this.duoModalRef, TwoFactorDuoComponent);
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
||||
duoComp.onUpdated.subscribe((enabled: boolean) => {
|
||||
duoComp.auth(result);
|
||||
duoComp.onUpdated.pipe(takeUntil(this.destroy$)).subscribe((enabled: boolean) => {
|
||||
this.updateStatus(enabled, TwoFactorProviderType.Duo);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case TwoFactorProviderType.Email: {
|
||||
const result: AuthResponse<TwoFactorEmailResponse> =
|
||||
await this.callTwoFactorVerifyDialog(type);
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
const emailComp = await this.openModal(this.emailModalRef, TwoFactorEmailComponent);
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
||||
emailComp.onUpdated.subscribe((enabled: boolean) => {
|
||||
await emailComp.auth(result);
|
||||
emailComp.onUpdated.pipe(takeUntil(this.destroy$)).subscribe((enabled: boolean) => {
|
||||
this.updateStatus(enabled, TwoFactorProviderType.Email);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case TwoFactorProviderType.WebAuthn: {
|
||||
const result: AuthResponse<TwoFactorWebAuthnResponse> =
|
||||
await this.callTwoFactorVerifyDialog(type);
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
const webAuthnComp = await this.openModal(
|
||||
this.webAuthnModalRef,
|
||||
TwoFactorWebAuthnComponent,
|
||||
);
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
||||
webAuthnComp.onUpdated.subscribe((enabled: boolean) => {
|
||||
webAuthnComp.auth(result);
|
||||
webAuthnComp.onUpdated.pipe(takeUntil(this.destroy$)).subscribe((enabled: boolean) => {
|
||||
this.updateStatus(enabled, TwoFactorProviderType.WebAuthn);
|
||||
});
|
||||
break;
|
||||
@@ -167,10 +208,12 @@ export class TwoFactorSetupComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
recoveryCode() {
|
||||
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this.openModal(this.recoveryModalRef, TwoFactorRecoveryComponent);
|
||||
async recoveryCode() {
|
||||
const result = await this.callTwoFactorVerifyDialog(-1 as TwoFactorProviderType);
|
||||
if (result) {
|
||||
const recoverComp = await this.openModal(this.recoveryModalRef, TwoFactorRecoveryComponent);
|
||||
recoverComp.auth(result);
|
||||
}
|
||||
}
|
||||
|
||||
async premiumRequired() {
|
||||
|
||||
Reference in New Issue
Block a user