const bcrypt = require('bcryptjs'); const { User, AuditLog } = require('../models'); const { generateToken } = require('../config/auth'); const { AUDIT_ACTIONS } = require('../config/constants'); // Register new user exports.register = async (req, res) => { try { const { email, password, fullName, role, phone, region, zone } = req.body; // Validate input if (!email || !password || !fullName || !role) { return res.status(400).json({ success: false, message: 'Email, password, full name, and role are required' }); } // Check if user already exists const existingUser = await User.findOne({ where: { email } }); if (existingUser) { return res.status(400).json({ success: false, message: 'User with this email already exists' }); } // Hash password const hashedPassword = await bcrypt.hash(password, 10); // Insert user const user = await User.create({ email, password: hashedPassword, name: fullName, role, phone, region, zone }); // Log audit await AuditLog.create({ userId: user.id, action: AUDIT_ACTIONS.CREATED, entityType: 'user', entityId: user.id }); res.status(201).json({ success: true, message: 'User registered successfully', userId: user.id }); } catch (error) { console.error('Register error:', error); res.status(500).json({ success: false, message: 'Error registering user' }); } }; // Login exports.login = async (req, res) => { try { const { email, password } = req.body; // Validate input if (!email || !password) { return res.status(400).json({ success: false, message: 'Email and password are required' }); } // Get user const user = await User.findOne({ where: { email } }); if (!user) { return res.status(401).json({ success: false, message: 'Invalid email or password' }); } // Check if account is active if (user.status !== 'active') { return res.status(403).json({ success: false, message: 'Account is deactivated' }); } // Verify password const isValidPassword = await bcrypt.compare(password, user.password); if (!isValidPassword) { return res.status(401).json({ success: false, message: 'Invalid email or password' }); } // Update last login await user.update({ lastLogin: new Date() }); // Generate token const token = generateToken(user); // Log audit await AuditLog.create({ userId: user.id, action: 'user_login', entityType: 'user', entityId: user.id }); res.json({ success: true, token, user: { id: user.id, email: user.email, fullName: user.name, role: user.role, region: user.region, zone: user.zone } }); } catch (error) { console.error('Login error:', error); res.status(500).json({ success: false, message: 'Error during login' }); } }; // Get profile exports.getProfile = async (req, res) => { try { const user = await User.findByPk(req.user.id, { attributes: ['id', 'email', 'name', 'role', 'region', 'zone', 'phone', 'createdAt'] }); if (!user) { return res.status(404).json({ success: false, message: 'User not found' }); } res.json({ success: true, user: { id: user.id, email: user.email, fullName: user.name, role: user.role, region: user.region, zone: user.zone, phone: user.phone, createdAt: user.createdAt } }); } catch (error) { console.error('Get profile error:', error); res.status(500).json({ success: false, message: 'Error fetching profile' }); } }; // Update profile exports.updateProfile = async (req, res) => { try { const { fullName, phone } = req.body; const user = await User.findByPk(req.user.id); if (!user) { return res.status(404).json({ success: false, message: 'User not found' }); } await user.update({ name: fullName || user.name, phone: phone || user.phone }); // Log audit await AuditLog.create({ userId: req.user.id, action: AUDIT_ACTIONS.UPDATED, entityType: 'user', entityId: req.user.id }); res.json({ success: true, message: 'Profile updated successfully' }); } catch (error) { console.error('Update profile error:', error); res.status(500).json({ success: false, message: 'Error updating profile' }); } }; // Change password exports.changePassword = async (req, res) => { try { const { currentPassword, newPassword } = req.body; if (!currentPassword || !newPassword) { return res.status(400).json({ success: false, message: 'Current password and new password are required' }); } // Get current user const user = await User.findByPk(req.user.id); if (!user) { return res.status(404).json({ success: false, message: 'User not found' }); } // Verify current password const isValid = await bcrypt.compare(currentPassword, user.password); if (!isValid) { return res.status(401).json({ success: false, message: 'Current password is incorrect' }); } // Hash new password const hashedPassword = await bcrypt.hash(newPassword, 10); // Update password await user.update({ password: hashedPassword }); // Log audit await AuditLog.create({ userId: req.user.id, action: 'password_changed', entityType: 'user', entityId: req.user.id }); res.json({ success: true, message: 'Password changed successfully' }); } catch (error) { console.error('Change password error:', error); res.status(500).json({ success: false, message: 'Error changing password' }); } };