124_webcalibre2/src/app/settings/actions.ts

68 lines
2 KiB
TypeScript
Raw Normal View History

'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}`
};
}