import type { NextApiRequest, NextApiResponse } from 'next' import bcrypt from 'bcryptjs' import { verifyResetToken, invalidateResetToken } from './forgot-password' import { getUserById } from './[...nextauth]' import { AuthResponse, ResetPasswordInput } from '@/lib/auth/types' import { withRateLimit } from '@/lib/auth/withAuth' const BCRYPT_ROUNDS = 12 async function handler( req: NextApiRequest, res: NextApiResponse ) { if (req.method !== 'POST') { return res.status(405).json({ success: false, message: 'Method not allowed', error: 'Only POST requests are accepted', }) } try { const { token, password }: ResetPasswordInput = req.body if (!token || !password) { return res.status(400).json({ success: false, message: 'Token and new password are required', error: 'VALIDATION_ERROR', }) } // Validate password strength if (password.length < 8) { return res.status(400).json({ success: false, message: 'Password must be at least 8 characters long', error: 'WEAK_PASSWORD', }) } const hasUpperCase = /[A-Z]/.test(password) const hasLowerCase = /[a-z]/.test(password) const hasNumbers = /\d/.test(password) if (!hasUpperCase || !hasLowerCase || !hasNumbers) { return res.status(400).json({ success: false, message: 'Password must contain uppercase, lowercase, and numbers', error: 'WEAK_PASSWORD', }) } // Verify token const payload = verifyResetToken(token) if (!payload) { return res.status(400).json({ success: false, message: 'Invalid or expired reset token', error: 'INVALID_TOKEN', }) } // Get user const user = getUserById(payload.userId) if (!user) { return res.status(400).json({ success: false, message: 'User not found', error: 'USER_NOT_FOUND', }) } // Hash new password const passwordHash = await bcrypt.hash(password, BCRYPT_ROUNDS) // Update user password (in-memory for now) user.passwordHash = passwordHash // Invalidate the used token invalidateResetToken(token) // TODO: Invalidate all existing sessions for this user (security best practice) // TODO: Send confirmation email console.log(`Password reset successful for user: ${user.email}`) return res.status(200).json({ success: true, message: 'Password reset successful. You can now sign in with your new password.', }) } catch (error) { console.error('Reset password error:', error) return res.status(500).json({ success: false, message: 'An error occurred resetting your password', error: 'INTERNAL_ERROR', }) } } // Apply rate limiting: 5 requests per minute per IP export default withRateLimit(handler, { limit: 5, windowMs: 60000, })