import { createHash, timingSafeEqual } from "node:crypto"; /** * Checks `Authorization: Bearer $ADMIN_TOKEN`. Returns "disabled" when no token is * configured so the admin routes can answer 404 and stay invisible. */ export function checkAdmin(request: Request): "ok" | "denied" | "disabled" { const expected = process.env.ADMIN_TOKEN; if (!expected) return "disabled"; const header = request.headers.get("authorization") ?? ""; const provided = header.startsWith("Bearer ") ? header.slice(7) : ""; // Hash both sides so the comparison has equal length and does not leak it. const a = createHash("sha256").update(provided).digest(); const b = createHash("sha256").update(expected).digest(); return timingSafeEqual(a, b) ? "ok" : "denied"; } export function adminDenied(result: "denied" | "disabled") { return result === "disabled" ? Response.json({ error: "Not found." }, { status: 404 }) : Response.json({ error: "Unauthorized." }, { status: 401 }); }