import { count, eq } from 'drizzle-orm' import { z } from 'zod' import { users } from '../../db/schema' const bodySchema = z.object({ name: z.string().trim().min(3, 'Mindestens 3 Zeichen').max(50), password: z.string().min(6, 'Mindestens 6 Zeichen').max(128), email: z.union([z.literal(''), z.email().max(255)]).optional(), }) export default defineEventHandler(async (event) => { const body = await readValidatedBody(event, bodySchema.parse) const db = useDb() const existing = await db .select({ id: users.id }) .from(users) .where(eq(users.name, body.name)) .limit(1) if (existing.length) { throw createError({ statusCode: 409, statusMessage: 'Name ist bereits vergeben' }) } try { const color = randomUserColor() const [result] = await db.insert(users).values({ name: body.name, email: body.email || null, passwordHash: hashPassword(body.password), color, }) const userId = Number(result.insertId) const [{ value: userCount }] = await db.select({ value: count() }).from(users) let roleNames: string[] = [] if (userCount === 1) { const adminRoleId = await ensureRole('admin') await assignRole(userId, adminRoleId) roleNames = ['admin'] } await createSession(event, userId) return { user: { id: userId, name: body.name, email: body.email || null, color, cardEffect: null, cardEffectColor: null, cardVignette: false, cardBorderEffect: null, cardBorderEffectColor: null, avatarUrl: null, roles: roleNames, permissions: await getUserPermissions(userId) } } } catch (err: unknown) { if (typeof err === 'object' && err !== null && (err as { errno?: number }).errno === 1062) { throw createError({ statusCode: 409, statusMessage: 'Name oder E-Mail ist bereits vergeben' }) } throw err } })