"use server"; import { revalidatePath } from "next/cache"; import { anmeldenameSchema, kontoNameSchema, kontoRolleSchema } from "@/lib/lokale-konten"; import { z } from "@/lib/validierung"; import { akteurVon, fehlerZustand, textfeld, type FormularZustand } from "@/server/actions/formular"; import { rechtErforderlich } from "@/server/auth/sitzungspflicht"; import { kontoAktivSetzen, kontoZuruecksetzen, lokalesKontoAnlegen, rolleAendern, } from "@/server/services/benutzer"; /** Benutzerverwaltung (#035). Duenn: Recht mit Re-Auth, Eingabe, Service. */ const PFAD = "/einstellungen/benutzer"; const id = z.string().min(1).max(64); /** Das Einmal-Passwort geht genau einmal an den Browser des Admins – nie ins Protokoll. */ export type KontoZustand = FormularZustand & { readonly einmalPasswort?: string; readonly anmeldename?: string; }; export async function kontoAnlegenAktion(_vorher: KontoZustand, formular: FormData): Promise { try { const { benutzer } = await rechtErforderlich("benutzerVerwalten"); const eingabe = z .object({ anmeldename: anmeldenameSchema, name: kontoNameSchema, rolle: kontoRolleSchema }) .safeParse({ anmeldename: textfeld(formular, "anmeldename") ?? "", name: textfeld(formular, "name") ?? "", rolle: textfeld(formular, "rolle") ?? "LESER", }); if (!eingabe.success) { const feldfehler: Record = {}; for (const fehler of eingabe.error.issues) feldfehler[String(fehler.path[0])] ??= fehler.message; return { feldfehler }; } const { einmalPasswort } = await lokalesKontoAnlegen(eingabe.data, akteurVon(benutzer)); revalidatePath(PFAD); return { einmalPasswort, anmeldename: eingabe.data.anmeldename }; } catch (fehler) { return fehlerZustand(fehler); } } export async function rolleAendernAktion(kontoId: string, rolle: string): Promise<{ fehler?: string }> { try { const { benutzer } = await rechtErforderlich("benutzerVerwalten"); await rolleAendern(id.parse(kontoId), kontoRolleSchema.parse(rolle), akteurVon(benutzer)); revalidatePath(PFAD); return {}; } catch (fehler) { return fehlerZustand(fehler); } } export async function aktivSetzenAktion(kontoId: string, aktiv: boolean): Promise<{ fehler?: string }> { try { const { benutzer } = await rechtErforderlich("benutzerVerwalten"); await kontoAktivSetzen(id.parse(kontoId), z.boolean().parse(aktiv), akteurVon(benutzer)); revalidatePath(PFAD); return {}; } catch (fehler) { return fehlerZustand(fehler); } } export async function zuruecksetzenAktion( kontoId: string, ): Promise<{ fehler?: string; einmalPasswort?: string }> { try { const { benutzer } = await rechtErforderlich("benutzerVerwalten"); const { einmalPasswort } = await kontoZuruecksetzen(id.parse(kontoId), akteurVon(benutzer)); revalidatePath(PFAD); return { einmalPasswort }; } catch (fehler) { return fehlerZustand(fehler); } }