fix(perm): bump token_version on permission change (invalidates JWTs)
setPermission / setUserPermission now bump token_version for affected
users so cached JWTs lose access immediately instead of after expiry.
Aligns with role-change pattern in adminController.updateRole.
Both writes wrapped in db.transaction() so token_version is only bumped
if the permission write itself succeeds.
Also cleaned up inline require('../db/db') calls to use top-level db.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -203,9 +203,15 @@ function setPermission(req, res) {
|
||||
return res.status(400).json({ error: 'Invalid role' });
|
||||
if (!ALL_PERMISSIONS.find(p => p.key === permission && p.role === role))
|
||||
return res.status(400).json({ error: 'Unknown permission' });
|
||||
db.prepare(
|
||||
'INSERT OR REPLACE INTO role_permissions (role, permission, enabled) VALUES (?, ?, ?)'
|
||||
).run(role, permission, enabled ? 1 : 0);
|
||||
db.transaction(() => {
|
||||
db.prepare(
|
||||
'INSERT OR REPLACE INTO role_permissions (role, permission, enabled) VALUES (?, ?, ?)'
|
||||
).run(role, permission, enabled ? 1 : 0);
|
||||
// Invalidate JWTs for all users of that role so the change takes effect immediately
|
||||
db.prepare(
|
||||
'UPDATE users SET token_version = token_version + 1 WHERE role = ?'
|
||||
).run(role);
|
||||
})();
|
||||
res.json({ ok: true });
|
||||
}
|
||||
|
||||
@@ -239,19 +245,19 @@ function getMyPermissions(req, res) {
|
||||
/* ── GET /api/permissions/users/:id ──────────────────────────────────── */
|
||||
function getUserPermissions(req, res) {
|
||||
const uid = Number(req.params.id);
|
||||
const target = require('../db/db').prepare('SELECT id, role FROM users WHERE id = ?').get(uid);
|
||||
const target = db.prepare('SELECT id, role FROM users WHERE id = ?').get(uid);
|
||||
if (!target) return res.status(404).json({ error: 'User not found' });
|
||||
|
||||
seedDefaults();
|
||||
// role-level values
|
||||
const roleRows = require('../db/db').prepare(
|
||||
const roleRows = db.prepare(
|
||||
'SELECT permission, enabled FROM role_permissions WHERE role = ?'
|
||||
).all(target.role);
|
||||
const roleMap = {};
|
||||
for (const r of roleRows) roleMap[r.permission] = r.enabled === 1;
|
||||
|
||||
// user-level overrides
|
||||
const userRows = require('../db/db').prepare(
|
||||
const userRows = db.prepare(
|
||||
'SELECT permission, enabled FROM user_permissions WHERE user_id = ?'
|
||||
).all(uid);
|
||||
const userMap = {};
|
||||
@@ -274,13 +280,19 @@ function getUserPermissions(req, res) {
|
||||
function setUserPermission(req, res) {
|
||||
const uid = Number(req.params.id);
|
||||
const { permission, enabled } = req.body;
|
||||
const target = require('../db/db').prepare('SELECT role FROM users WHERE id = ?').get(uid);
|
||||
const target = db.prepare('SELECT role FROM users WHERE id = ?').get(uid);
|
||||
if (!target) return res.status(404).json({ error: 'User not found' });
|
||||
if (!ALL_PERMISSIONS.find(p => p.key === permission && p.role === target.role))
|
||||
return res.status(400).json({ error: 'Unknown permission for this role' });
|
||||
require('../db/db').prepare(
|
||||
'INSERT OR REPLACE INTO user_permissions (user_id, permission, enabled) VALUES (?, ?, ?)'
|
||||
).run(uid, permission, enabled ? 1 : 0);
|
||||
db.transaction(() => {
|
||||
db.prepare(
|
||||
'INSERT OR REPLACE INTO user_permissions (user_id, permission, enabled) VALUES (?, ?, ?)'
|
||||
).run(uid, permission, enabled ? 1 : 0);
|
||||
// Invalidate existing JWT for this user immediately
|
||||
db.prepare(
|
||||
'UPDATE users SET token_version = token_version + 1 WHERE id = ?'
|
||||
).run(uid);
|
||||
})();
|
||||
res.json({ ok: true });
|
||||
}
|
||||
|
||||
@@ -289,11 +301,11 @@ function resetUserPermissions(req, res) {
|
||||
const uid = Number(req.params.id);
|
||||
const { permission } = req.body; // optional: reset one key
|
||||
if (permission) {
|
||||
require('../db/db').prepare(
|
||||
db.prepare(
|
||||
'DELETE FROM user_permissions WHERE user_id = ? AND permission = ?'
|
||||
).run(uid, permission);
|
||||
} else {
|
||||
require('../db/db').prepare('DELETE FROM user_permissions WHERE user_id = ?').run(uid);
|
||||
db.prepare('DELETE FROM user_permissions WHERE user_id = ?').run(uid);
|
||||
}
|
||||
res.json({ ok: true });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user