import { createHmac, randomBytes } from "node:crypto"; export const ACCESS_KEY_PREFIX = "ydr_live_"; export function generateAccessKey() { const visibleId = randomBytes(6).toString("hex"); const secret = randomBytes(32).toString("base64url"); const token = `${ACCESS_KEY_PREFIX}${visibleId}_${secret}`; return { token, tokenPrefix: `${ACCESS_KEY_PREFIX}${visibleId}`, }; } export function hashAccessKey(token: string, pepper: string) { const normalizedToken = String(token || "").trim(); const normalizedPepper = String(pepper || "").trim(); if (!normalizedToken || !normalizedPepper) { throw new Error("Access Key token and pepper are required"); } return createHmac("sha256", normalizedPepper) .update(normalizedToken) .digest("hex"); } export function getAccessKeyPrefix(token: string) { const normalized = String(token || "").trim(); const match = /^(ydr_live_[a-f0-9]{12})_[A-Za-z0-9_-]{20,}$/.exec( normalized ); return match?.[1] || null; } export function parseBearerAccessKey(header: string | null | undefined) { const match = /^Bearer\s+(.+)$/i.exec(String(header || "").trim()); const token = match?.[1]?.trim() || ""; return getAccessKeyPrefix(token) ? token : null; }