1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-01 17:23:37 +00:00
This commit is contained in:
Bernd Schoolmann
2025-11-17 15:54:39 +01:00
parent 1443ec75e8
commit 67d0c2a59a

View File

@@ -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<PrfKey>(
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<boolean> {
return Promise.resolve(false);
}
static isUserVerifyingPlatformAuthenticatorAvailable(): Promise<boolean> {
return Promise.resolve(false);
}
}
const mockPublicKeyCredential: CustomPublicKeyCredential = {
authenticatorAttachment: "cross-platform",
id: "mockCredentialId",
type: "public-key",
rawId: randomBytes(32),
response: mockAuthenticatorAssertionResponse,
prf: randomBytes(32),
};