auth.middleware.js•2.42 kB
const jwt = require('jsonwebtoken');
const User = require('../models/user.model');
const config = require('../config/config');
const { logger } = require('../utils/logger');
/**
* Middleware to authenticate requests using JWT
*/
exports.authenticate = async (req, res, next) => {
try {
// Get token from header
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({
success: false,
message: 'No token provided'
});
}
const token = authHeader.split(' ')[1];
// Verify token
const decoded = jwt.verify(token, config.jwt.secret);
// Find user
const user = await User.findById(decoded.id).select('-password');
if (!user) {
return res.status(404).json({
success: false,
message: 'User not found'
});
}
// Check if user is active
if (!user.isActive) {
return res.status(403).json({
success: false,
message: 'Account is disabled'
});
}
// Attach user to request
req.user = {
id: user._id,
username: user.username,
email: user.email,
role: user.role
};
next();
} catch (error) {
if (error.name === 'JsonWebTokenError') {
return res.status(401).json({
success: false,
message: 'Invalid token'
});
} else if (error.name === 'TokenExpiredError') {
return res.status(401).json({
success: false,
message: 'Token expired'
});
}
logger.error('Authentication error:', error);
return res.status(500).json({
success: false,
message: 'Authentication error',
error: process.env.NODE_ENV === 'development' ? error.message : undefined
});
}
};
/**
* Middleware to authorize requests based on user role
* @param {string[]} roles - Array of allowed roles
*/
exports.authorize = (roles = []) => {
// Convert string to array if only one role is passed
if (typeof roles === 'string') {
roles = [roles];
}
return (req, res, next) => {
// Check if user exists and has a role in the allowed roles
if (!req.user || (roles.length && !roles.includes(req.user.role))) {
return res.status(403).json({
success: false,
message: 'Insufficient permissions'
});
}
next();
};
};