/** * Controller utilisateur */ import bcrypt from 'bcrypt'; import { pool } from '../../db.js'; import { AppError, asyncHandler } from '../middleware/errorHandler.js'; import { sendAccountDeletedEmail } from '../services/email.service.js'; /** * Récupérer le profil de l'utilisateur connecté * GET /api/user/profile */ export const getProfile = asyncHandler(async (req, res) => { const userId = req.user.id; const result = await pool.query( `SELECT id, email, first_name, last_name, phone, address, city, postal_code, role, is_verified, is_active, created_at, updated_at FROM users WHERE id = $1`, [userId] ); const user = result.rows[0]; res.json({ success: true, data: { id: user.id, email: user.email, firstName: user.first_name, lastName: user.last_name, phone: user.phone, address: user.address, city: user.city, postalCode: user.postal_code, role: user.role, isVerified: user.is_verified, isActive: user.is_active, createdAt: user.created_at, updatedAt: user.updated_at, }, }); }); /** * Mettre à jour le profil * PUT /api/user/profile */ export const updateProfile = asyncHandler(async (req, res) => { const userId = req.user.id; const { firstName, lastName, phone, address, city, postalCode, isActive } = req.body; // Construire la requête dynamiquement const updates = []; const values = []; let paramCount = 1; if (firstName !== undefined) { updates.push(`first_name = $${paramCount++}`); values.push(firstName); } if (lastName !== undefined) { updates.push(`last_name = $${paramCount++}`); values.push(lastName); } if (phone !== undefined) { updates.push(`phone = $${paramCount++}`); values.push(phone); } if (address !== undefined) { updates.push(`address = $${paramCount++}`); values.push(address); } if (city !== undefined) { updates.push(`city = $${paramCount++}`); values.push(city); } if (postalCode !== undefined) { updates.push(`postal_code = $${paramCount++}`); values.push(postalCode); } if (isActive !== undefined) { updates.push(`is_active = $${paramCount++}`); values.push(isActive); } if (updates.length === 0) { return res.json({ success: true, message: 'Aucune modification à apporter', }); } // Ajouter updated_at à la mise à jour updates.push(`updated_at = NOW()`); values.push(userId); const query = ` UPDATE users SET ${updates.join(', ')} WHERE id = $${paramCount} RETURNING id, email, first_name, last_name, phone, address, city, postal_code, role, is_verified, is_active, created_at, updated_at `; const result = await pool.query(query, values); const user = result.rows[0]; res.json({ success: true, message: 'Profil mis à jour avec succès', data: { id: user.id, email: user.email, firstName: user.first_name, lastName: user.last_name, phone: user.phone, address: user.address, city: user.city, postalCode: user.postal_code, role: user.role, isVerified: user.is_verified, isActive: user.is_active, createdAt: user.created_at, updatedAt: user.updated_at, }, }); }); /** * Changer le mot de passe * PUT /api/user/change-password */ export const changePassword = asyncHandler(async (req, res, next) => { const userId = req.user.id; const { currentPassword, newPassword } = req.body; // Récupérer le mot de passe actuel const result = await pool.query('SELECT password FROM users WHERE id = $1', [userId]); if (result.rows.length === 0) { return next(new AppError('Utilisateur non trouvé', 404)); } const user = result.rows[0]; // Vérifier le mot de passe actuel const isPasswordValid = await bcrypt.compare(currentPassword, user.password); if (!isPasswordValid) { return next(new AppError('Mot de passe actuel incorrect', 401)); } // Hasher le nouveau mot de passe const hashedPassword = await bcrypt.hash(newPassword, 10); // Mettre à jour le mot de passe await pool.query('UPDATE users SET password = $1 WHERE id = $2', [hashedPassword, userId]); res.json({ success: true, message: 'Mot de passe modifié avec succès', }); }); /** * Supprimer le compte * DELETE /api/user/account */ export const deleteAccount = asyncHandler(async (req, res) => { const userId = req.user.id; // Récupérer les infos de l'utilisateur avant suppression const userResult = await pool.query( 'SELECT email, first_name FROM users WHERE id = $1', [userId] ); const user = userResult.rows[0]; // Supprimer l'utilisateur (les tickets seront supprimés en cascade) await pool.query('DELETE FROM users WHERE id = $1', [userId]); // Envoyer l'email de confirmation de suppression try { await sendAccountDeletedEmail(user.email, user.first_name); } catch (error) { console.error('Erreur envoi email de suppression:', error); } res.json({ success: true, message: 'Compte supprimé avec succès', }); }); export default { getProfile, updateProfile, changePassword, deleteAccount, };