'use server'; import { auth } from "@/auth"; import { prisma } from "@/lib/prisma"; import { revalidatePath } from "next/cache"; /** * Toggles a user's role between 'ADMIN' and 'USER'. * * Security Logic: * 1. Checks if the caller is the Bootstrap Admin (via .env). * 2. Checks if the caller has the 'ADMIN' role in the database. * 3. Prevents the Bootstrap Admin from being demoted to 'USER'. */ export async function toggleUserRoleAction(targetUserId: string) { const session = await auth(); const callerEmail = session?.user?.email; if (!callerEmail) { throw new Error("Unauthorized: No session found."); } // 1. Authorization: Who is trying to change the role? const isBootstrap = callerEmail === process.env.INITIAL_ADMIN_EMAIL; const callerDbRecord = await prisma.user.findUnique({ where: { email: callerEmail }, select: { role: true } }); const isAdmin = isBootstrap || callerDbRecord?.role === "ADMIN"; if (!isAdmin) { throw new Error("Forbidden: You do not have permission to manage roles."); } // 2. Fetch the target user to be modified const targetUser = await prisma.user.findUnique({ where: { id: targetUserId }, select: { id: true, email: true, role: true } }); if (!targetUser) { throw new Error("User not found."); } // 3. Protection: Prevent demoting the primary bootstrap admin // This ensures you don't accidentally lock yourself out of the settings page. if (targetUser.email === process.env.INITIAL_ADMIN_EMAIL && targetUser.role === "ADMIN") { throw new Error("Security Restriction: The primary Bootstrap Admin role cannot be removed."); } // 4. Determine new role const newRole = targetUser.role === "ADMIN" ? "USER" : "ADMIN"; // 5. Execute Update await prisma.user.update({ where: { id: targetUserId }, data: { role: newRole } }); // 6. Refresh the data on the Settings page revalidatePath("/settings"); return { success: true, message: `User ${targetUser.email} is now a ${newRole}` }; }