Files
node-red-contrib-matrix-chat/src/matrix-synapse-register.js
T
skylord123 25c92b787a - Messages used to get ignored if they were over 1 second old. This caused issues with messages being ignored on servers that took longer than a second to respond (*cough* matrix.org *cough*). Now it accepts all new messages. Moving forward any messages that are sent before Node-RED starts or gets deployed will be ignored (so that old messages don't pop up since the cache clears every deploy/node-red restart so old messages look like new ones).
- When the matrix-server node would shut down (from a deployment) it wasn't properly shutting the old instance of the client down. This would cause messages to start duplicating X times (X being however many times you deployed since you last started Node-RED). This is now fixed.
- Upgraded to matrix-js-sdk 15.3.0
- Message processing is now done on the matrix-server node. Before if you had multiple matrix-receive nodes it would output one line per matrix-receive node into the log. Now it only outputs from the matrix-server node. Note that all messages get logged that are sent to rooms the bot is in whereas before it would only log message in rooms the matrix-receive node was in.
- Fixed Shared secret registration failing if user_type was defined.
2022-01-14 12:56:14 -07:00

106 lines
3.8 KiB
JavaScript

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")
if(msg.payload.user_type || null) {
hmac.update("\x00")
.update(msg.payload.user_type);
}
hmac = hmac.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 },
}
});
}