- matrix-receive node updated so that msg.sender is msg.userId instead (for better node chaining).

- change all references from msg.roomId to msg.topic to conform to Node-RED standards.
- Added node for listing Synapse users server-wide (as long as the caller is an admin)
- Events for Room.timeline are now handled by the server-config node and node's that listen for it bind a listener to that instead of the matrix client.
- Added kick and ban nodes for kicking/banning from a room
- Added node for fetching synapse user list using synapse admin API
- Added node for fetching whois data from a user using Matrix admin API
- Added node for deactivating users using the Synapse admin API
- Can register users using the Synapse admin endpoint v1 (yay legacy)
- Can add users using the Synapse admin endpoint v2
- Add more info to the readme.
This commit is contained in:
2021-08-18 11:18:29 -06:00
parent cd99955115
commit b33595d5eb
31 changed files with 1874 additions and 109 deletions
+100
View File
@@ -0,0 +1,100 @@
module.exports = function(RED) {
const got = require("got");
const utf8 = require('utf8');
const crypto = require('crypto');
function MatrixSynapseRegister(n) {
RED.nodes.createNode(this, n);
let node = this;
this.name = n.name;
this.server = this.credentials.server;
this.sharedSecret = this.credentials.sharedSecret;
if(!this.server) {
node.error('Server URL must be configured on the node.');
return;
}
if(!this.sharedSecret) {
node.error('Shared registration secret must be configured on the node.');
return;
}
node.on("input", function (msg) {
if(!msg.payload.username) {
node.error("msg.payload.username is required");
return;
}
if(!msg.payload.password) {
node.error("msg.payload.password is required");
return;
}
(async () => {
try {
var response = await got.get(this.server + '/_synapse/admin/v1/register', {
responseType: 'json'
});
} catch (error) {
msg.error = error;
msg.error_extra = 'Failed fetching nonce key from registration endpoint';
delete msg.payload.password;
node.status({fill:"red",shape:"ring",text:"Failure"});
node.send([null, msg]);
return;
}
var nonce = response.body.nonce;
if(!nonce) {
node.error('Could not get nonce from /_synapse/admin/v1/register');
return;
}
let hmac = crypto.createHmac("sha1", node.sharedSecret )
.update(utf8.encode(nonce))
.update("\x00")
.update(utf8.encode(msg.payload.username))
.update("\x00")
.update(utf8.encode(msg.payload.password))
.update("\x00")
.update(msg.payload.admin ? "admin" : "notadmin")
.digest('hex');
try {
response = await got.post(this.server + '/_synapse/admin/v1/register', {
json: {
"nonce": nonce,
"username": msg.payload.username,
"password": msg.payload.password,
"mac": hmac,
"admin": msg.payload.admin || false,
"user_type": msg.payload.user_type || null,
},
responseType: 'json'
});
} catch (error) {
msg.error = error;
msg.error_extra = 'Failed submitting registration request';
delete msg.payload.password;
node.status({fill:"red",shape:"ring",text:"Failure"});
node.send([null, msg]);
return;
}
node.status({fill:"green",shape:"dot",text:"Registered: " + msg.payload.username});
msg.payload = response.body;
node.send(msg);
})();
});
}
RED.nodes.registerType("matrix-synapse-register", MatrixSynapseRegister, {
credentials: {
server: { type:"text", value: null, required: true },
sharedSecret: { type:"text", value: null },
}
});
}