import { NextRequest, NextResponse } from 'next/server'; import bcryptjs from 'bcryptjs'; import { eq } from 'drizzle-orm'; import { db } from '@/lib/db'; import { users } from '@/lib/db/schema'; export async function POST(request: NextRequest) { let body: unknown; try { body = await request.json(); } catch { return NextResponse.json({ error: 'Invalid JSON body' }, { status: 400 }); } const { email, password, name } = body as Record; // Validate email if (!email || typeof email !== 'string' || email.trim() === '') { return NextResponse.json({ error: 'Email is required' }, { status: 400 }); } // Validate password if (!password || typeof password !== 'string' || password.length < 8) { return NextResponse.json( { error: 'Password must be at least 8 characters' }, { status: 400 } ); } const normalizedEmail = email.trim().toLowerCase(); // Check email uniqueness const [existingUser] = await db .select({ id: users.id }) .from(users) .where(eq(users.email, normalizedEmail)) .limit(1); if (existingUser) { return NextResponse.json( { error: 'An account with this email already exists' }, { status: 409 } ); } // Hash password const password_hash = await bcryptjs.hash(password, 12); // Insert user const [newUser] = await db .insert(users) .values({ email: normalizedEmail, password_hash, name: typeof name === 'string' && name.trim() !== '' ? name.trim() : null, provider: 'credentials', }) .returning({ id: users.id, email: users.email, name: users.name }); return NextResponse.json( { id: newUser.id, email: newUser.email, name: newUser.name }, { status: 201 } ); }