feat(perm): audit log for permission + feature-flag changes

Adds audit entries for:
- permission.set (role-level change)
- permission.user_set (per-user override)
- permission.user_reset (clear user override)
- feature.update (global feature flag toggle, per-key with old->new diff)

Old value captured for feature.update for full diff trail.
permissionsController: added audit import, wired audit() after each write.
adminController.updateFeatures: replaced bulk audit with per-key entries
capturing old value from app_settings before overwrite.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-05-17 14:16:45 +03:00
parent dd1adc0c69
commit 539d33df31
2 changed files with 11 additions and 4 deletions
@@ -1,4 +1,5 @@
const db = require('../db/db');
const { audit } = require('../utils/audit');
/* ── All known permissions ─────────────────────────────────────────────── */
const ALL_PERMISSIONS = [
@@ -212,6 +213,7 @@ function setPermission(req, res) {
'UPDATE users SET token_version = token_version + 1 WHERE role = ?'
).run(role);
})();
audit(req, 'permission.set', `role:${role}/${permission}`, `enabled=${enabled ? 1 : 0}`);
res.json({ ok: true });
}
@@ -293,6 +295,7 @@ function setUserPermission(req, res) {
'UPDATE users SET token_version = token_version + 1 WHERE id = ?'
).run(uid);
})();
audit(req, 'permission.user_set', `user:${uid}/${permission}`, `enabled=${enabled ? 1 : 0}`);
res.json({ ok: true });
}
@@ -307,6 +310,7 @@ function resetUserPermissions(req, res) {
} else {
db.prepare('DELETE FROM user_permissions WHERE user_id = ?').run(uid);
}
audit(req, 'permission.user_reset', `user:${uid}`, permission || null);
res.json({ ok: true });
}