/** * EmailAuthController * * @description Controller for email/password authentication. * Extracted from auth.controller.ts (P0-009: Auth Controller split). * * Routes: * - POST /auth/register - Register new user * - POST /auth/login - Login with email/password * - POST /auth/verify-email - Verify email address * - POST /auth/forgot-password - Request password reset * - POST /auth/reset-password - Reset password with token * - POST /auth/change-password - Change password (authenticated) * * @see OAuthController - OAuth authentication * @see TwoFactorController - 2FA operations * @see TokenController - Token management */ import { Request, Response, NextFunction } from 'express'; import { emailService } from '../services/email.service'; /** * Gets client info from request */ const getClientInfo = (req: Request) => ({ userAgent: req.headers['user-agent'], ipAddress: req.ip || req.socket.remoteAddress, }); /** * POST /auth/register * * Register a new user with email/password */ export const register = async (req: Request, res: Response, next: NextFunction) => { try { const { email, password, firstName, lastName, acceptTerms } = req.body; const { userAgent, ipAddress } = getClientInfo(req); const result = await emailService.register( { email, password, firstName, lastName, acceptTerms }, userAgent, ipAddress, ); res.status(201).json({ success: true, message: result.message, data: { userId: result.userId }, }); } catch (error) { next(error); } }; /** * POST /auth/login * * Login with email/password (supports 2FA) */ export const login = async (req: Request, res: Response, next: NextFunction) => { try { const { email, password, totpCode, rememberMe } = req.body; const { userAgent, ipAddress } = getClientInfo(req); const result = await emailService.login( { email, password, totpCode, rememberMe }, userAgent, ipAddress, ); if (result.requiresTwoFactor) { return res.status(200).json({ success: true, requiresTwoFactor: true, message: 'Please enter your 2FA code', }); } res.json({ success: true, data: result, }); } catch (error) { next(error); } }; /** * POST /auth/verify-email * * Verify email address with token */ export const verifyEmail = async (req: Request, res: Response, next: NextFunction) => { try { const { token } = req.body; const result = await emailService.verifyEmail(token); res.json({ success: true, message: result.message, }); } catch (error) { next(error); } }; /** * POST /auth/forgot-password * * Request password reset email */ export const forgotPassword = async (req: Request, res: Response, next: NextFunction) => { try { const { email } = req.body; const result = await emailService.sendPasswordResetEmail(email); res.json({ success: true, message: result.message, }); } catch (error) { next(error); } }; /** * POST /auth/reset-password * * Reset password using token from email */ export const resetPassword = async (req: Request, res: Response, next: NextFunction) => { try { const { token, password } = req.body; const result = await emailService.resetPassword(token, password); res.json({ success: true, message: result.message, }); } catch (error) { next(error); } }; /** * POST /auth/change-password * * Change password for authenticated user */ export const changePassword = async (req: Request, res: Response, next: NextFunction) => { try { const userId = req.user!.id; const { currentPassword, newPassword } = req.body; const result = await emailService.changePassword(userId, currentPassword, newPassword); res.json({ success: true, message: result.message, }); } catch (error) { next(error); } };