user.routes.js•6.86 kB
const express = require('express');
const User = require('../models/user.model');
const { authenticate, authorize } = require('../middleware/auth.middleware');
const { logger } = require('../utils/logger');
const router = express.Router();
/**
* @route GET /api/users
* @desc Get all users
* @access Private/Admin
*/
router.get('/', authenticate, authorize(['admin']), async (req, res) => {
try {
const users = await User.find().select('-password');
res.json({
success: true,
count: users.length,
data: users
});
} catch (error) {
logger.error('Error fetching users:', error);
res.status(500).json({
success: false,
message: 'Error fetching users',
error: process.env.NODE_ENV === 'development' ? error.message : undefined
});
}
});
/**
* @route GET /api/users/:id
* @desc Get a user by ID
* @access Private
*/
router.get('/:id', authenticate, async (req, res) => {
try {
// Users can only access their own data unless they're an admin
if (req.params.id !== req.user.id && req.user.role !== 'admin') {
return res.status(403).json({
success: false,
message: 'Access denied'
});
}
const user = await User.findById(req.params.id).select('-password');
if (!user) {
return res.status(404).json({
success: false,
message: 'User not found'
});
}
res.json({
success: true,
data: user
});
} catch (error) {
logger.error('Error fetching user:', error);
res.status(500).json({
success: false,
message: 'Error fetching user',
error: process.env.NODE_ENV === 'development' ? error.message : undefined
});
}
});
/**
* @route PUT /api/users/:id
* @desc Update a user
* @access Private
*/
router.put('/:id', authenticate, async (req, res) => {
try {
// Users can only update their own data unless they're an admin
if (req.params.id !== req.user.id && req.user.role !== 'admin') {
return res.status(403).json({
success: false,
message: 'Access denied'
});
}
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({
success: false,
message: 'User not found'
});
}
const { firstName, lastName, email } = req.body;
// Update fields if provided
if (firstName) user.firstName = firstName;
if (lastName) user.lastName = lastName;
if (email) {
// Check if email already exists
const existingUser = await User.findOne({ email });
if (existingUser && existingUser._id.toString() !== req.params.id) {
return res.status(400).json({
success: false,
message: 'Email already in use'
});
}
user.email = email;
}
// Only admins can update these fields
if (req.user.role === 'admin') {
const { role, isActive } = req.body;
if (role) user.role = role;
if (isActive !== undefined) user.isActive = isActive;
}
await user.save();
// Don't return the password
user.password = undefined;
res.json({
success: true,
message: 'User updated successfully',
data: user
});
} catch (error) {
logger.error('Error updating user:', error);
res.status(500).json({
success: false,
message: 'Error updating user',
error: process.env.NODE_ENV === 'development' ? error.message : undefined
});
}
});
/**
* @route PUT /api/users/:id/password
* @desc Update a user's password
* @access Private
*/
router.put('/:id/password', authenticate, async (req, res) => {
try {
// Users can only update their own password unless they're an admin
if (req.params.id !== req.user.id && req.user.role !== 'admin') {
return res.status(403).json({
success: false,
message: 'Access denied'
});
}
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({
success: false,
message: 'User not found'
});
}
const { currentPassword, newPassword } = req.body;
// Admin can change password without current password
if (req.user.role !== 'admin') {
// Verify current password
if (!currentPassword) {
return res.status(400).json({
success: false,
message: 'Current password is required'
});
}
const isMatch = await user.comparePassword(currentPassword);
if (!isMatch) {
return res.status(401).json({
success: false,
message: 'Current password is incorrect'
});
}
}
// Validate new password
if (!newPassword || newPassword.length < 8) {
return res.status(400).json({
success: false,
message: 'New password must be at least 8 characters long'
});
}
// Update password
user.password = newPassword;
await user.save();
res.json({
success: true,
message: 'Password updated successfully'
});
} catch (error) {
logger.error('Error updating password:', error);
res.status(500).json({
success: false,
message: 'Error updating password',
error: process.env.NODE_ENV === 'development' ? error.message : undefined
});
}
});
/**
* @route DELETE /api/users/:id
* @desc Delete a user
* @access Private/Admin
*/
router.delete('/:id', authenticate, authorize(['admin']), async (req, res) => {
try {
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({
success: false,
message: 'User not found'
});
}
await user.remove();
res.json({
success: true,
message: 'User deleted successfully'
});
} catch (error) {
logger.error('Error deleting user:', error);
res.status(500).json({
success: false,
message: 'Error deleting user',
error: process.env.NODE_ENV === 'development' ? error.message : undefined
});
}
});
/**
* @route GET /api/users/profile
* @desc Get current user's profile
* @access Private
*/
router.get('/profile/me', authenticate, async (req, res) => {
try {
const user = await User.findById(req.user.id).select('-password');
if (!user) {
return res.status(404).json({
success: false,
message: 'User not found'
});
}
res.json({
success: true,
data: user
});
} catch (error) {
logger.error('Error fetching profile:', error);
res.status(500).json({
success: false,
message: 'Error fetching profile',
error: process.env.NODE_ENV === 'development' ? error.message : undefined
});
}
});
module.exports = router;