From 5b1c1d50eb0f31f366f8d35a4af060dbcf10568b Mon Sep 17 00:00:00 2001 From: Will Martin Date: Wed, 25 Oct 2023 08:40:00 -0400 Subject: [PATCH] add lastpass mfa dialog variant scaffolding; add yubikey variant (#6687) --- apps/browser/src/_locales/en/messages.json | 3 ++ apps/desktop/src/locales/en/messages.json | 3 ++ ...lastpass-multifactor-prompt.component.html | 2 +- .../lastpass-multifactor-prompt.component.ts | 20 +++++++++-- .../lastpass-direct-import-ui.service.ts | 35 +++++++++++-------- 5 files changed, 45 insertions(+), 18 deletions(-) diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 52ad849a23..529ead2d6c 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -2674,5 +2674,8 @@ }, "collection": { "message": "Collection" + }, + "lastPassYubikeyDesc": { + "message": "Insert the YubiKey associated with your LastPass account into your computer's USB port, then touch its button." } } diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index ecd8e9a596..365d5bb2b6 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -2602,5 +2602,8 @@ }, "collection": { "message": "Collection" + }, + "lastPassYubikeyDesc": { + "message": "Insert the YubiKey associated with your LastPass account into your computer's USB port, then touch its button." } } diff --git a/libs/importer/src/components/lastpass/dialog/lastpass-multifactor-prompt.component.html b/libs/importer/src/components/lastpass/dialog/lastpass-multifactor-prompt.component.html index 1b933ec987..ab4cd6a622 100644 --- a/libs/importer/src/components/lastpass/dialog/lastpass-multifactor-prompt.component.html +++ b/libs/importer/src/components/lastpass/dialog/lastpass-multifactor-prompt.component.html @@ -5,7 +5,7 @@
-

{{ description | i18n }}

+

{{ descriptionI18nKey | i18n }}

{{ "passcode" | i18n }} diff --git a/libs/importer/src/components/lastpass/dialog/lastpass-multifactor-prompt.component.ts b/libs/importer/src/components/lastpass/dialog/lastpass-multifactor-prompt.component.ts index f0094111c9..c3167bfea4 100644 --- a/libs/importer/src/components/lastpass/dialog/lastpass-multifactor-prompt.component.ts +++ b/libs/importer/src/components/lastpass/dialog/lastpass-multifactor-prompt.component.ts @@ -14,8 +14,10 @@ import { TypographyModule, } from "@bitwarden/components"; +export type LastPassMultifactorPromptVariant = "otp" | "oob" | "yubikey"; + type LastPassMultifactorPromptData = { - isOOB?: boolean; + variant: LastPassMultifactorPromptVariant; }; @Component({ @@ -34,7 +36,19 @@ type LastPassMultifactorPromptData = { ], }) export class LastPassMultifactorPromptComponent { - protected description = this.data?.isOOB ? "lastPassOOBDesc" : "lastPassMFADesc"; + private variant = this.data.variant; + + protected get descriptionI18nKey(): string { + switch (this.variant) { + case "oob": + return "lastPassOOBDesc"; + case "yubikey": + return "lastPassYubikeyDesc"; + case "otp": + default: + return "lastPassMFADesc"; + } + } protected formGroup = new FormGroup({ passcode: new FormControl("", { @@ -56,7 +70,7 @@ export class LastPassMultifactorPromptComponent { this.dialogRef.close(this.formGroup.value.passcode); }; - static open(dialogService: DialogService, data?: LastPassMultifactorPromptData) { + static open(dialogService: DialogService, data: LastPassMultifactorPromptData) { return dialogService.open(LastPassMultifactorPromptComponent, { data }); } } diff --git a/libs/importer/src/components/lastpass/lastpass-direct-import-ui.service.ts b/libs/importer/src/components/lastpass/lastpass-direct-import-ui.service.ts index 036f340299..256b2b226c 100644 --- a/libs/importer/src/components/lastpass/lastpass-direct-import-ui.service.ts +++ b/libs/importer/src/components/lastpass/lastpass-direct-import-ui.service.ts @@ -8,6 +8,10 @@ import { OtpResult, OobResult } from "../../importers/lastpass/access/models"; import { Ui } from "../../importers/lastpass/access/ui"; import { LastPassMultifactorPromptComponent } from "./dialog"; +import { LastPassMultifactorPromptVariant } from "./dialog/lastpass-multifactor-prompt.component"; + +type OtpDialogVariant = Extract; +type OobDialogVariant = Extract; @Injectable({ providedIn: "root", @@ -17,43 +21,46 @@ export class LastPassDirectImportUIService implements Ui { constructor(private dialogService: DialogService) {} - private async getOTPResult() { - this.mfaDialogRef = LastPassMultifactorPromptComponent.open(this.dialogService); - const passcode = await firstValueFrom(this.mfaDialogRef.closed); + private async getOTPResult(variant: OtpDialogVariant) { + const passcode = await this.openMFADialog(variant); return new OtpResult(passcode, false); } - private async getOOBResult() { - this.mfaDialogRef = LastPassMultifactorPromptComponent.open(this.dialogService, { - isOOB: true, - }); - const passcode = await firstValueFrom(this.mfaDialogRef.closed); + private async getOOBResult(variant: OobDialogVariant) { + const passcode = await this.openMFADialog(variant); return new OobResult(false, passcode, false); } + private openMFADialog(variant: LastPassMultifactorPromptVariant) { + this.mfaDialogRef = LastPassMultifactorPromptComponent.open(this.dialogService, { + variant, + }); + return firstValueFrom(this.mfaDialogRef.closed); + } + closeMFADialog() { this.mfaDialogRef?.close(); } async provideGoogleAuthPasscode() { - return this.getOTPResult(); + return this.getOTPResult("otp"); } async provideMicrosoftAuthPasscode() { - return this.getOTPResult(); + return this.getOTPResult("otp"); } async provideYubikeyPasscode() { - return this.getOTPResult(); + return this.getOTPResult("yubikey"); } async approveLastPassAuth() { - return this.getOOBResult(); + return this.getOOBResult("oob"); } async approveDuo() { - return this.getOOBResult(); + return this.getOOBResult("oob"); } async approveSalesforceAuth() { - return this.getOOBResult(); + return this.getOOBResult("oob"); } }