import { createHmac, timingSafeEqual } from 'crypto'; import { cookies } from 'next/headers'; export const ADMIN_SESSION_COOKIE = 'shahi_admin_session'; const SESSION_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000; function getSessionSecret(): string { return process.env.ADMIN_SESSION_SECRET ?? 'shahi-kitchen-admin-dev-secret'; } export function createAdminSessionToken(): string { const issuedAt = Date.now().toString(); const payload = `admin:${issuedAt}`; const signature = createHmac('sha256', getSessionSecret()).update(payload).digest('hex'); return `${payload}.${signature}`; } export function verifyAdminSessionToken(token: string | undefined | null): boolean { if (!token) return false; const [payload, signature] = token.split('.'); if (!payload || !signature) return false; const expected = createHmac('sha256', getSessionSecret()).update(payload).digest('hex'); const sigBuffer = Buffer.from(signature); const expectedBuffer = Buffer.from(expected); if (sigBuffer.length !== expectedBuffer.length) return false; if (!timingSafeEqual(sigBuffer, expectedBuffer)) return false; const [, issuedAtRaw] = payload.split(':'); const issuedAt = Number(issuedAtRaw); if (!Number.isFinite(issuedAt)) return false; return Date.now() - issuedAt <= SESSION_MAX_AGE_MS; } export async function isAdminAuthenticated(): Promise { const cookieStore = await cookies(); const token = cookieStore.get(ADMIN_SESSION_COOKIE)?.value; return verifyAdminSessionToken(token); } export function getAdminSessionCookieOptions() { return { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'lax' as const, path: '/', maxAge: SESSION_MAX_AGE_MS / 1000, }; }