import { RequestPasswordResetCommand } from './RequestPasswordResetCommand'; import { IUserRepository } from '../../../Domain/IRepository/IUserRepository'; import { EmailService } from '../../Services/EmailService'; import { TokenService } from '../../Services/TokenService'; import { logAuth, logWarning, logError } from '../../Services/Logger'; export class RequestPasswordResetCommandHandler { constructor( private userRepo: IUserRepository, private emailService: EmailService ) {} async execute(cmd: RequestPasswordResetCommand): Promise { try { if (!cmd.email) { throw new Error('Email is required'); } // Find user by email const user = await this.userRepo.findByEmail(cmd.email); if (!user) { // Don't reveal if user exists or not for security reasons // Still return true but don't send email logAuth(`Password reset requested for non-existent email: ${cmd.email}`); return true; } // Generate password reset token const resetTokenData = TokenService.generatePasswordResetToken(); // Update user with reset token user.token = await TokenService.hashToken(resetTokenData.token); user.TokenExpires = resetTokenData.expiresAt; await this.userRepo.update(user.id, user); // Send password reset email try { const baseUrl = process.env.FRONTEND_URL || 'http://localhost:5173'; const resetUrl = TokenService.generatePasswordResetUrl(baseUrl, resetTokenData.token); var lang: 'en' | 'hu' | 'de' = 'en'; if (cmd.language) { lang = cmd.language.toLowerCase() as 'en' | 'hu' | 'de'; } const emailSent = await this.emailService.sendPasswordResetEmail( user.email, `${user.fname} ${user.lname}`, resetTokenData.token, resetUrl, lang ); if (!emailSent) { logWarning(`Failed to send password reset email to ${user.email}`); // Don't throw error - request should still succeed even if email fails } else { logAuth(`Password reset email sent successfully to ${user.email}`); } } catch (emailError) { logError('Error sending password reset email', emailError instanceof Error ? emailError : new Error(String(emailError))); // Don't throw error - request should still succeed even if email fails } return true; } catch (error) { logError('Password reset request error', error instanceof Error ? error : new Error(String(error))); throw error; } } }