tududi/backend/services/applyPerms.js
antanst e58ea08b7b Introduce RBAC scaffolding (roles, permissions, actions) and admin/shares endpoints.
Adds initial models, migrations, and services to support role-based access and sharing; wires routes to prepare for permission-driven features.
2025-09-22 15:20:46 +03:00

45 lines
1.6 KiB
JavaScript

const { sequelize } = require('../models');
function maxAccess(a, b) {
if (a === 'rw' || b === 'rw') return 'rw';
if (a === 'ro' || b === 'ro') return 'ro';
return 'none';
}
async function applyPerms(tx, changes) {
const { Permission } = require('../models');
const upserts = changes.upserts || [];
const deletes = changes.deletes || [];
// Upserts: for SQLite we can emulate ON CONFLICT with find+create/update in tx
for (const u of upserts) {
const where = { user_id: u.userId, resource_type: u.resourceType, resource_uid: u.resourceUid };
const existing = await Permission.findOne({ where, transaction: tx, lock: tx.LOCK.UPDATE });
if (existing) {
const nextLevel = maxAccess(existing.access_level, u.accessLevel);
await existing.update({
access_level: nextLevel,
propagation: u.propagation || existing.propagation,
granted_by_user_id: u.grantedByUserId,
source_action_id: u.sourceActionId || existing.source_action_id || null,
}, { transaction: tx });
} else {
await Permission.create({
user_id: u.userId,
resource_type: u.resourceType,
resource_uid: u.resourceUid,
access_level: u.accessLevel,
propagation: u.propagation || 'direct',
granted_by_user_id: u.grantedByUserId,
source_action_id: u.sourceActionId || null,
}, { transaction: tx });
}
}
// Deletes
for (const d of deletes) {
await Permission.destroy({ where: { user_id: d.userId, resource_type: d.resourceType, resource_uid: d.resourceUid }, transaction: tx });
}
}
module.exports = { applyPerms };