4.1.3
This commit is contained in:
35
middlewares/auditLogger.js
Normal file
35
middlewares/auditLogger.js
Normal file
@@ -0,0 +1,35 @@
|
||||
const AuditLog = require('../models/AuditLogModel')
|
||||
|
||||
const SENSITIVE_KEYS = new Set(['password', 'new_password', 'token', 'otp'])
|
||||
const WRITE_METHODS = new Set(['POST', 'PUT', 'PATCH', 'DELETE'])
|
||||
|
||||
function sanitizeBody(body) {
|
||||
if (!body || typeof body !== 'object') return null
|
||||
const clone = {}
|
||||
for (const [key, value] of Object.entries(body)) {
|
||||
clone[key] = SENSITIVE_KEYS.has(key) ? '[hidden]' : value
|
||||
}
|
||||
return clone
|
||||
}
|
||||
|
||||
// باید بعد از adminAuth بیاد (به req.admin نیاز داره). فقط متدهای نوشتاری رو ثبت
|
||||
// میکنه — GET یعنی فقط دیدن، نه یه «کار انجامشده» که نیاز به تاریخچه داشته باشه
|
||||
module.exports = function auditLogger(req, res, next) {
|
||||
if (!WRITE_METHODS.has(req.method)) return next()
|
||||
|
||||
res.on('finish', () => {
|
||||
if (!req.admin) return
|
||||
AuditLog.create({
|
||||
adminId: req.admin._id,
|
||||
adminUserName: req.admin.user_name,
|
||||
method: req.method,
|
||||
path: req.originalUrl,
|
||||
statusCode: res.statusCode,
|
||||
body: sanitizeBody(req.body)
|
||||
}).catch((err) => {
|
||||
console.error('[auditLogger] failed to write audit log:', err.message)
|
||||
})
|
||||
})
|
||||
|
||||
next()
|
||||
}
|
||||
19
middlewares/requirePermission.js
Normal file
19
middlewares/requirePermission.js
Normal file
@@ -0,0 +1,19 @@
|
||||
// باید بعد از adminAuth بیاد (به req.admin نیاز داره). super_admin همیشه رد میشه؛
|
||||
// staff فقط اگه key توی permissions خودش باشه
|
||||
module.exports = function requirePermission(key) {
|
||||
return (req, res, next) => {
|
||||
const admin = req.admin
|
||||
if (!admin) {
|
||||
return res.status(401).send({ status: 'error', code: 401, message: 'Access Denied' })
|
||||
}
|
||||
if (admin.role === 'super_admin') return next()
|
||||
if (Array.isArray(admin.permissions) && admin.permissions.includes(key)) {
|
||||
return next()
|
||||
}
|
||||
return res.status(403).send({
|
||||
status: 'error',
|
||||
code: 403,
|
||||
message: 'شما دسترسی لازم برای این بخش را ندارید'
|
||||
})
|
||||
}
|
||||
}
|
||||
13
middlewares/requireSuperAdmin.js
Normal file
13
middlewares/requireSuperAdmin.js
Normal file
@@ -0,0 +1,13 @@
|
||||
// مدیریت کاربران پنل (ساخت/حذف/تغییرِ دسترسیِ ادمینهای دیگه) همیشه فقط برای
|
||||
// super_admin مجازه — حتی اگه یهجوری کلید 'user-management' به یه staff داده بشه،
|
||||
// این جلوی افزایشِ خودسرانهی دسترسی (privilege escalation) رو میگیره
|
||||
module.exports = function requireSuperAdmin(req, res, next) {
|
||||
if (req.admin?.role !== 'super_admin') {
|
||||
return res.status(403).send({
|
||||
status: 'error',
|
||||
code: 403,
|
||||
message: 'فقط سوپرادمین به این بخش دسترسی دارد'
|
||||
})
|
||||
}
|
||||
next()
|
||||
}
|
||||
Reference in New Issue
Block a user