import { auth } from '@/auth' import { NextResponse } from 'next/server' import { prisma } from '@/lib/prisma' export type AuthResult = | { ok: true; userId: string } | { ok: false; response: NextResponse } /** * Retrieves the authenticated user ID or throws an Unauthorized error. * Use in Server Actions where throw semantics are preferred. * * @throws {Error} 'Unauthorized' if no valid session exists. * @returns The authenticated user's ID string. */ export async function requireAuth(): Promise { const session = await auth() if (!session?.user?.id) { throw new Error('Unauthorized') } return session.user.id } /** * Auth guard for API routes — returns a 401 NextResponse instead of throwing. * * Usage: * ```ts * const auth = await requireAuthOrResponse() * if (!auth.ok) return auth.response * const userId = auth.userId * ``` * * @param format 'plain' (default) returns `{ error: 'Unauthorized' }`. * 'success' returns `{ success: false, error: 'Unauthorized' }`. */ export async function requireAuthOrResponse( format: 'plain' | 'success' = 'plain', ): Promise { const session = await auth() if (!session?.user?.id) { const body = format === 'success' ? { success: false, error: 'Unauthorized' } : { error: 'Unauthorized' } return { ok: false, response: NextResponse.json(body, { status: 401 }) } } return { ok: true, userId: session.user.id } } /** * Admin guard for API routes — checks user role in DB, returns 401/403 on failure. * * Usage: * ```ts * const auth = await requireAdminOrResponse() * if (!auth.ok) return auth.response * const userId = auth.userId * ``` */ export async function requireAdminOrResponse(): Promise { const session = await auth() if (!session?.user?.id) { return { ok: false, response: NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } } const user = await prisma.user.findUnique({ where: { id: session.user.id }, select: { role: true }, }) if (user?.role !== 'ADMIN') { return { ok: false, response: NextResponse.json({ error: 'Forbidden' }, { status: 403 }) } } return { ok: true, userId: session.user.id } }