import { headers } from 'next/headers'; import { ensureAuthSchema } from '@/lib/auth'; import { asErrorMessage, jsonError } from '@/lib/server/http'; type RecordValue = Record; export type AuthenticatedUser = { id: string; email: string; name: string | null; image: string | null; role?: string | string[]; }; export type AuthenticatedSession = { user: AuthenticatedUser; session: RecordValue | null; raw: RecordValue; }; const UNAUTHORIZED_SESSION: AuthenticatedSession = { user: { id: '', email: '', name: null, image: null }, session: null, raw: {} }; function asRecord(value: unknown): RecordValue | null { if (!value || typeof value !== 'object' || Array.isArray(value)) { return null; } return value as RecordValue; } function asString(value: unknown) { return typeof value === 'string' && value.trim().length > 0 ? value : null; } function asNullableString(value: unknown) { return typeof value === 'string' ? value : null; } function normalizeRole(value: unknown) { if (typeof value === 'string') { return value; } if (Array.isArray(value)) { const roles = value.filter((entry): entry is string => typeof entry === 'string'); return roles.length > 0 ? roles : undefined; } return undefined; } function normalizeSession(rawSession: unknown): AuthenticatedSession | null { const root = asRecord(rawSession); if (!root) { return null; } const rootSession = asRecord(root.session); const userRecord = asRecord(root.user) ?? asRecord(rootSession?.user); if (!userRecord) { return null; } const id = asString(userRecord.id); const email = asString(userRecord.email); if (!id || !email) { return null; } return { user: { id, email, name: asNullableString(userRecord.name), image: asNullableString(userRecord.image), role: normalizeRole(userRecord.role) }, session: rootSession, raw: root }; } export async function getAuthenticatedSession() { const auth = await ensureAuthSchema(); const session = await auth.api.getSession({ headers: await headers() }); return normalizeSession(session); } export async function requireAuthenticatedSession() { try { const session = await getAuthenticatedSession(); if (!session) { return { session: UNAUTHORIZED_SESSION, response: jsonError('Unauthorized', 401) }; } return { session, response: null }; } catch (error) { return { session: UNAUTHORIZED_SESSION, response: jsonError(asErrorMessage(error, 'Authentication subsystem is unavailable.'), 500) }; } }