const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); const { User } = require('../models'); const logger = require('../utils/logger'); const generateToken = (userId) => { return jwt.sign({ userId }, process.env.JWT_SECRET, { expiresIn: process.env.JWT_EXPIRES_IN || '7d' }); }; const register = async (req, res) => { try { const { email, password, firstName, lastName, role = 'user' } = req.body; // Validate input if (!email || !password || !firstName || !lastName) { return res.status(400).json({ success: false, error: 'All fields are required' }); } // Check if user already exists const existingUser = await User.findOne({ where: { email } }); if (existingUser) { return res.status(400).json({ success: false, error: 'User already exists with this email' }); } // Hash password const saltRounds = 12; const passwordHash = await bcrypt.hash(password, saltRounds); // Create user const user = await User.create({ email, password_hash: passwordHash, first_name: firstName, last_name: lastName, role }); // Generate token const token = generateToken(user.id); logger.info(`New user registered: ${email}`); res.status(201).json({ success: true, data: { user: { id: user.id, email: user.email, firstName: user.first_name, lastName: user.last_name, role: user.role }, token } }); } catch (error) { logger.error('Registration error:', error); res.status(500).json({ success: false, error: 'Internal server error' }); } }; const login = async (req, res) => { try { const { email, password } = req.body; // Validate input if (!email || !password) { return res.status(400).json({ success: false, error: 'Email and password are required' }); } // Find user const user = await User.findOne({ where: { email } }); if (!user) { return res.status(401).json({ success: false, error: 'Invalid credentials' }); } // Check if user is active if (!user.is_active) { return res.status(401).json({ success: false, error: 'Account is deactivated' }); } // Verify password const isValidPassword = await bcrypt.compare(password, user.password_hash); if (!isValidPassword) { return res.status(401).json({ success: false, error: 'Invalid credentials' }); } // Update last login await user.update({ last_login: new Date() }); // Generate token const token = generateToken(user.id); logger.info(`User logged in: ${email}`); res.json({ success: true, data: { user: { id: user.id, email: user.email, firstName: user.first_name, lastName: user.last_name, role: user.role }, token } }); } catch (error) { logger.error('Login error:', error); res.status(500).json({ success: false, error: 'Internal server error' }); } }; const getProfile = async (req, res) => { try { const user = await User.findByPk(req.user.userId, { attributes: { exclude: ['password_hash'] } }); if (!user) { return res.status(404).json({ success: false, error: 'User not found' }); } res.json({ success: true, data: { user } }); } catch (error) { logger.error('Get profile error:', error); res.status(500).json({ success: false, error: 'Internal server error' }); } }; const updateProfile = async (req, res) => { try { const { firstName, lastName, preferences } = req.body; const user = await User.findByPk(req.user.userId); if (!user) { return res.status(404).json({ success: false, error: 'User not found' }); } // Update user const updateData = {}; if (firstName) updateData.first_name = firstName; if (lastName) updateData.last_name = lastName; if (preferences) updateData.preferences = { ...user.preferences, ...preferences }; await user.update(updateData); res.json({ success: true, data: { user: { id: user.id, email: user.email, firstName: user.first_name, lastName: user.last_name, role: user.role, preferences: user.preferences } } }); } catch (error) { logger.error('Update profile error:', error); res.status(500).json({ success: false, error: 'Internal server error' }); } }; module.exports = { register, login, getProfile, updateProfile };