Files
Epicnabbo-Catalogus-Updated…/src/lib/auth/totp.test.ts
T
Simo ec2d46e583 Add byte-compatible Auth & SSO core primitives
Pure, unit-tested primitives the AtomCMS->Next.js login must reproduce exactly
(verified now with round-trip + known vectors; full end-to-end check deferred
until a real DB + APP_KEY + live emulator are available):

- password.ts: argon2id (m=65536,t=4,p=1 via hash-wasm) + bcrypt ($2y$ accepted)
  verify, and the md5->argon2id on-login upgrade gated by convert_passwords
  (mirrors RedirectIfTwoFactorAuthenticatable).
- sso-ticket.ts: '{hotel_name without spaces}-{uuidv4}' written to auth_ticket +
  ip_current (mirrors User::ssoTicket()).
- laravel-encrypter.ts: AES-256-CBC + HMAC-SHA256 payload compatible with
  Laravel encrypt()/encryptString (for existing 2FA secrets) incl. PHP string
  (de)serialization.
- totp.ts: otplib Google2FA-compatible TOTP verify (SHA1/6/30).

Libs: hash-wasm + bcryptjs + otplib (pure JS/WASM, no native build). 28 tests.
2026-06-27 16:00:25 +02:00

28 lines
878 B
TypeScript

import { describe, expect, it } from "vitest";
import { generateTotp, totpKeyUri, verifyTotp } from "./totp";
const SECRET = "JBSWY3DPEHPK3PXP"; // standard base32 test secret
describe("totp", () => {
it("verifies the current generated code", () => {
const code = generateTotp(SECRET);
expect(code).toMatch(/^\d{6}$/);
expect(verifyTotp(code, SECRET)).toBe(true);
});
it("rejects a wrong code", () => {
expect(verifyTotp("000000", SECRET)).toBe(false);
});
it("rejects malformed input without throwing", () => {
expect(verifyTotp("not-a-code", SECRET)).toBe(false);
});
it("builds an otpauth provisioning URI", () => {
const uri = totpKeyUri(SECRET, "alice", "AtomHotel");
expect(uri.startsWith("otpauth://totp/")).toBe(true);
expect(uri).toContain("secret=" + SECRET);
expect(uri).toContain("issuer=AtomHotel");
});
});