import { QueryCtx, MutationCtx } from "../_generated/server"; import type { Id } from "../_generated/dataModel"; type AuthCtx = QueryCtx | MutationCtx; export async function getCurrentUser(ctx: QueryCtx) { const identity = await ctx.auth.getUserIdentity(); if (!identity) return null; return await ctx.db .query("users") .withIndex("by_external_id", (q) => q.eq("externalId", identity.subject)) .unique(); } export async function getCurrentUserOrThrow(ctx: AuthCtx) { const user = await getCurrentUser(ctx as QueryCtx); if (!user) throw new Error("Unauthenticated"); return user; } export async function requireAdmin(ctx: QueryCtx) { const user = await getCurrentUserOrThrow(ctx); if (user.role !== "admin" && user.role !== "super_admin") { throw new Error("Unauthorized: admin access required"); } return user; } export async function requireSuperAdmin(ctx: QueryCtx) { const user = await getCurrentUserOrThrow(ctx); if (user.role !== "super_admin") { throw new Error("Unauthorized: super_admin access required"); } return user; } export async function requireOwnership( ctx: AuthCtx, resourceUserId: Id<"users">, ) { const user = await getCurrentUserOrThrow(ctx); if (resourceUserId !== user._id) { throw new Error("Unauthorized: resource does not belong to you"); } return user; }