feat(access): Фаза 0 — целостность правил доступа + подтверждение массового закрытия

- contentAccess.purgeAccessFor(scope,id) — единая точка очистки content_access
  (нет FK). deleteClass и _deleteUserTx переведены на неё (убрано дублирование).
- Админ-UI: confirm() перед «Закрыть у всех / Закрыть весь» (необратимая массовая
  операция больше не срабатывает мгновенно).
- Новый тест content-access.test.js (9/9): allowlist, ученик>класс, наследование
  главой хаба, admin/teacher bypass, allowedRefs/filterTextbooks, purgeAccessFor,
  чистка правил при DELETE класса. Полный backend-набор: 203/206 (3 — baseline Auth).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-06-03 12:39:08 +03:00
parent edb98895df
commit 1bbddc00c8
5 changed files with 126 additions and 4 deletions
+3 -2
View File
@@ -3,6 +3,7 @@ const crypto = require('crypto');
const { onClassJoined } = require('./gamificationController');
const { pushNotif } = require('../utils/notifications');
const { stripTags } = require('../utils/sanitize');
const { purgeAccessFor } = require('../services/contentAccess');
function genCode() {
return crypto.randomBytes(4).toString('hex').toUpperCase();
@@ -324,8 +325,8 @@ function deleteClass(req, res) {
if (req.user.role !== 'admin' && cls.teacher_id !== req.user.id)
return res.status(403).json({ error: 'Forbidden' });
stmts.deleteClass.run(req.params.id);
// Правила доступа к контенту для этого класса (нет FK — чистим вручную):
db.prepare("DELETE FROM content_access WHERE scope = 'class' AND target_id = ?").run(req.params.id);
// Правила доступа к контенту для этого класса (нет FK — единая чистка):
purgeAccessFor('class', req.params.id);
res.json({ ok: true });
}