// Run with: npm run test:token import test from "node:test"; import assert from "node:assert/strict"; import { signStaffToken, verifyStaffToken, safeEqual, STAFF_TOKEN_MAX_TTL_SECONDS, } from "./staff-token.mjs"; const SECRET = "test-secret"; const NOW = 1_800_000_000 - 3600; // one hour before the vector's exp // Produced by the PHP implementation in civi-extension Tab.php: // rtrim(strtr(base64_encode(hash_hmac('sha256', // 'webform-mw.staff-report.v1:1234:1800000000', 'test-secret', TRUE)), // '+/', '-_'), '=') const PHP_VECTOR = "HlcxJCgUHfa6fhuvldUxZmCk_y62TcuQ4dH2JjFSqCo"; test("signStaffToken matches the PHP implementation", () => { assert.equal(signStaffToken(SECRET, "1234", "1800000000"), PHP_VECTOR); }); test("verifyStaffToken accepts a valid, unexpired token", () => { assert.equal(verifyStaffToken(SECRET, "1234", "1800000000", PHP_VECTOR, NOW), true); }); test("verifyStaffToken rejects a token for a different org", () => { assert.equal(verifyStaffToken(SECRET, "1235", "1800000000", PHP_VECTOR, NOW), false); }); test("verifyStaffToken rejects a tampered exp", () => { assert.equal(verifyStaffToken(SECRET, "1234", "1800000001", PHP_VECTOR, NOW), false); }); test("verifyStaffToken rejects a wrong secret", () => { assert.equal(verifyStaffToken("other-secret", "1234", "1800000000", PHP_VECTOR, NOW), false); }); test("verifyStaffToken rejects an expired token", () => { assert.equal(verifyStaffToken(SECRET, "1234", "1800000000", PHP_VECTOR, 1_800_000_000), false); }); test("verifyStaffToken rejects exp too far in the future", () => { const now = 1_800_000_000 - STAFF_TOKEN_MAX_TTL_SECONDS - 1; assert.equal(verifyStaffToken(SECRET, "1234", "1800000000", PHP_VECTOR, now), false); }); test("verifyStaffToken rejects missing or malformed inputs", () => { assert.equal(verifyStaffToken("", "1234", "1800000000", PHP_VECTOR, NOW), false); assert.equal(verifyStaffToken(SECRET, null, "1800000000", PHP_VECTOR, NOW), false); assert.equal(verifyStaffToken(SECRET, "1234", undefined, PHP_VECTOR, NOW), false); assert.equal(verifyStaffToken(SECRET, "1234", "1800000000", "", NOW), false); assert.equal(verifyStaffToken(SECRET, "01234", "1800000000", PHP_VECTOR, NOW), false); assert.equal(verifyStaffToken(SECRET, "1234", "18e8", PHP_VECTOR, NOW), false); assert.equal(verifyStaffToken(SECRET, "-1", "1800000000", PHP_VECTOR, NOW), false); }); test("safeEqual compares by value and tolerates length mismatch", () => { assert.equal(safeEqual("abc", "abc"), true); assert.equal(safeEqual("abc", "abd"), false); assert.equal(safeEqual("abc", "abcd"), false); assert.equal(safeEqual("", ""), true); });