import bcrypt from 'bcryptjs'; import { sql } from '../../../lib/sql.js'; import { generateToken } from '../auth-utils.js'; import { checkAuthRateLimit } from '../../../lib/rate-limit.js'; export default async function handler(req, res) { if (req.method !== 'POST') { return res.status(405).json({ error: 'Method not allowed' }); } const { allowed, reset } = await checkAuthRateLimit(req); if (!allowed) { res.setHeader('Retry-After', Math.ceil((reset - Date.now()) / 1000)); return res.status(429).json({ error: 'Too many attempts. Try again later.' }); } try { const { email, password } = req.body; if (!email || !password) { return res.status(400).json({ error: 'Email and password are required' }); } // Get user from database const result = await sql` SELECT id, email, password, role, created_at FROM users WHERE email = ${email} `; if (result.rows.length === 0) { return res.status(401).json({ error: 'Invalid credentials' }); } const user = result.rows[0]; // Verify password const isValidPassword = await bcrypt.compare(password, user.password); if (!isValidPassword) { return res.status(401).json({ error: 'Invalid credentials' }); } // Generate JWT token const token = generateToken({ id: user.id, email: user.email, role: user.role }); // Return user data (without password) and token const { password: _, ...userWithoutPassword } = user; res.status(200).json({ success: true, user: userWithoutPassword, token }); } catch (error) { console.error('Login error:', error); res.status(500).json({ error: 'Internal server error' }); } }