fix(features): админ-оверрайд в requireFeature — API отключённого модуля 404-ил админа
Симптом: collection выключен, админ открывал страницу (фронтовый админ-оверрайд), но GET /api/collection отдавал 404 — requireFeature 404-ил всех. requireFeature идёт ДО authMiddleware (req.user нет), поэтому сам декодирую Bearer-токен: если роль admin — пропускаем к API даже выключенного модуля. Для student/teacher всё по-прежнему 404 (модуль скрыт). Зеркалит фронтовый _isAdminUser. Чинит ВСЕ отключённые модули для админа, не только коллекцию. Проверено: admin→bypass, student/teacher/нет токена/мусор/чужой секрет→404 (6/6). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,19 @@
|
||||
* if (feats.exam9 === false) { ... }
|
||||
*/
|
||||
const db = require('../db/db');
|
||||
const jwt = require('jsonwebtoken');
|
||||
|
||||
// Админ-оверрайд: requireFeature идёт ДО authMiddleware (req.user ещё нет),
|
||||
// поэтому декодируем Bearer-токен сами — админ открывает и отключённые модули
|
||||
// (зеркалит фронтовый _isAdminUser, см. project_gamification_killswitch).
|
||||
function _isAdminReq(req) {
|
||||
try {
|
||||
const h = req.headers.authorization || '';
|
||||
if (!h.startsWith('Bearer ')) return false;
|
||||
const p = jwt.verify(h.slice(7), process.env.JWT_SECRET, { algorithms: ['HS256'] });
|
||||
return !!(p && p.role === 'admin');
|
||||
} catch (e) { return false; }
|
||||
}
|
||||
|
||||
const _stmtSingle = db.prepare("SELECT value FROM app_settings WHERE key = ?");
|
||||
const _stmtGlobalFeats = db.prepare("SELECT key, value FROM app_settings WHERE key LIKE 'feature_%'");
|
||||
@@ -41,7 +54,7 @@ function requireFeature(name) {
|
||||
const settingKey = `feature_${name}_enabled`;
|
||||
return (req, res, next) => {
|
||||
const row = _stmtSingle.get(settingKey);
|
||||
if (row && row.value === '0') {
|
||||
if (row && row.value === '0' && !_isAdminReq(req)) { // админ проходит к API даже выключенного модуля
|
||||
return res.status(404).json({ error: 'Feature disabled' });
|
||||
}
|
||||
next();
|
||||
|
||||
Reference in New Issue
Block a user