const express = require('express'); const jwt = require('jsonwebtoken'); const bcrypt = require('bcryptjs'); const { body, validationResult } = require('express-validator'); const { User } = require('../models'); const { auth, requireSuperAdmin } = require('../middleware/auth'); const router = express.Router(); // Generate JWT token const generateToken = (userId) => { return jwt.sign({ userId }, process.env.JWT_SECRET, { expiresIn: process.env.JWT_EXPIRES_IN || '7d' }); }; // @route POST /api/auth/login // @desc Login user // @access Public router.post('/login', [ body('email').isEmail().normalizeEmail(), body('password').isLength({ min: 6 }) ], async (req, res) => { try { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } const { email, password } = req.body; const user = await User.findOne({ where: { email } }); console.log('Login attempt for email:', email, 'User found:', !!user, 'User active:', user?.isActive); if (!user || !user.isActive) { return res.status(401).json({ error: 'Invalid credentials or account inactive.' }); } const isPasswordValid = await user.comparePassword(password); console.log('Password validation result:', isPasswordValid); if (!isPasswordValid) { return res.status(401).json({ error: 'Invalid credentials.' }); } // Update last login await user.update({ lastLogin: new Date() }); const token = generateToken(user.id); res.json({ token, user: { id: user.id, firstName: user.firstName, lastName: user.lastName, email: user.email, role: user.role, avatar: user.avatar, phone: user.phone, requiresPasswordChange: user.requiresPasswordChange } }); } catch (error) { console.error('Login error:', error); res.status(500).json({ error: 'Server error.' }); } }); // @route POST /api/auth/register // @desc Register new user (Super Admin only) // @access Private (Super Admin) router.post('/register', [ auth, requireSuperAdmin, body('firstName').isLength({ min: 2, max: 50 }), body('lastName').isLength({ min: 2, max: 50 }), body('email').isEmail().normalizeEmail(), body('password').isLength({ min: 6 }), body('role').isIn(['super_admin', 'trainer', 'trainee']) ], async (req, res) => { try { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } const { firstName, lastName, email, password, role, phone } = req.body; // Check if user already exists const existingUser = await User.findOne({ where: { email } }); if (existingUser) { return res.status(400).json({ error: 'User with this email already exists.' }); } const user = await User.create({ firstName, lastName, email, password, role, phone }); console.log('User created successfully:', { id: user.id, email: user.email, role: user.role, isActive: user.isActive }); res.status(201).json({ message: 'User created successfully.', user: { id: user.id, firstName: user.firstName, lastName: user.lastName, email: user.email, role: user.role, phone: user.phone } }); } catch (error) { console.error('Registration error:', error); res.status(500).json({ error: 'Server error.' }); } }); // @route GET /api/auth/me // @desc Get current user // @access Private router.get('/me', auth, async (req, res) => { try { res.json({ user: { id: req.user.id, firstName: req.user.firstName, lastName: req.user.lastName, email: req.user.email, role: req.user.role, avatar: req.user.avatar, phone: req.user.phone, lastLogin: req.user.lastLogin } }); } catch (error) { console.error('Get user error:', error); res.status(500).json({ error: 'Server error.' }); } }); // @route PUT /api/auth/profile // @desc Update user profile // @access Private router.put('/profile', [ auth, body('firstName').optional().isLength({ min: 2, max: 50 }), body('lastName').optional().isLength({ min: 2, max: 50 }), body('phone').optional().isMobilePhone() ], async (req, res) => { try { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } const { firstName, lastName, phone } = req.body; const updateData = {}; if (firstName) updateData.firstName = firstName; if (lastName) updateData.lastName = lastName; if (phone) updateData.phone = phone; await req.user.update(updateData); res.json({ message: 'Profile updated successfully.', user: { id: req.user.id, firstName: req.user.firstName, lastName: req.user.lastName, email: req.user.email, role: req.user.role, avatar: req.user.avatar, phone: req.user.phone } }); } catch (error) { console.error('Profile update error:', error); res.status(500).json({ error: 'Server error.' }); } }); // @route PUT /api/auth/change-password // @desc Change user password // @access Private router.put('/change-password', [ auth, body('currentPassword').isLength({ min: 6 }), body('newPassword').isLength({ min: 6 }) ], async (req, res) => { try { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } const { currentPassword, newPassword } = req.body; const isCurrentPasswordValid = await req.user.comparePassword(currentPassword); if (!isCurrentPasswordValid) { return res.status(400).json({ error: 'Current password is incorrect.' }); } await req.user.update({ password: newPassword }); res.json({ message: 'Password changed successfully.' }); } catch (error) { console.error('Password change error:', error); res.status(500).json({ error: 'Server error.' }); } }); // @route PUT /api/auth/first-password-change // @desc Change password on first login (for imported users) // @access Private router.put('/first-password-change', [ auth, body('newPassword').isLength({ min: 6 }) ], async (req, res) => { try { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } const { newPassword } = req.body; // Check if user requires password change if (!req.user.requiresPasswordChange) { return res.status(400).json({ error: 'Password change not required.' }); } await req.user.update({ password: newPassword, requiresPasswordChange: false }); res.json({ message: 'Password changed successfully.', user: { id: req.user.id, firstName: req.user.firstName, lastName: req.user.lastName, email: req.user.email, role: req.user.role, avatar: req.user.avatar, phone: req.user.phone, requiresPasswordChange: false } }); } catch (error) { console.error('First password change error:', error); res.status(500).json({ error: 'Server error.' }); } }); module.exports = router;