Files
BRETT/server/api/auth/register.post.ts
T
2026-10-03 20:07:49 +02:00

52 lines
1.8 KiB
TypeScript

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
}
})