chore: seminarhof customer project
This commit is contained in:
43
packages/functions/src/lib/session.ts
Normal file
43
packages/functions/src/lib/session.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user