const { logger } = require('../middleware/logger'); class PasswordResetRepository { constructor(unitOfWork) { this.unitOfWork = unitOfWork; this.conn = unitOfWork.connection; } async findValidTokenByUserId(userId) { logger.info('PasswordResetRepository.findValidTokenByUserId:start', { userId }); try { const [rows] = await this.conn.query( `SELECT * FROM password_resets WHERE user_id = ? AND used_at IS NULL AND expires_at > NOW() LIMIT 1`, [userId] ); logger.info('PasswordResetRepository.findValidTokenByUserId:success', { userId, found: rows.length > 0 }); return rows.length > 0 ? rows[0] : null; } catch (error) { logger.error('PasswordResetRepository.findValidTokenByUserId:error', { userId, error: error.message }); throw error; } } async createToken(userId, token, expiresAt) { logger.info('PasswordResetRepository.createToken:start', { userId, token, expiresAt }); try { await this.conn.query( `INSERT INTO password_resets (user_id, token, expires_at) VALUES (?, ?, ?)`, [userId, token, expiresAt] ); logger.info('PasswordResetRepository.createToken:success', { userId }); } catch (error) { logger.error('PasswordResetRepository.createToken:error', { userId, error: error.message }); throw error; } } async findValidToken(token) { logger.info('PasswordResetRepository.findValidToken:start', { token }); try { const [rows] = await this.conn.query( `SELECT * FROM password_resets WHERE token = ? AND used_at IS NULL LIMIT 1`, [token] ); const row = rows[0]; logger.info('PasswordResetRepository.findValidToken:success', { token, found: !!row }); if (!row || new Date(row.expires_at) < new Date()) { return null; } return row; } catch (error) { logger.error('PasswordResetRepository.findValidToken:error', { token, error: error.message }); throw error; } } async updateUserPassword(userId, hashedPassword) { logger.info('PasswordResetRepository.updateUserPassword:start', { userId }); try { await this.conn.query( `UPDATE users SET password = ? WHERE id = ?`, [hashedPassword, userId] ); logger.info('PasswordResetRepository.updateUserPassword:success', { userId }); } catch (error) { logger.error('PasswordResetRepository.updateUserPassword:error', { userId, error: error.message }); throw error; } } async markTokenUsed(tokenId) { logger.info('PasswordResetRepository.markTokenUsed:start', { tokenId }); try { await this.conn.query( `UPDATE password_resets SET used_at = NOW() WHERE id = ?`, [tokenId] ); logger.info('PasswordResetRepository.markTokenUsed:success', { tokenId }); } catch (error) { logger.error('PasswordResetRepository.markTokenUsed:error', { tokenId, error: error.message }); throw error; } } } module.exports = PasswordResetRepository;