import { createHmac, timingSafeEqual } from 'node:crypto' const TOKEN_COOKIE = 'admin_token' const TOKEN_MAX_AGE = 60 * 60 * 24 // 24h export function signToken(payload: string, secret: string): string { const hmac = createHmac('sha256', secret) hmac.update(payload) return payload + '.' + hmac.digest('hex') } export function verifyToken(token: string, secret: string): string | null { const dotIndex = token.lastIndexOf('.') if (dotIndex === -1) return null const payload = token.slice(0, dotIndex) const expected = signToken(payload, secret) const a = Buffer.from(token) const b = Buffer.from(expected) if (a.length !== b.length) return null if (!timingSafeEqual(a, b)) return null // Check expiry try { const data = JSON.parse(payload) if (data.exp && data.exp < Math.floor(Date.now() / 1000)) return null return payload } catch { return null } } export function setAdminCookie(event: any, secret: string): void { const exp = Math.floor(Date.now() / 1000) + TOKEN_MAX_AGE const payload = JSON.stringify({ role: 'admin', exp }) const token = signToken(payload, secret) setCookie(event, TOKEN_COOKIE, token, { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'lax', maxAge: TOKEN_MAX_AGE, path: '/', }) } export function clearAdminCookie(event: any): void { deleteCookie(event, TOKEN_COOKIE, { path: '/' }) } export function getAdminToken(event: any): string | null { return getCookie(event, TOKEN_COOKIE) ?? null }