68 lines
2 KiB
TypeScript
68 lines
2 KiB
TypeScript
|
|
'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}`
|
||
|
|
};
|
||
|
|
}
|