From 67d0c2a59ad548e9f73d2e857ccd47c5dbb3f862 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Mon, 17 Nov 2025 15:54:39 +0100 Subject: [PATCH] FIx test --- .../webauthn-login-admin.service.spec.ts | 76 +++++-------------- 1 file changed, 21 insertions(+), 55 deletions(-) diff --git a/apps/web/src/app/auth/core/services/webauthn-login/webauthn-login-admin.service.spec.ts b/apps/web/src/app/auth/core/services/webauthn-login/webauthn-login-admin.service.spec.ts index 7e263b638e0..27b86417005 100644 --- a/apps/web/src/app/auth/core/services/webauthn-login/webauthn-login-admin.service.spec.ts +++ b/apps/web/src/app/auth/core/services/webauthn-login/webauthn-login-admin.service.spec.ts @@ -6,6 +6,10 @@ import { mock, MockProxy } from "jest-mock-extended"; import { of } from "rxjs"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; +import { + PublicKeyCredential as CustomPublicKeyCredential, + AuthenticatorAssertionResponse as CustomAuthenticatorAssertionResponse, +} from "@bitwarden/common/auth/abstractions/webauthn/navigator-credentials.service"; import { WebAuthnLoginPrfKeyServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login-prf-key.service.abstraction"; import { WebAuthnLoginCredentialAssertionView } from "@bitwarden/common/auth/models/view/webauthn-login/webauthn-login-credential-assertion.view"; import { WebAuthnLoginAssertionResponseRequest } from "@bitwarden/common/auth/services/webauthn-login/request/webauthn-login-assertion-response.request"; @@ -64,8 +68,6 @@ describe("WebauthnAdminService", () => { // Save original global class originalAuthenticatorAssertionResponse = global.AuthenticatorAssertionResponse; - // Mock the global AuthenticatorAssertionResponse class b/c the class is only available in secure contexts - global.AuthenticatorAssertionResponse = MockAuthenticatorAssertionResponse; keyService.userKey$.mockReturnValue(of(mockUserKey)); }); @@ -117,7 +119,7 @@ describe("WebauthnAdminService", () => { describe("enableCredentialEncryption", () => { it("should call the necessary methods to update the credential", async () => { // Arrange - const response = new MockPublicKeyCredential(); + const response = mockPublicKeyCredential; const prfKeySet = new RotateableKeySet( new EncString("test_encryptedUserKey"), new EncString("test_encryptedPublicKey"), @@ -154,7 +156,7 @@ describe("WebauthnAdminService", () => { it("should throw error when PRF Key is undefined", async () => { // Arrange - const response = new MockPublicKeyCredential(); + const response = mockPublicKeyCredential; const assertionOptions: WebAuthnLoginCredentialAssertionView = new WebAuthnLoginCredentialAssertionView( @@ -181,7 +183,7 @@ describe("WebauthnAdminService", () => { }); test.each([null, undefined, ""])("should throw an error when userId is %p", async (userId) => { - const response = new MockPublicKeyCredential(); + const response = mockPublicKeyCredential; const assertionOptions: WebAuthnLoginCredentialAssertionView = new WebAuthnLoginCredentialAssertionView( "enable_credential_encryption_test_token", @@ -394,57 +396,21 @@ function createDeviceResponse({ prf = false }: { prf?: boolean } = {}): PublicKe return credential; } -/** - * Mocks for the PublicKeyCredential and AuthenticatorAssertionResponse classes copied from webauthn-login.service.spec.ts - */ - // AuthenticatorAssertionResponse && PublicKeyCredential are only available in secure contexts // so we need to mock them and assign them to the global object to make them available // for the tests -class MockAuthenticatorAssertionResponse implements AuthenticatorAssertionResponse { - clientDataJSON: ArrayBuffer = randomBytes(32).buffer; - authenticatorData: ArrayBuffer = randomBytes(196).buffer; - signature: ArrayBuffer = randomBytes(72).buffer; - userHandle: ArrayBuffer = randomBytes(16).buffer; +const mockAuthenticatorAssertionResponse: CustomAuthenticatorAssertionResponse = { + clientDataJSON: randomBytes(32), + authenticatorData: randomBytes(196), + signature: randomBytes(72), + userHandle: randomBytes(16), +}; - clientDataJSONB64Str = Utils.fromBufferToUrlB64(this.clientDataJSON); - authenticatorDataB64Str = Utils.fromBufferToUrlB64(this.authenticatorData); - signatureB64Str = Utils.fromBufferToUrlB64(this.signature); - userHandleB64Str = Utils.fromBufferToUrlB64(this.userHandle); -} - -class MockPublicKeyCredential implements PublicKeyCredential { - authenticatorAttachment = "cross-platform"; - id = "mockCredentialId"; - type = "public-key"; - rawId: ArrayBuffer = randomBytes(32).buffer; - rawIdB64Str = Utils.fromBufferToUrlB64(this.rawId); - - response: MockAuthenticatorAssertionResponse = new MockAuthenticatorAssertionResponse(); - - // Use random 64 character hex string (32 bytes - matters for symmetric key creation) - // to represent the prf key binary data and convert to ArrayBuffer - // Creating the array buffer from a known hex value allows us to - // assert on the value in tests - private prfKeyArrayBuffer: ArrayBuffer = Utils.hexStringToArrayBuffer( - "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", - ); - - getClientExtensionResults(): any { - return { - prf: { - results: { - first: this.prfKeyArrayBuffer, - }, - }, - }; - } - - static isConditionalMediationAvailable(): Promise { - return Promise.resolve(false); - } - - static isUserVerifyingPlatformAuthenticatorAvailable(): Promise { - return Promise.resolve(false); - } -} +const mockPublicKeyCredential: CustomPublicKeyCredential = { + authenticatorAttachment: "cross-platform", + id: "mockCredentialId", + type: "public-key", + rawId: randomBytes(32), + response: mockAuthenticatorAssertionResponse, + prf: randomBytes(32), +};