import bcrypt from 'bcrypt'; import { prisma } from './db.js'; const SALT_ROUNDS = 12; const SESSION_DURATION_MS = 30 * 24 * 60 * 60 * 1000; // 30 days export async function hashPassword(password: string): Promise { return bcrypt.hash(password, SALT_ROUNDS); } export async function verifyPassword(password: string, hash: string): Promise { return bcrypt.compare(password, hash); } export async function createSession(userId: string): Promise<{ id: string; expiresAt: Date }> { const expiresAt = new Date(Date.now() + SESSION_DURATION_MS); const session = await prisma.session.create({ data: { userId, expiresAt } }); return { id: session.id, expiresAt }; } export async function validateSession(sessionId: string) { const session = await prisma.session.findUnique({ where: { id: sessionId }, include: { user: { select: { id: true, email: true, name: true, globalRole: true, tenantRole: true, tenantId: true } } } }); if (!session) return null; if (session.expiresAt < new Date()) { await prisma.session.delete({ where: { id: sessionId } }); return null; } return session; } export async function deleteSession(sessionId: string) { await prisma.session.delete({ where: { id: sessionId } }).catch(() => {}); } export function sessionCookieName(): string { return 'session'; } export function sessionCookieOptions(expiresAt: Date) { return { path: '/', httpOnly: true, sameSite: 'lax' as const, secure: !import.meta.env.DEV, expires: expiresAt }; }