import { cookies } from "next/headers"; import { createHmac, timingSafeEqual, randomBytes, scryptSync } from "crypto"; import { getDb } from "./db"; const SESSION_SECRET = process.env.SESSION_SECRET!; const COOKIE_NAME = "session"; const MAX_AGE = 60 * 60 * 24 * 7; // 7 dagen type SessionPayload = { userId: number; email: string; name: string }; function sign(payload: SessionPayload): string { const data = JSON.stringify(payload); const encoded = Buffer.from(data).toString("base64url"); const sig = createHmac("sha256", SESSION_SECRET).update(encoded).digest("base64url"); return `${encoded}.${sig}`; } function verify(token: string): SessionPayload | null { const [encoded, sig] = token.split("."); if (!encoded || !sig) return null; const expected = createHmac("sha256", SESSION_SECRET).update(encoded).digest("base64url"); try { if (!timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) return null; } catch { return null; } return JSON.parse(Buffer.from(encoded, "base64url").toString()); } export async function getSession(): Promise { const jar = await cookies(); const token = jar.get(COOKIE_NAME)?.value; if (!token) return null; return verify(token); } export async function createSession(payload: SessionPayload) { const jar = await cookies(); jar.set(COOKIE_NAME, sign(payload), { httpOnly: true, secure: process.env.NODE_ENV === "production", sameSite: "lax", maxAge: MAX_AGE, path: "/", }); } export async function destroySession() { const jar = await cookies(); jar.delete(COOKIE_NAME); } export function hashPassword(password: string): string { const salt = randomBytes(16).toString("hex"); const hash = scryptSync(password, salt, 64).toString("hex"); return `${salt}:${hash}`; } export function verifyPassword(password: string, stored: string): boolean { const [salt, hash] = stored.split(":"); const attempt = scryptSync(password, salt, 64).toString("hex"); return timingSafeEqual(Buffer.from(hash, "hex"), Buffer.from(attempt, "hex")); } export function getUserByEmail(email: string) { const db = getDb(); return db.prepare("SELECT * FROM users WHERE email = ?").get(email) as | { id: number; email: string; name: string; password_hash: string; role: string } | undefined; }