import { eq } from "drizzle-orm"; import { auth } from "@/lib/auth"; import { db } from "@/lib/db"; import { resolveBearerToken } from "@/modules/_core/api-token"; import { householdMembers } from "@/modules/_core/schema"; export type ApiAuthContext = { householdId: string; userId: string | null; role: "owner" | "member" | null; }; function parseBearerToken(request: Request): string | null { const header = request.headers.get("Authorization"); if (!header?.startsWith("Bearer ")) return null; const token = header.slice("Bearer ".length).trim(); return token.length > 0 ? token : null; } async function resolveSessionAuth(): Promise { let session; try { session = await auth(); } catch { return null; } if (!session?.user?.id) return null; const [row] = await db .select({ householdId: householdMembers.householdId, role: householdMembers.role, }) .from(householdMembers) .where(eq(householdMembers.userId, session.user.id)) .limit(1); if (!row) return null; return { householdId: row.householdId, userId: session.user.id, role: row.role, }; } export async function resolveApiAuth(request: Request): Promise { const sessionAuth = await resolveSessionAuth(); if (sessionAuth) return sessionAuth; const rawToken = parseBearerToken(request); if (!rawToken) return null; const bearer = await resolveBearerToken(rawToken); if (!bearer) return null; return { householdId: bearer.householdId, userId: null, role: null, }; } export async function requireApiAuth(request: Request): Promise { const ctx = await resolveApiAuth(request); if (!ctx) { throw new Response(JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { "Content-Type": "application/json" }, }); } return ctx; }