import { describe, expect, it } from "vitest"; import { utf8ToBytes } from "../../src/crypto/encoding"; import { credentialHealthReport, findTotpDrift, generateTotpTimeline, } from "../../src/otp/diagnostics"; import type { OtpProfile } from "../../src/otp/profile"; const profile: OtpProfile = { kind: "totp", secret: utf8ToBytes("12345678901234567890"), issuer: "RFC", account: "vector", algorithm: "SHA-1", digits: 8, period: 30, epoch: 0, counter: 0n, extensions: new Map(), }; describe("OTP diagnostics", () => { it("builds an ordered RFC timeline and finds clock drift", async () => { const timeline = await generateTotpTimeline(profile, 59, 1, 2); expect(timeline.map((item) => item.delta)).toEqual([-1, 0, 1, 2]); expect(timeline[1]).toMatchObject({ code: "94287082", counter: 1n }); const drift = await findTotpDrift(timeline[2]!.code, profile, 59, 5); expect(drift).toMatchObject({ delta: 1, driftSeconds: 30 }); }); it("honors a custom T0 and bounds diagnostic work", async () => { const shifted = { ...profile, epoch: 30 }; expect((await generateTotpTimeline(shifted, 59, 0, 0))[0]!.counter).toBe( 0n, ); await expect( findTotpDrift("12345678", profile, 59, 10_001), ).rejects.toThrow(/10000/u); }); it("detects duplicate secrets without exposing their fingerprint", async () => { const report = await credentialHealthReport([ profile, { ...profile, issuer: "Other", account: "second" }, ]); expect(report.findings).toEqual( expect.arrayContaining([ expect.objectContaining({ code: "reused-secret", severity: "danger" }), ]), ); expect(JSON.stringify(report)).not.toContain("31323334"); }); });