const SESSION_COOKIE = "wp_admin_session"; const SESSION_TTL_SECONDS = 60 * 60 * 24 * 7; function getSecret() { const secret = process.env.ADMIN_SESSION_SECRET; if (!secret) { throw new Error("ADMIN_SESSION_SECRET is not set"); } return secret; } function toHex(buffer: ArrayBuffer) { return Array.from(new Uint8Array(buffer)) .map((b) => b.toString(16).padStart(2, "0")) .join(""); } async function sign(value: string) { const key = await crypto.subtle.importKey( "raw", new TextEncoder().encode(getSecret()), { name: "HMAC", hash: "SHA-256" }, false, ["sign"] ); const signature = await crypto.subtle.sign( "HMAC", key, new TextEncoder().encode(value) ); return toHex(signature); } export async function createSessionToken(email: string) { const expiresAt = Math.floor(Date.now() / 1000) + SESSION_TTL_SECONDS; const payload = `${email}.${expiresAt}`; const signature = await sign(payload); return `${payload}.${signature}`; } export async function verifySessionToken(token?: string | null) { if (!token) return false; const parts = token.split("."); if (parts.length < 3) return false; const signature = parts.pop()!; const expiresAt = Number(parts.pop()); const email = parts.join("."); if (!email || !expiresAt || Number.isNaN(expiresAt)) return false; if (expiresAt < Math.floor(Date.now() / 1000)) return false; const payload = `${email}.${expiresAt}`; const expectedSignature = await sign(payload); return signature === expectedSignature; } export function getSessionCookieName() { return SESSION_COOKIE; } export function getAdminCredentials() { return { email: process.env.ADMIN_EMAIL || "", password: process.env.ADMIN_PASSWORD || "", }; }