tududi/backend/services/execAction.js
antanst b8611d9338 chore(lint): remove unnecessary try/catch and tighten error handling
- Projects: remove superfluous try/catch around toast; keep explicit error path
- AdminUsers/Sidebar/ShareService: keep minimal catch blocks only to ignore non-JSON parse failures, without swallowing errors
- Lint/format pass remains green
2025-09-22 15:20:46 +03:00

88 lines
2.9 KiB
JavaScript

const { sequelize, Action } = require('../models');
const { isAdmin } = require('./rolesService');
const { applyPerms } = require('./applyPerms');
const {
calculateProjectPerms,
calculateTaskPerms,
calculateNotePerms,
calculateAreaPerms,
calculateTagPerms,
} = require('./permissionsCalculators');
async function assertActorCanShare(actorUserId, resourceType, resourceOwnerId) {
if (await isAdmin(actorUserId)) return;
if (resourceOwnerId !== actorUserId) {
const err = new Error('Forbidden');
err.status = 403;
throw err;
}
}
async function execAction(action) {
// action: { verb, actorUserId, targetUserId, resourceType, resourceUid, accessLevel? }
return await sequelize.transaction(async (tx) => {
// Resolve owner id for authorization (basic impl for projects; extend later)
let ownerUserId = null;
if (action.resourceType === 'project') {
const { Project } = require('../models');
const proj = await Project.findOne({
where: { uid: action.resourceUid },
attributes: ['user_id'],
transaction: tx,
lock: tx.LOCK.UPDATE,
});
if (!proj) {
const err = new Error('Resource not found');
err.status = 404;
throw err;
}
ownerUserId = proj.user_id;
}
await assertActorCanShare(
action.actorUserId,
action.resourceType,
ownerUserId
);
const actionRow = await Action.create(
{
actor_user_id: action.actorUserId,
verb: action.verb,
resource_type: action.resourceType,
resource_uid: action.resourceUid,
target_user_id: action.targetUserId,
access_level: action.accessLevel || null,
metadata: null,
},
{ transaction: tx }
);
let changes = { upserts: [], deletes: [] };
const ctx = { tx };
if (action.resourceType === 'project') {
changes = await calculateProjectPerms(ctx, action);
} else if (action.resourceType === 'task') {
changes = await calculateTaskPerms(ctx, action);
} else if (action.resourceType === 'note') {
changes = await calculateNotePerms(ctx, action);
} else if (action.resourceType === 'area') {
changes = await calculateAreaPerms(ctx, action);
} else if (action.resourceType === 'tag') {
changes = await calculateTagPerms(ctx, action);
}
// Attach source_action_id
changes.upserts = changes.upserts.map((u) => ({
...u,
source_action_id: actionRow.id,
}));
await applyPerms(tx, changes);
return actionRow.id;
});
}
module.exports = { execAction };