import { replyToAction } from './publishActionReply.js' function matchesActionsChannel(redisCnx, chan, channels) { if(!Array.isArray(channels) || !channels.length) return(false) for(const configured of channels) { if(!configured) continue if(redisCnx.fullChan(configured) === chan) return(true) } return(false) } export async function dispatchActions(redisCnx, msg, chan, rules) { if(!matchesActionsChannel(redisCnx, chan, rules.channels)) return(false) const action = msg.action const sender = msg.sender ?? null const reqid = ('reqid' in msg) ? msg.reqid.substr(0, 50) : null const roles = Array.isArray(msg.roles) ? msg.roles : ['*'] if(!action || typeof(action) !== 'string') { if(!sender) return(true) replyToAction(redisCnx, { action, reqid, sender, success: false, err: 'Missing or invalid action', }) return(true) } if(!sender) { console.warn(`[${redisCnx.redisId}] Action ${action} without sender on ${chan}`) return(true) } if(redisCnx.accessRights && !redisCnx.accessRights.canDo(roles, action, sender)) { replyToAction(redisCnx, { action, reqid, sender, success: false, err: 'Unauthorized action !', }) return(true) } const handler = redisCnx['action_'+action] if(typeof(handler) !== 'function') { replyToAction(redisCnx, { action, reqid, sender, success: false, err: `Unknown action: ${action}`, }) return(true) } if(redisCnx.debug) { console.log(`[${redisCnx.redisId}] Dispatching action ${action} from ${sender}`) } try { await handler.call(redisCnx, action, ('payload' in msg) ? msg.payload : null, reqid, sender, roles) } catch(err) { console.error(`[${redisCnx.redisId}] Action ${action} failed:`, err) replyToAction(redisCnx, { action, reqid, sender, success: false, err: err.message ?? `${action} failed`, }) } return(true) }