import { NextResponse } from "next/server"; import bcrypt from "bcryptjs"; import { requireCurrentUser, UnauthorizedError } from "@/lib/auth"; import { prisma } from "@/lib/prisma"; import { normalizeDisplayName, normalizeEmail, normalizePassword, normalizeUserRole } from "@/lib/validation"; export async function GET() { try { const currentUser = await requireCurrentUser(); if (currentUser.role !== "ADMIN") { return NextResponse.json({ error: "Keine Berechtigung." }, { status: 403 }); } const users = await prisma.user.findMany({ orderBy: { createdAt: "asc" }, select: { id: true, email: true, displayName: true, role: true, createdAt: true } }); return NextResponse.json({ users }); } catch (error) { if (error instanceof UnauthorizedError) { return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); } return NextResponse.json({ error: "Nutzer konnten nicht geladen werden." }, { status: 500 }); } } export async function POST(request: Request) { try { const currentUser = await requireCurrentUser(); if (currentUser.role !== "ADMIN") { return NextResponse.json({ error: "Keine Berechtigung." }, { status: 403 }); } const body = (await request.json().catch(() => null)) as { email?: unknown; password?: unknown; displayName?: unknown; role?: unknown; } | null; const email = normalizeEmail(body?.email); const password = normalizePassword(body?.password); const displayName = normalizeDisplayName(body?.displayName); const role = normalizeUserRole(body?.role) ?? "USER"; if (!email || !password) { return NextResponse.json( { error: "E-Mail oder Passwort ungültig. Das Passwort muss 10 bis 128 Zeichen lang sein." }, { status: 400 } ); } const existingUser = await prisma.user.findUnique({ where: { email }, select: { id: true } }); if (existingUser) { return NextResponse.json( { error: "Ein Nutzer mit dieser E-Mail existiert bereits." }, { status: 409 } ); } const passwordHash = await bcrypt.hash(password, 12); const user = await prisma.user.create({ data: { email, passwordHash, displayName, role, settings: { create: { darkMode: false, calendarMaxEvents: 8, calendarLookaheadDays: 60, dashboardTitle: "Personal Dashboard", logoUrl: "/logo.svg", primaryColor: "#2563eb", secondaryColor: "#dbeafe" } }, widgets: { create: [ { type: "favorites", title: "Links/Favoriten", position: 0, x: 0, y: 0, w: 3, h: 6 }, { type: "note", title: "Notiz", position: 1, x: 3, y: 0, w: 3, h: 4 }, { type: "search", title: "Suche", position: 3, x: 9, y: 0, w: 3, h: 2 }, { type: "calendar", title: "Kalender", position: 4, x: 9, y: 2, w: 3, h: 7 } ] } }, select: { id: true, email: true, displayName: true, role: true, createdAt: true } }); const createdWidgets = await prisma.widget.findMany({ where: { userId: user.id, type: { in: ["note"] } } }); await Promise.all( createdWidgets.map((widget) => prisma.noteBoardItem.create({ data: { id: widget.id, userId: user.id, type: widget.type, title: widget.title, content: "" } }) ) ); return NextResponse.json( { user }, { status: 201 } ); } catch (error) { if (error instanceof UnauthorizedError) { return NextResponse.json({ error: "Nicht angemeldet." }, { status: 401 }); } return NextResponse.json({ error: "Nutzer konnte nicht erstellt werden." }, { status: 500 }); } }