This commit is contained in:
STEINNI
2025-09-11 20:50:34 +00:00
parent 500166b0bc
commit de69b3d4de
18 changed files with 2427 additions and 0 deletions
+242
View File
@@ -0,0 +1,242 @@
module.exports.methods = {
/* Request:
{
"action": "SUB",
"payload" : ["chan1","chan2","unauthorized"]
}
Reply: (returns all active subscriptions after this SUB)
{
"action": "SUB",
"success": true,
"payload" : ["chan1","chan2","wasalreadysubscribed"]
}
*/
action_SUB(action, payload, reqid){
if(!Array.isArray(payload)){
this.sendErr(action, 'Invalid payload', reqid);
return;
};
for(var chan of payload){
if((!chan) || (typeof(chan)!='string')) continue
if(!this.accessRights.canSubscribe(this.userId, this.roles, chan)) continue
// Chat chans are forbidden here
if((chan.substr(0,8) == 'userchans') || (chan.substr(0,9) == 'lobbychans')) continue;
if(!chan.startsWith(this.config.redis.basePrefix)) chan = this.config.redis.basePrefix + chan
if(this.subscriptions.indexOf(chan)<0) {
this.subscriptions.push(chan);
}
if(!(chan in this.rediscnx.subscriptions)) this.rediscnx.subscriptions[chan] = [];
if(this.rediscnx.subscriptions[chan].indexOf(this.uuid)<0) {
this.rediscnx.subscriptions[chan].push(this.uuid);
}
}
let shortChans = this.subscriptions.map(item => (
item.startsWith(this.config.redis.basePrefix) ? item.substr(this.config.redis.basePrefix.length) : item
))
let reply = {
'action': action,
'payload': shortChans,
'success': true,
};
if(reqid) reply.reqid = reqid;
this.send(JSON.stringify(reply));
},
/*
Request:
{
"action":"UNSUB",
"payload" : ["chan1","notsubscribed_chan","mandatory_chan"]
}
reply:
{
"action":"UNSUB",
"success": true,
"payload" : ["chan1"]
}
*/
action_UNSUB(action, payload, reqid){
if(!Array.isArray(payload)){
this.sendErr(action, 'Invalid payload', reqid);
return;
};
for(var chan of payload){
if((!chan) || (typeof(chan)!='string')) continue
if(this.accessRights.isMandatory(this.userId, this.roles, chan)) continue
// Chat chans are forbidden here
if((chan.substr(0,8) == 'userchans') || (chan.substr(0,9) == 'lobbychans')) continue;
if(!chan.startsWith(this.config.redis.basePrefix)) chan = this.config.redis.basePrefix + chan
if(this.subscriptions.indexOf(chan)>-1) {
this.subscriptions.splice(this.subscriptions.indexOf(chan), 1);
}
if((chan in this.rediscnx.subscriptions) && (this.rediscnx.subscriptions[chan].indexOf(this.uuid)>-1)) {
this.rediscnx.subscriptions[chan].splice(this.rediscnx.subscriptions[chan].indexOf(this.uuid), 1) ;
}
}
let shortChans = this.subscriptions.map(item => (
item.startsWith(this.config.redis.basePrefix) ? item.substr(this.config.redis.basePrefix.length) : item
))
let reply = {
'action': action,
'payload': shortChans,
'success': true,
};
if(reqid) reply.reqid = reqid;
this.send(JSON.stringify(reply));
},
/*
Request:
{
"action": "SUBLST",
}
reply:
{
"action": "SUBLST",
"success": true,
"payload" : ["chan1","chan2","mandatory_chan"]
}
*/
action_SUBLST(action, payload, reqid){
let shortChans = this.subscriptions.map(item => (
item.startsWith(this.config.redis.basePrefix) ? item.substr(this.config.redis.basePrefix.length) : item
))
let reply = {
'action': action,
'payload': shortChans,
'success': true,
};
if(reqid) reply.reqid = reqid;
this.send(JSON.stringify(reply));
},
/*
Request:
{
"action": "PUB",
"payload" : { 'chan':'chan1', 'msg':'Hello folks !'}
}
reply:
{
"action": "PUB",
"success": true,
}
*/
async action_PUB(action, payload, reqid){
if((typeof(payload)!='object') || (typeof(payload.chan)!='string') || (typeof(payload.msg)!='string')){
this.sendErr(action, 'Invalid payload', reqid);
if(this.debug) console.log('PUB: Invalid payload')
return;
};
// Chat chans are forbidden here
if((payload.chan.substr(0,8) == 'userchans') || (payload.chan.substr(0,9) == 'lobbychans')){
this.sendErr(action, 'Forbidden chan', reqid);
if(this.debug) console.log('PUB: Forbidden chan')
return;
};
if( (!this.accessRights.canPublish(this.userId, this.roles, payload.chan)) &&
(! this.rediscnx.redPillsUuids.includes(this.uuid)) ) {
this.sendErr(action, 'Unauthorized chan !', reqid);
if(this.debug) console.log('PUB: Unauthorized chan', payload.chan)
return
}
let msgO
try { msgO = JSON.parse(payload.msg) } catch(err) { msgO = {'err':err} }
let histId = null
if(this.rediscnx.isHistorizedChan(payload.chan)) { // historize first to add the histId
let shortChan = payload.chan.startsWith(this.config.redis.basePrefix) ? payload.chan.substr(this.config.redis.basePrefix.length) : payload.chan
histId = await this.rediscnx.redisXadd(this.config.redis.basePrefix+this.config.redis.historizePrefix + shortChan, payload.msg, this.config.redis.historizeMax);
if( !histId) {
this.sendErr(action, 'Could not historize, aborted event publish !', reqid);
console.error(`Could not historize for "${shortChan}", aborted event publish !`)
return
}
msgO.histId = histId
}
msgO.sender = this.userId
try { payload.msg = JSON.stringify(msgO) } catch(err) {payload.msg = `{"err":"${err}}"` }
this.rediscnx.redisPublish(payload.chan, payload.msg)
let reply = {
'action': action,
'payload': null,
'success': true,
};
if(reqid) reply.reqid = reqid;
this.send(JSON.stringify(reply));
},
/*
Request:
{
"action": "CHANHIST",
"payload": {
"chan": "aze",
"from": "123456879-0", //Histid or seconds since epoch
"to": "987654321-1" // Optional
}
}
reply:
{
"action": "CHANHIST",
"success": true,
"payload" : [
"123456879-1": { payload },
"123456885-0": { payload },
"123456890-0": { payload }
]
}
*/
async action_CHANHIST(action, payload, reqid){
if((!payload.channel) || (typeof(payload.channel)!='string') || (!payload.from) || (typeof(payload.from)!='string') || (payload.to && (typeof(payload.to)!='string'))){
this.sendErr(action, 'Invalid payload', reqid)
return
}
if( (!payload.from.match(/^(\d{13,})-(\d+)$/)) && (!payload.from.match(/^(\d{10,})$/)) ){
this.sendErr(action, 'Invalid payload', reqid)
return
}
if(payload.to && (!payload.to.match(/^(\d{13,})-(\d+)$/)) && (!payload.to.match(/^(\d{10,})$/)) ){
this.sendErr(action, 'Invalid payload', reqid)
return
}
if( (!this.accessRights.canSubscribe(this.userId, this.roles, payload.channel)) &&
(! this.rediscnx.redPillsUuids.includes(this.uuid)) ) {
this.sendErr(action, 'Unauthorized channel !', reqid)
return
}
if(!this.rediscnx.isHistorizedChan(payload.channel)){
this.sendErr(action, 'Not an historized channel !', reqid)
return
}
let from = (payload.from.indexOf('-')>-1) ? payload.from : 1000*payload.from
let to = '+'
if(payload.to) to = (payload.to.indexOf('-')>-1) ? payload.to : 1000*payload.to
let streamName = payload.channel.startsWith(this.config.redis.basePrefix) ? this.config.redis.historizePrefix+payload.channel.substr(this.config.redis.basePrefix.length) : this.config.redis.historizePrefix + payload.channel
let respPayload = await this.rediscnx.redisXrange(streamName, from, to);
let reply = {
'action': action,
'payload': respPayload,
'success': true,
};
if(reqid) reply.reqid = reqid;
this.send(JSON.stringify(reply));
},
}