Files
famapp/tests/unit/api-auth.test.ts

41 lines
1.4 KiB
TypeScript

import assert from "node:assert/strict";
import { createHash } from "node:crypto";
import { describe, it } from "node:test";
import { hashApiToken } from "../../src/modules/_core/api-token";
function parseBearerToken(header: string | null): string | null {
if (!header?.startsWith("Bearer ")) return null;
const token = header.slice("Bearer ".length).trim();
return token.length > 0 ? token : null;
}
describe("hashApiToken", () => {
it("returns SHA-256 hex digest matching Node crypto", () => {
const raw = "test-token-value";
const expected = createHash("sha256").update(raw).digest("hex");
assert.equal(hashApiToken(raw), expected);
});
it("produces distinct hashes for different inputs", () => {
assert.notEqual(hashApiToken("token-a"), hashApiToken("token-b"));
});
it("is deterministic for the same input", () => {
const raw = "famapp-api-token-abc123";
assert.equal(hashApiToken(raw), hashApiToken(raw));
});
});
describe("parseBearerToken", () => {
it("extracts token from a valid Authorization header", () => {
assert.equal(parseBearerToken("Bearer abc.def-ghi"), "abc.def-ghi");
});
it("returns null for missing or malformed headers", () => {
assert.equal(parseBearerToken(null), null);
assert.equal(parseBearerToken("Basic dXNlcjpwYXNz"), null);
assert.equal(parseBearerToken("Bearer "), null);
assert.equal(parseBearerToken("Bearer"), null);
});
});