import { NextRequest, NextResponse } from 'next/server' import { prisma } from '@/lib/db' import { getSession, hashPassword, isAdmin } from '@/lib/auth' import { z } from 'zod' const createUserSchema = z.object({ email: z.string().email(), name: z.string().min(1).max(100), password: z.string().min(6), role: z.enum(['SERVER_ADMIN', 'TENANT_ADMIN', 'OPERATOR', 'VIEWER']), tenantId: z.string().optional(), }) export async function GET() { try { const user = await getSession() if (!user || !isAdmin(user.role)) { return NextResponse.json({ error: 'Nicht autorisiert' }, { status: 403 }) } const where = user.role === 'SERVER_ADMIN' ? {} : { memberships: { some: { tenantId: user.tenantId } }, } const users = await (prisma as any).user.findMany({ where, orderBy: { createdAt: 'desc' }, select: { id: true, email: true, name: true, role: true, emailVerified: true, isActive: true, lastLoginAt: true, createdAt: true, updatedAt: true, memberships: { include: { tenant: { select: { id: true, name: true, slug: true } } }, }, _count: { select: { projects: true } }, }, }) return NextResponse.json({ users }) } catch (error) { console.error('Error fetching users:', error) return NextResponse.json({ error: 'Interner Fehler' }, { status: 500 }) } } export async function POST(req: NextRequest) { try { const session = await getSession() if (!session || !isAdmin(session.role)) { return NextResponse.json({ error: 'Nicht autorisiert' }, { status: 403 }) } const body = await req.json() const data = createUserSchema.parse(body) // Only SERVER_ADMIN can create SERVER_ADMIN users if (data.role === 'SERVER_ADMIN' && session.role !== 'SERVER_ADMIN') { return NextResponse.json({ error: 'Keine Berechtigung' }, { status: 403 }) } const existing = await (prisma as any).user.findUnique({ where: { email: data.email } }) if (existing) { return NextResponse.json({ error: 'E-Mail bereits vergeben' }, { status: 400 }) } const hashedPassword = await hashPassword(data.password) // Rechte-Ausweitung verhindern: Nicht-SERVER_ADMIN darf NUR im eigenen Tenant // anlegen — der mitgeschickte tenantId aus dem Body wird ignoriert. const tenantId = session.role === 'SERVER_ADMIN' ? (data.tenantId || session.tenantId) : session.tenantId const user = await (prisma as any).user.create({ data: { email: data.email, name: data.name, password: hashedPassword, role: data.role as any, ...(tenantId && data.role !== 'SERVER_ADMIN' ? { memberships: { create: { tenantId, role: data.role as any }, }, } : {}), }, select: { id: true, email: true, name: true, role: true, createdAt: true, }, }) return NextResponse.json({ user }, { status: 201 }) } catch (error) { if (error instanceof z.ZodError) { return NextResponse.json({ error: 'Ungültige Daten' }, { status: 400 }) } console.error('Error creating user:', error) return NextResponse.json({ error: 'Interner Fehler' }, { status: 500 }) } }