const jwt = require('jsonwebtoken'); const { pool } = require('../config/database'); const JWT_SECRET = require('../config/jwt-secret'); const ROLES = { user: 0, reviewer: 1, radio_admin: 1, admin: 2, super_admin: 3 }; const ROLE_NAMES = { user: '普通用户', reviewer: '审核员', radio_admin: '广播管理员', admin: '管理员', super_admin: '超级管理员' }; const ROLE_PERMISSIONS = { user: [], reviewer: ['posts:review'], radio_admin: ['songs:review', 'songs:delete', 'slots:manage', 'stats:view'], admin: ['posts:review', 'posts:delete', 'songs:review', 'songs:delete', 'slots:manage', 'users:view', 'users:status', 'notices:manage', 'feedbacks:manage'], super_admin: ['posts:review', 'posts:delete', 'songs:review', 'songs:delete', 'slots:manage', 'users:view', 'users:status', 'users:role', 'admin:manage', 'stats:view', 'logs:view', 'notices:manage', 'settings:view', 'feedbacks:manage', 'stories:review', 'post-views:view', 'wechat:review'] }; const auth = async (req, res, next) => { try { const token = req.headers.authorization?.split(' ')[1] || req.cookies?.token; if (!token) { return res.status(401).json({ code: 401, message: '请先登录' }); } const decoded = jwt.verify(token, JWT_SECRET); const [users] = await pool.execute('SELECT id, username, nickname, avatar, role, status FROM users WHERE id = ?', [decoded.id]); if (users.length === 0) { return res.status(401).json({ code: 401, message: '用户不存在' }); } if (users[0].status === 0) { return res.status(403).json({ code: 403, message: '账号已被禁用' }); } req.user = users[0]; req.user.roleName = ROLE_NAMES[users[0].role] || '普通用户'; req.user.permissions = ROLE_PERMISSIONS[users[0].role] || []; next(); } catch (err) { if (err && ['TokenExpiredError', 'JsonWebTokenError', 'NotBeforeError'].includes(err.name)) { return res.status(401).json({ code: 401, message: '登录已过期,请重新登录' }); } console.error('[Auth] 用户状态查询失败:', err && (err.code || err.message)); return res.status(503).json({ code: 503, message: '服务暂时不可用,请稍后重试' }); } }; const optionalAuth = async (req, res, next) => { try { const token = req.headers.authorization?.split(' ')[1] || req.cookies?.token; if (token) { const decoded = jwt.verify(token, JWT_SECRET); const [users] = await pool.execute('SELECT id, username, nickname, avatar, role, status FROM users WHERE id = ?', [decoded.id]); if (users.length > 0 && users[0].status === 1) { req.user = users[0]; req.user.roleName = ROLE_NAMES[users[0].role] || '普通用户'; req.user.permissions = ROLE_PERMISSIONS[users[0].role] || []; } } } catch (err) { } next(); }; const isStaff = (req, res, next) => { if (!req.user || ROLES[req.user.role] < 1) { return res.status(403).json({ code: 403, message: '无管理权限' }); } next(); }; const adminOnly = (req, res, next) => { if (!req.user || ROLES[req.user.role] < 2) { return res.status(403).json({ code: 403, message: '需要管理员权限' }); } next(); }; const superAdminOnly = (req, res, next) => { if (!req.user || req.user.role !== 'super_admin') { return res.status(403).json({ code: 403, message: '需要超级管理员权限' }); } next(); }; const requirePermission = (permission) => { return (req, res, next) => { if (!req.user) { return res.status(401).json({ code: 401, message: '请先登录' }); } if (req.user.role === 'super_admin' || (req.user.permissions && req.user.permissions.includes(permission))) { return next(); } return res.status(403).json({ code: 403, message: '权限不足' }); }; }; function isStaffRole(role) { return role && ROLES[role] >= 1; } module.exports = { auth, optionalAuth, adminOnly, isStaff, superAdminOnly, requirePermission, isStaffRole, ROLES, ROLE_NAMES, ROLE_PERMISSIONS };