feat(ST-111ci8t4): admin user-actions (delete, updateRoles, setMustResetPassword)

- lib/session.ts: isAdmin: boolean toegevoegd aan SessionData
- lib/auth-guard.ts: requireAdmin() toegevoegd (redirect /dashboard bij !isAdmin)
- actions/admin/users.ts: deleteUserAction (zelfbescherming), updateUserRolesAction
  (Zod z.nativeEnum, eigen ADMIN-rol-beveiliging, transactie), setMustResetPasswordAction
  — alle drie 'use server', revalidatePath('/admin/users')
This commit is contained in:
Scrum4Me Agent 2026-05-05 14:38:42 +02:00
parent 71281038ff
commit 5fd56e3f67
3 changed files with 52 additions and 0 deletions

43
actions/admin/users.ts Normal file
View file

@ -0,0 +1,43 @@
'use server'
import { revalidatePath } from 'next/cache'
import { z } from 'zod'
import { Role } from '@prisma/client'
import { prisma } from '@/lib/prisma'
import { requireAdmin } from '@/lib/auth-guard'
export async function deleteUserAction(userId: string) {
const session = await requireAdmin()
if (userId === session.userId) {
throw new Error('Zelfverwijdering niet toegestaan')
}
await prisma.user.delete({ where: { id: userId } })
revalidatePath('/admin/users')
}
const rolesSchema = z.array(z.nativeEnum(Role))
export async function updateUserRolesAction(userId: string, roles: Role[]) {
const session = await requireAdmin()
const parsed = rolesSchema.safeParse(roles)
if (!parsed.success) {
throw new Error('Ongeldige rol-waarden')
}
if (userId === session.userId && !parsed.data.includes(Role.ADMIN)) {
throw new Error('Kan eigen ADMIN-rol niet verwijderen')
}
await prisma.$transaction([
prisma.userRole.deleteMany({ where: { user_id: userId } }),
...parsed.data.map((role) => prisma.userRole.create({ data: { user_id: userId, role } })),
])
revalidatePath('/admin/users')
}
export async function setMustResetPasswordAction(userId: string, value: boolean) {
await requireAdmin()
await prisma.user.update({ where: { id: userId }, data: { must_reset_password: value } })
revalidatePath('/admin/users')
}