Files

57 lines
1.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
bytesToArrayBuffer,
bytesToBase64Url,
utf8ToBytes,
} from "../../src/crypto/encoding";
import {
parseAuthenticatorData,
parseClientData,
} from "../../src/webauthn/parser";
describe("WebAuthn parsers", () => {
it("parses collected client data without normalizing security fields", () => {
const json = utf8ToBytes(
JSON.stringify({
type: "webauthn.get",
challenge: "YWJj",
origin: "https://example.test",
crossOrigin: false,
}),
);
expect(parseClientData(bytesToBase64Url(json))).toMatchObject({
type: "webauthn.get",
origin: "https://example.test",
});
});
it("extracts flags and the unsigned signature counter", async () => {
const rpHash = new Uint8Array(
await crypto.subtle.digest(
"SHA-256",
bytesToArrayBuffer(utf8ToBytes("example.test")),
),
);
const bytes = Uint8Array.from([...rpHash, 0x05, 0x00, 0x00, 0x00, 0x09]);
const parsed = parseAuthenticatorData(bytes);
expect(parsed.flags).toMatchObject({
userPresent: true,
userVerified: true,
});
expect(parsed.signCount).toBe(9);
});
it("rejects inconsistent backup flags and undeclared trailing data", () => {
expect(() =>
parseAuthenticatorData(
Uint8Array.from([...new Uint8Array(32), 0x10, 0, 0, 0, 0]),
),
).toThrow(/backup/iu);
expect(() =>
parseAuthenticatorData(
Uint8Array.from([...new Uint8Array(32), 0x01, 0, 0, 0, 0, 0]),
),
).toThrow(/not described/iu);
});
});