From 77f1e0254ed1db09cb2936de542739702a6915c6 Mon Sep 17 00:00:00 2001 From: Jared Snider Date: Mon, 3 Feb 2025 18:35:17 -0500 Subject: [PATCH] PM-8113 - DesktopTwoFactorAuthDuoComponentService - add tests --- ...-factor-auth-duo-component.service.spec.ts | 93 +++++++++++++++++++ ...p-two-factor-auth-duo-component.service.ts | 1 - 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 apps/desktop/src/auth/services/desktop-two-factor-auth-duo-component.service.spec.ts diff --git a/apps/desktop/src/auth/services/desktop-two-factor-auth-duo-component.service.spec.ts b/apps/desktop/src/auth/services/desktop-two-factor-auth-duo-component.service.spec.ts new file mode 100644 index 0000000000..12ca8013b1 --- /dev/null +++ b/apps/desktop/src/auth/services/desktop-two-factor-auth-duo-component.service.spec.ts @@ -0,0 +1,93 @@ +import { MockProxy, mock } from "jest-mock-extended"; +import { BehaviorSubject, firstValueFrom } from "rxjs"; + +import { + Environment, + EnvironmentService, +} from "@bitwarden/common/platform/abstractions/environment.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { MessageListener } from "@bitwarden/common/platform/messaging"; + +import { DesktopTwoFactorAuthDuoComponentService } from "./desktop-two-factor-auth-duo-component.service"; + +describe("DesktopTwoFactorAuthDuoComponentService", () => { + let desktopTwoFactorAuthDuoComponentService: DesktopTwoFactorAuthDuoComponentService; + let messageListener: MockProxy; + let environmentService: MockProxy; + let i18nService: MockProxy; + let platformUtilsService: MockProxy; + + beforeEach(() => { + jest.clearAllMocks(); + + messageListener = mock(); + environmentService = mock(); + i18nService = mock(); + platformUtilsService = mock(); + + desktopTwoFactorAuthDuoComponentService = new DesktopTwoFactorAuthDuoComponentService( + messageListener, + environmentService, + i18nService, + platformUtilsService, + ); + }); + + describe("listenForDuo2faResult$", () => { + it("should return an observable that emits a duo 2FA result when a duo result message is received", async () => { + const message: { code: string; state: string } = { + code: "123456", + state: "abcdef", + }; + const expectedDuo2faResult = { + code: message.code, + state: message.state, + token: `${message.code}|${message.state}`, + }; + + const messages = new BehaviorSubject(message); + messageListener.messages$.mockReturnValue(messages); + + const duo2faResult = await firstValueFrom( + desktopTwoFactorAuthDuoComponentService.listenForDuo2faResult$(), + ); + expect(duo2faResult).toEqual(expectedDuo2faResult); + }); + }); + + describe("launchDuoFrameless", () => { + it("should build and launch the duo frameless URL", async () => { + // Arrange + const duoFramelessUrl = "https://duoFramelessUrl"; + const webVaultUrl = "https://webVaultUrl"; + + i18nService.t.mockImplementation((key) => key); + + const handOffMessage = { + title: "youSuccessfullyLoggedIn", + message: "youMayCloseThisWindow", + isCountdown: false, + }; + + const mockEnvironment = { + getWebVaultUrl: () => webVaultUrl, + } as unknown as Environment; + const environmentBSubject = new BehaviorSubject(mockEnvironment); + environmentService.environment$ = environmentBSubject.asObservable(); + + // Act + await desktopTwoFactorAuthDuoComponentService.launchDuoFrameless(duoFramelessUrl); + + // Assert + const launchUrl = + webVaultUrl + + "/duo-redirect-connector.html" + + "?duoFramelessUrl=" + + encodeURIComponent(duoFramelessUrl) + + "&handOffMessage=" + + encodeURIComponent(JSON.stringify(handOffMessage)); + expect(platformUtilsService.launchUri).toHaveBeenCalledWith(launchUrl); + }); + }); +}); diff --git a/apps/desktop/src/auth/services/desktop-two-factor-auth-duo-component.service.ts b/apps/desktop/src/auth/services/desktop-two-factor-auth-duo-component.service.ts index d051124a6b..eef03ca5b5 100644 --- a/apps/desktop/src/auth/services/desktop-two-factor-auth-duo-component.service.ts +++ b/apps/desktop/src/auth/services/desktop-two-factor-auth-duo-component.service.ts @@ -11,7 +11,6 @@ import { CommandDefinition, MessageListener } from "@bitwarden/common/platform/m // We should explore consolidating the messaging approach across clients - i.e., we // should use the same command definition across all clients. We use duoResult on extension for no real // benefit. -// TODO: add tests export const DUO_2FA_RESULT_COMMAND = new CommandDefinition<{ code: string; state: string }>( "duoCallback", );