File size: 2,578 Bytes
c2efbe6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | const jwt = require('jsonwebtoken');
const Admin = require('../models/adminModel');
const asyncHandler = require('express-async-handler');
const protectAdmin = asyncHandler(async (req, res, next) => {
let token;
if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) {
try {
token = req.headers.authorization.split(' ')[1];
const decoded = jwt.verify(token, process.env.JWT_SECRET_KEY);
const admin = await Admin.findById(decoded.id).select('-password');
if (!admin) {
res.status(401);
throw new Error('Admin not found');
}
if (!admin.isActive) {
res.status(401);
throw new Error('Admin account is deactivated');
}
req.admin = admin;
next();
} catch (error) {
res.status(401);
throw new Error('Not authorized, token failed');
}
}
if (!token) {
res.status(401);
throw new Error('Not authorized, no token');
}
});
const requirePermission = (resource, action) => {
return (req, res, next) => {
if (!req.admin) {
res.status(401);
throw new Error('Authentication required');
}
if (!req.admin.hasPermission(resource, action)) {
res.status(403);
throw new Error(`Insufficient permissions: ${resource}.${action}`);
}
next();
};
};
const requireRole = (roles) => {
return (req, res, next) => {
if (!req.admin) {
res.status(401);
throw new Error('Authentication required');
}
const allowedRoles = Array.isArray(roles) ? roles : [roles];
if (!allowedRoles.includes(req.admin.role)) {
res.status(403);
throw new Error(`Insufficient role. Required: ${allowedRoles.join(' or ')}`);
}
next();
};
};
const logAdminActivity = (action, description) => {
return (req, res, next) => {
const originalSend = res.send;
res.send = function(data) {
if (req.admin && res.statusCode < 400) {
const activityLog = {
action,
description,
ipAddress: req.ip || req.connection.remoteAddress,
userAgent: req.get('User-Agent'),
timestamp: new Date()
};
Admin.findByIdAndUpdate(
req.admin._id,
{ $push: { activityLog: activityLog } },
{ new: true }
).catch(err => console.error('Failed to log admin activity:', err));
}
originalSend.call(this, data);
};
next();
};
};
module.exports = {
protectAdmin,
requirePermission,
requireRole,
logAdminActivity
}; |