Files
seminarhof-e2e-mqo0qs8e/packages/functions/src/lib/session.ts
2026-06-21 18:46:29 +02:00

44 lines
1.3 KiB
TypeScript

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<DB>,
http: { response?: { cookie: (name: string, value: string, opts: Record<string, unknown>) => void } } | undefined,
userId: string,
): Promise<string> {
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
}