admin / Synapse-Sonar
publicAttack Surface Simulation
Synapse-Sonar / synapse-sonar / lib / auth.ts
1131 B · main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | import { getServerSession } from "next-auth"; import { authOptions } from "@/lib/authOptions"; import { Role } from "@prisma/client"; /** * The authenticated principal, always carrying a tenantId. EVERY data query in * the app must be scoped by `ctx.tenantId` — there is no cross-tenant read path. */ export interface TenantContext { userId: string; tenantId: string; role: Role; username: string; email: string; } export class HttpError extends Error { constructor(public status: number, message: string) { super(message); } } /** * Resolve the tenant-scoped session for a route handler. Throws HttpError(401) * when there is no valid session. Use this at the top of every protected route. */ export async function requireTenantContext(): Promise<TenantContext> { const session = await getServerSession(authOptions); if (!session?.user?.tenantId) { throw new HttpError(401, "Unauthenticated"); } return { userId: session.user.id, tenantId: session.user.tenantId, role: session.user.role as Role, username: session.user.username, email: session.user.email ?? "", }; } |