fix(passkey): add test for verifying passkey authentication and returning user

This commit is contained in:
ouwargui
2025-10-10 03:15:27 -03:00
committed by Alex Yang
parent 49750bb91f
commit df1281bec0

View File

@@ -1,10 +1,19 @@
import { createAuthClient } from "better-auth/client";
import { getTestInstance } from "better-auth/test";
import { describe, expect, it } from "vitest";
import { describe, expect, it, vi } from "vitest";
import type { Passkey } from ".";
import { passkey } from ".";
import { passkeyClient } from "./client";
vi.mock("@simplewebauthn/server", async (importOriginal) => {
const actual =
await importOriginal<typeof import("@simplewebauthn/server")>();
return {
...actual,
verifyAuthenticationResponse: vi.fn(),
};
});
describe("passkey", async () => {
const { auth, signInWithTestUser, customFetchImpl } = await getTestInstance({
plugins: [passkey()],
@@ -121,4 +130,90 @@ describe("passkey", async () => {
});
expect(deleteResult).toBe(null);
});
it("should verify passkey authentication and return user", async () => {
const { headers, user } = await signInWithTestUser();
const context = await auth.$context;
await context.adapter.create<Omit<Passkey, "id">, Passkey>({
model: "passkey",
data: {
userId: user.id,
publicKey: "mockPublicKey",
name: "mockName",
counter: 0,
deviceType: "singleDevice",
credentialID: "mockCredentialID",
createdAt: new Date(),
backedUp: false,
transports: "mockTransports",
aaguid: "mockAAGUID",
} satisfies Omit<Passkey, "id">,
});
const client = createAuthClient({
plugins: [passkeyClient()],
baseURL: "http://localhost:3000/api/auth",
fetchOptions: {
headers: headers,
customFetchImpl,
},
});
let passkeyCookie = "";
await client.passkey.generateAuthenticateOptions({
fetchOptions: {
onResponse(context) {
const setCookie = context.response.headers.get("Set-Cookie");
if (setCookie) {
passkeyCookie = setCookie;
}
},
},
});
// Mock the verification response
const { verifyAuthenticationResponse } = await import(
"@simplewebauthn/server"
);
const mockedVerify = verifyAuthenticationResponse as unknown as ReturnType<
typeof vi.fn
>;
mockedVerify.mockResolvedValueOnce({
verified: true,
authenticationInfo: {
newCounter: 1,
},
});
const currentCookie = (headers as any).cookie || "";
const combinedCookie = currentCookie
? `${currentCookie}; ${passkeyCookie}`
: passkeyCookie;
const response = await auth.api.verifyPasskeyAuthentication({
headers: {
...headers,
cookie: combinedCookie,
origin: "http://localhost:3000",
},
body: {
response: {
id: "mockCredentialID",
rawId: "mockRawId",
response: {
clientDataJSON: "mockClientDataJSON",
authenticatorData: "mockAuthenticatorData",
signature: "mockSignature",
userHandle: "mockUserHandle",
},
type: "public-key",
clientExtensionResults: {},
},
},
});
expect(response).toHaveProperty("user");
expect(response.user).toHaveProperty("id", user.id);
expect(response.user).toHaveProperty("email", user.email);
});
});