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

99 lines
2.7 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import connectDB from '@/lib/mongodb'
import { User } from '@/models/user'
import { generateTokens } from '@/lib/jwt'
const LoginSchema = z.object({
emailOrId: z.string().min(1, 'Email or Silicon ID is required'),
password: z.string().min(1, 'Password is required'),
rememberMe: z.boolean().optional(),
})
export async function POST(request: NextRequest) {
try {
const body = await request.json()
// Validate input
const validatedData = LoginSchema.parse(body)
// Connect to database
await connectDB()
// Find user by email or Silicon ID
const emailOrId = validatedData.emailOrId
const user = await User.findOne({
$or: [{ email: emailOrId.toLowerCase() }, { siliconId: emailOrId }],
})
if (!user) {
return NextResponse.json(
{ success: false, error: { message: 'Invalid credentials', code: 'INVALID_CREDENTIALS' } },
{ status: 401 }
)
}
// Check password
const isPasswordValid = await user.comparePassword(validatedData.password)
if (!isPasswordValid) {
return NextResponse.json(
{ success: false, error: { message: 'Invalid credentials', code: 'INVALID_CREDENTIALS' } },
{ status: 401 }
)
}
// Generate tokens
const { accessToken, refreshToken } = generateTokens({
userId: user._id.toString(),
email: user.email,
role: user.role,
})
// Update user's refresh token and last login
user.refreshToken = refreshToken
user.lastLogin = new Date()
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('Login 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 }
)
}
}