76 lines
2.6 KiB
TypeScript
76 lines
2.6 KiB
TypeScript
|
|
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<boolean> {
|
|
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;
|
|
}
|
|
}
|
|
}
|