import "server-only"; import { getServerSession } from "next-auth"; import type { Session } from "next-auth"; import { db } from "@/db"; import { authOptions } from "@/lib/auth/auth-options"; import { getGuildMemberRoles } from "@/lib/discord/discord"; export type SessionWithDiscord = Session & { user?: Session["user"] & { id?: string; discordId?: string; }; }; export type FormAccessConfig = { id: string; allowedRoles?: string[] | null; deniedRoles?: string[] | null; }; export function getAdminDiscordIds() { return (process.env.ADMIN_DISCORD_IDS ?? "") .split(",") .map((id) => id.trim()) .filter(Boolean); } export function getSessionDiscordId(session: Session | null) { return (session as SessionWithDiscord | null)?.user?.discordId ?? null; } export async function getCurrentDiscordId() { const session = await getServerSession(authOptions); return getSessionDiscordId(session); } export async function requireDiscordId() { const discordId = await getCurrentDiscordId(); if (!discordId) { throw new Error("Not authenticated"); } return discordId; } export async function requireAdmin() { const discordId = await requireDiscordId(); if (!getAdminDiscordIds().includes(discordId)) { throw new Error("Unauthorized"); } return discordId; } export async function canAccessForm(form: FormAccessConfig, discordId: string | null) { const allowedRoles = form.allowedRoles ?? []; const deniedRoles = form.deniedRoles ?? []; if (allowedRoles.length === 0 && deniedRoles.length === 0) { return true; } if (!discordId) { return false; } const userRoles = await getGuildMemberRoles(discordId); const isAllowed = allowedRoles.length === 0 || userRoles.some((role) => allowedRoles.includes(role)); const isDenied = deniedRoles.some((role) => userRoles.includes(role)); return isAllowed && !isDenied; } export async function requireFormAccess(formId: string, discordId: string) { const form = await db.query.forms.findFirst({ where: (forms, { eq }) => eq(forms.id, formId), }); if (!form) { throw new Error("Form not found"); } if (!(await canAccessForm(form, discordId))) { throw new Error("Unauthorized"); } return form; }