ai-wpa/app/api/auth/register/route.ts

110 lines
2.9 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import connectDB from '@/lib/mongodb'
import { User, UserSchema } from '@/models/user'
import { generateTokens } from '@/lib/jwt'
import { generateSiliconId } from '@/lib/siliconId'
const RegisterSchema = UserSchema.pick({
email: true,
name: true,
password: true,
})
export async function POST(request: NextRequest) {
try {
const body = await request.json()
// Validate input
const validatedData = RegisterSchema.parse(body)
// Connect to database
await connectDB()
// Check if user already exists
const existingUser = await User.findOne({ email: validatedData.email.toLowerCase() })
if (existingUser) {
return NextResponse.json(
{ success: false, error: { message: 'User already exists', code: 'USER_EXISTS' } },
{ status: 409 }
)
}
// Generate tokens first
const tempUser = {
email: validatedData.email.toLowerCase(),
name: validatedData.name,
role: 'user' as const,
}
// Generate unique Silicon ID
const siliconId = generateSiliconId()
console.log('Generated siliconId:', siliconId)
// Create new user
const user = new User({
email: tempUser.email,
name: tempUser.name,
password: validatedData.password,
siliconId: siliconId,
provider: 'local',
})
console.log('User before save:', JSON.stringify(user.toObject(), null, 2))
await user.save()
console.log('user after save:', user)
// Generate tokens with actual user ID
const { accessToken, refreshToken } = generateTokens({
userId: user._id.toString(),
email: user.email,
role: user.role,
})
// Update user with refresh token (single save)
user.refreshToken = refreshToken
await user.save()
// Create response with tokens
const response = NextResponse.json({
success: true,
data: {
user: user.toJSON(),
accessToken,
},
})
// Set HTTP-only cookies
response.cookies.set('accessToken', accessToken, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: 15 * 60, // 15 minutes
path: '/',
})
response.cookies.set('refreshToken', refreshToken, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: 7 * 24 * 60 * 60, // 7 days
path: '/',
})
return response
} catch (error) {
console.error('Registration error:', error)
if (error instanceof z.ZodError) {
return NextResponse.json(
{ success: false, error: { message: error.issues[0].message, code: 'VALIDATION_ERROR' } },
{ status: 400 }
)
}
return NextResponse.json(
{ success: false, error: { message: 'Internal server error', code: 'INTERNAL_ERROR' } },
{ status: 500 }
)
}
}