import type { Kysely } from 'kysely' import type { DB } from '../types/db.types.js' import { SESSION_COOKIE } from '../middleware/session-cookie.js' export const SESSION_DAYS = 30 export const uid = () => globalThis.crypto?.randomUUID?.() ?? `id_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}` const isoOffsetDays = (days: number) => { const d = new Date() d.setUTCDate(d.getUTCDate() + days) return d.toISOString() } /** * Creates a server-side session row for `userId` and writes the session cookie. * Shared by password login and the passwordless booking-form magic link so both * issue identical sessions. `http` is optional (absent off the HTTP transport). */ export async function createUserSession( kysely: Kysely, http: { response?: { cookie: (name: string, value: string, opts: Record) => void } } | undefined, userId: string, ): Promise { const sessionId = uid() await kysely .insertInto('bookingSession') .values({ sessionId, userId, expiresAt: isoOffsetDays(SESSION_DAYS) }) .execute() if (http?.response) { http.response.cookie(SESSION_COOKIE, sessionId, { httpOnly: true, secure: false, sameSite: 'lax', path: '/', maxAge: 60 * 60 * 24 * SESSION_DAYS, }) } return sessionId }