281 lines
7.6 KiB
JavaScript
281 lines
7.6 KiB
JavaScript
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);
|
|
}
|
|
};
|