const User = require('../models/User'); const { validationResult } = require('express-validator'); // @desc Get all users // @route GET /api/users // @access Private (superadmin: all users, companyadmin: only users from their company) exports.getUsers = async (req, res, next) => { try { let query = {}; // If user is companyadmin, only get users from their company if (req.user.role === 'companyadmin') { query = { companyId: req.user.companyId }; } const users = await User.find(query).select('-password'); res.status(200).json({ success: true, count: users.length, data: users }); } catch (error) { next(error); } }; // @desc Get single user // @route GET /api/users/:id // @access Private (superadmin: any user, companyadmin: only users from their company) exports.getUser = async (req, res, next) => { try { const user = await User.findById(req.params.id).select('-password'); if (!user) { return res.status(404).json({ success: false, message: 'User not found' }); } // Check if companyadmin is trying to access user from another company if (req.user.role === 'companyadmin' && user.companyId.toString() !== req.user.companyId.toString()) { return res.status(403).json({ success: false, message: 'Not authorized to access this user' }); } res.status(200).json({ success: true, data: user }); } catch (error) { next(error); } }; // @desc Create user // @route POST /api/users // @access Private (superadmin: can create any user, companyadmin: can only create employers in their company) exports.createUser = async (req, res, next) => { try { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ success: false, errors: errors.array() }); } const { email, password, role, companyId } = req.body; // Check if user is trying to create a role they're not allowed to if (req.user.role === 'companyadmin' && role !== 'employer') { return res.status(403).json({ success: false, message: 'Company admin can only create employer users' }); } // Check if companyadmin is trying to create user for another company if (req.user.role === 'companyadmin' && companyId.toString() !== req.user.companyId.toString()) { return res.status(403).json({ success: false, message: 'Not authorized to create user for another company' }); } // Create user const user = await User.create({ email, password, role, companyId: role === 'superadmin' ? null : companyId, createdBy: req.user._id }); res.status(201).json({ success: true, data: { _id: user._id, email: user.email, role: user.role, companyId: user.companyId, createdAt: user.createdAt } }); } catch (error) { // Check for duplicate email if (error.code === 11000) { return res.status(400).json({ success: false, message: 'Email already exists' }); } next(error); } }; // @desc Update user // @route PUT /api/users/:id // @access Private (superadmin: any user, companyadmin: only employers in their company) exports.updateUser = async (req, res, next) => { try { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ success: false, errors: errors.array() }); } let user = await User.findById(req.params.id); if (!user) { return res.status(404).json({ success: false, message: 'User not found' }); } // Check if companyadmin is trying to update user from another company if (req.user.role === 'companyadmin' && user.companyId.toString() !== req.user.companyId.toString()) { return res.status(403).json({ success: false, message: 'Not authorized to update this user' }); } // Check if companyadmin is trying to update a companyadmin if (req.user.role === 'companyadmin' && user.role === 'companyadmin') { return res.status(403).json({ success: false, message: 'Company admin cannot update other company admins' }); } // Check if trying to change role to something not allowed if (req.body.role && req.user.role === 'companyadmin' && req.body.role !== 'employer') { return res.status(403).json({ success: false, message: 'Company admin can only update to employer role' }); } // Update user user = await User.findByIdAndUpdate( req.params.id, req.body, { new: true, runValidators: true } ).select('-password'); res.status(200).json({ success: true, data: user }); } catch (error) { next(error); } }; // @desc Delete user // @route DELETE /api/users/:id // @access Private (superadmin: any user, companyadmin: only employers in their company) exports.deleteUser = async (req, res, next) => { try { const user = await User.findById(req.params.id); if (!user) { return res.status(404).json({ success: false, message: 'User not found' }); } // Check if companyadmin is trying to delete user from another company if (req.user.role === 'companyadmin' && user.companyId.toString() !== req.user.companyId.toString()) { return res.status(403).json({ success: false, message: 'Not authorized to delete this user' }); } // Check if companyadmin is trying to delete a companyadmin if (req.user.role === 'companyadmin' && user.role === 'companyadmin') { return res.status(403).json({ success: false, message: 'Company admin cannot delete other company admins' }); } await user.deleteOne(); res.status(200).json({ success: true, data: {} }); } catch (error) { next(error); } }; // @desc Reset user password // @route PUT /api/users/:id/reset-password // @access Private (superadmin: any user, companyadmin: only employers in their company) exports.resetPassword = async (req, res, next) => { try { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ success: false, errors: errors.array() }); } const { newPassword } = req.body; let user = await User.findById(req.params.id); if (!user) { return res.status(404).json({ success: false, message: 'User not found' }); } // Check if companyadmin is trying to reset password for user from another company if (req.user.role === 'companyadmin' && user.companyId.toString() !== req.user.companyId.toString()) { return res.status(403).json({ success: false, message: 'Not authorized to reset password for this user' }); } // Check if companyadmin is trying to reset password for a companyadmin if (req.user.role === 'companyadmin' && user.role === 'companyadmin') { return res.status(403).json({ success: false, message: 'Company admin cannot reset password for other company admins' }); } // Update password user.password = newPassword; await user.save(); res.status(200).json({ success: true, message: 'Password reset successful' }); } catch (error) { next(error); } };