59 lines
2.3 KiB
TypeScript
59 lines
2.3 KiB
TypeScript
"use server";
|
|
|
|
import { revalidatePath } from "next/cache";
|
|
import { auth } from "@/auth";
|
|
import { UserRole } from "@/generated/prisma/enums";
|
|
import { requireRole } from "@/lib/authorization";
|
|
import { prisma } from "@/lib/prisma";
|
|
import { recordAudit } from "@/lib/admin/audit";
|
|
|
|
const ROLE_VALUES = new Set<string>([
|
|
UserRole.OWNER,
|
|
UserRole.CE_MANAGER,
|
|
UserRole.CE_MEMBER,
|
|
UserRole.TOURIST,
|
|
UserRole.ADMIN,
|
|
]);
|
|
|
|
async function audit(event: string, target: string, actor: string | null, details: Record<string, unknown>) {
|
|
await recordAudit({ scope: "admin.users", event, target, actorEmail: actor, details });
|
|
}
|
|
|
|
export async function updateUserRoleAction(id: string, role: string) {
|
|
await requireRole([UserRole.ADMIN]);
|
|
if (!ROLE_VALUES.has(role)) {
|
|
return { ok: false as const, error: "Rôle invalide" };
|
|
}
|
|
const session = await auth();
|
|
if (role !== UserRole.ADMIN) {
|
|
const adminCount = await prisma.user.count({ where: { role: UserRole.ADMIN, isActive: true } });
|
|
const current = await prisma.user.findUnique({ where: { id }, select: { role: true } });
|
|
if (current?.role === UserRole.ADMIN && adminCount <= 1) {
|
|
return { ok: false as const, error: "Impossible de retirer le dernier admin actif." };
|
|
}
|
|
}
|
|
await prisma.user.update({ where: { id }, data: { role: role as UserRole } });
|
|
await audit("user.role.update", id, session?.user?.email ?? null, { role });
|
|
revalidatePath("/admin/users");
|
|
revalidatePath(`/admin/users/${id}`);
|
|
return { ok: true as const };
|
|
}
|
|
|
|
export async function toggleUserActiveAction(id: string, active: boolean) {
|
|
await requireRole([UserRole.ADMIN]);
|
|
const session = await auth();
|
|
if (!active) {
|
|
const target = await prisma.user.findUnique({ where: { id }, select: { role: true, isActive: true } });
|
|
if (target?.role === UserRole.ADMIN) {
|
|
const adminCount = await prisma.user.count({ where: { role: UserRole.ADMIN, isActive: true } });
|
|
if (adminCount <= 1) {
|
|
return { ok: false as const, error: "Impossible de désactiver le dernier admin." };
|
|
}
|
|
}
|
|
}
|
|
await prisma.user.update({ where: { id }, data: { isActive: active } });
|
|
await audit("user.active.update", id, session?.user?.email ?? null, { active });
|
|
revalidatePath("/admin/users");
|
|
revalidatePath(`/admin/users/${id}`);
|
|
return { ok: true as const };
|
|
}
|