import { createHmac, timingSafeEqual } from "node:crypto"; /** * Passcode gate. The console is public on the Internet (www.socialcrawl.co) and can launch browsers * on a cluster node, so every page and API call requires a signed cookie obtained with SRC_DASHBOARD_PASSCODE. */ export const COOKIE = "src_access"; const SECRET = process.env.SRC_DASHBOARD_SECRET ?? process.env.SRC_API_TOKEN ?? "dev-secret"; const PASSCODE = process.env.SRC_DASHBOARD_PASSCODE ?? ""; export function gateEnabled(): boolean { return PASSCODE.length > 0; } export function checkPasscode(input: string): boolean { if (!PASSCODE) return true; const a = Buffer.from(input); const b = Buffer.from(PASSCODE); return a.length === b.length && timingSafeEqual(a, b); } export function makeToken(): string { const exp = Date.now() + 30 * 24 * 3600 * 1000; const body = `${exp}`; return `${body}.${createHmac("sha256", SECRET).update(body).digest("hex")}`; } export function verifyToken(token: string | undefined): boolean { if (!PASSCODE) return true; if (!token) return false; const [body, sig] = token.split("."); if (!body || !sig) return false; const expect = createHmac("sha256", SECRET).update(body).digest("hex"); if (expect.length !== sig.length || !timingSafeEqual(Buffer.from(expect), Buffer.from(sig))) return false; return Number(body) > Date.now(); }