import type { NextApiRequest, NextApiResponse } from 'next' import crypto from 'crypto' import { findUserByEmail } from './[...nextauth]' import { AuthResponse, ForgotPasswordInput, TokenPayload } from '@/lib/auth/types' import { withRateLimit } from '@/lib/auth/withAuth' // In-memory token store (will be replaced with database in Agent 2) const passwordResetTokens = new Map() // Token expiry: 1 hour const TOKEN_EXPIRY_MS = 60 * 60 * 1000 function generateResetToken(userId: string, email: string): string { const token = crypto.randomBytes(32).toString('hex') const payload: TokenPayload = { userId, email, type: 'password_reset', expiresAt: Date.now() + TOKEN_EXPIRY_MS, } passwordResetTokens.set(token, payload) return token } export function verifyResetToken(token: string): TokenPayload | null { const payload = passwordResetTokens.get(token) if (!payload) return null if (Date.now() > payload.expiresAt) { passwordResetTokens.delete(token) return null } return payload } export function invalidateResetToken(token: string): void { passwordResetTokens.delete(token) } 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 { email }: ForgotPasswordInput = req.body if (!email) { return res.status(400).json({ success: false, message: 'Email is required', error: 'VALIDATION_ERROR', }) } // Always return success to prevent email enumeration attacks const successResponse: AuthResponse = { success: true, message: 'If an account exists with this email, you will receive a password reset link.', } const user = findUserByEmail(email) if (!user) { // Return success even if user doesn't exist (security best practice) return res.status(200).json(successResponse) } // Generate reset token const resetToken = generateResetToken(user.id, user.email) // Build reset URL const baseUrl = process.env.NEXTAUTH_URL || `http://${req.headers.host}` const resetUrl = `${baseUrl}/auth/reset-password?token=${resetToken}` // TODO: Send email with reset link (will be implemented with Agent 8 - Notifications) // For now, log the reset URL (in development only) if (process.env.NODE_ENV === 'development') { console.log(`Password reset link for ${email}: ${resetUrl}`) } return res.status(200).json(successResponse) } catch (error) { console.error('Forgot password error:', error) return res.status(500).json({ success: false, message: 'An error occurred processing your request', error: 'INTERNAL_ERROR', }) } } // Apply rate limiting: 3 requests per minute per IP export default withRateLimit(handler, { limit: 3, windowMs: 60000, })