- Move client storage to the Node-RED user directory.
- Remove mention of Device ID being required for encryption (since it can now auto generate if not provided this could make people think they have to set it when that isn't the case) - matrix-js-sdk updated from ^v15.3.0 to ^v15.5.0 - got updated from ^11.8.2 to ^12.0.1 (this also required us to change how we import this library in code) - Node-RED version requirement added for >=v1.3.0 - NodeJS version requirement added for >=v14.0.0 - removed `process` dependency - send-image node fixed so error doesn't get thrown (`matrix-js-sdk` updated causing some errors) - updated send-image node docs to explain that msg.contentType is necessary for some clients to render the image (otherwise it could display as a blank message in the room). - If a matrix server configuration node was missing it's User ID it would throw a TypeError instead of telling the user the actual issue. - Updated user list example: it now paginates all users on the server (if you had a lot of users the message would fail to send because it was too large) - Added example for creating a room and inviting a user - Added example for joining a mentioned room - Added example for listing out a user's or server's rooms - Added example for getting session data from a user via whois info - Added example for getting a room's user list - Added example for downloading & storing received files/images - Added example for kicking/banning user from a room. - Added example for deactivating a user - Removed message in the room-users config stating it only works if you are an admin - Receive node now outputs `msg.filename` for files and images
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
module.exports = function(RED) {
|
||||
const got = require('got');
|
||||
const crypto = require('isomorphic-webcrypto');
|
||||
|
||||
function MatrixDecryptFile(n) {
|
||||
@@ -10,6 +9,8 @@ module.exports = function(RED) {
|
||||
this.name = n.name;
|
||||
|
||||
node.on("input", async function (msg) {
|
||||
const { got } = await import('got');
|
||||
|
||||
if(!msg.type) {
|
||||
node.error('msg.type is required.');
|
||||
return;
|
||||
|
||||
@@ -204,6 +204,11 @@
|
||||
</li>
|
||||
|
||||
<li><code>msg.type</code> == '<strong>m.file</strong>'
|
||||
<dl class="message-properties">
|
||||
<dt>msg.filename <span class="property-type">string</span></dt>
|
||||
<dd>the file's parsed filename</dd>
|
||||
</dl>
|
||||
|
||||
<dl class="message-properties">
|
||||
<dt>msg.url <span class="property-type">string</span></dt>
|
||||
<dd>the file's URL</dd>
|
||||
@@ -216,6 +221,11 @@
|
||||
</li>
|
||||
|
||||
<li><code>msg.type</code> == '<strong>m.image</strong>'
|
||||
<dl class="message-properties">
|
||||
<dt>msg.filename <span class="property-type">string</span></dt>
|
||||
<dd>the image's parsed filename</dd>
|
||||
</dl>
|
||||
|
||||
<dl class="message-properties">
|
||||
<dt>msg.url <span class="property-type">string</span></dt>
|
||||
<dd>the image's URL</dd>
|
||||
|
||||
@@ -62,6 +62,7 @@ module.exports = function(RED) {
|
||||
|
||||
case 'm.file':
|
||||
if(!node.acceptFiles) return;
|
||||
msg.filename = msg.content.filename || msg.content.body;
|
||||
if(msg.encrypted) {
|
||||
msg.url = node.server.matrixClient.mxcUrlToHttp(msg.content.file.url);
|
||||
msg.mxc_url = msg.content.file.url;
|
||||
@@ -73,7 +74,7 @@ module.exports = function(RED) {
|
||||
|
||||
case 'm.image':
|
||||
if(!node.acceptImages) return;
|
||||
|
||||
msg.filename = msg.content.filename || msg.content.body;
|
||||
if(msg.encrypted) {
|
||||
msg.url = node.server.matrixClient.mxcUrlToHttp(msg.content.file.url);
|
||||
msg.mxc_url = msg.content.file.url;
|
||||
|
||||
@@ -31,9 +31,6 @@
|
||||
<label for="node-input-server"><i class="fa fa-user"></i> Room Id</label>
|
||||
<input type="text" id="node-input-roomId" placeholder="msg.topic">
|
||||
</div>
|
||||
<div class="form-tips">
|
||||
This only works on Synapse servers. The user also must be an administrator.
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/html" data-help-name="matrix-room-users">
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
<script type="text/html" data-help-name="matrix-send-image">
|
||||
<h3>Details</h3>
|
||||
<p>This node will send an image to a Matrix chat room. Supports direct linking to a File In node.</p>
|
||||
<p>This node will send an image to a Matrix chat room. Supports direct linking to a File In node. It's recommended you set <code>msg.contentType</code> so the client knows how to render the image (otherwise the image could show blank).</p>
|
||||
|
||||
<h3>Inputs</h3>
|
||||
<dl class="message-properties">
|
||||
|
||||
@@ -72,20 +72,28 @@ module.exports = function(RED) {
|
||||
})
|
||||
.then(function(file){
|
||||
node.server.matrixClient
|
||||
.sendImageMessage(msg.topic, file.content_uri, {}, (msg.body || msg.filename) || "")
|
||||
.sendImageMessage(
|
||||
msg.topic,
|
||||
file.content_uri,
|
||||
{},
|
||||
(msg.body || msg.filename) || null,
|
||||
null
|
||||
)
|
||||
.then(function(e) {
|
||||
node.log("Image message sent: " + e);
|
||||
msg.eventId = e.event_id;
|
||||
msg.content_uri_mxc = file.content_uri;
|
||||
msg.content_uri = node.server.matrixClient.mxcUrlToHttp(file.content_uri);
|
||||
node.send([msg, null]);
|
||||
})
|
||||
.catch(function(e){
|
||||
node.warn("Error sending image message " + e);
|
||||
node.warn("Error sending image message: " + e);
|
||||
msg.error = e;
|
||||
node.send([null, msg]);
|
||||
});
|
||||
})
|
||||
.catch(function(e){
|
||||
node.warn("Error uploading image message " + e);
|
||||
node.warn("Error uploading image message: " + e);
|
||||
msg.error = e;
|
||||
node.send([null, msg]);
|
||||
});
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
style="width: auto; margin-left: 125px; vertical-align: top"
|
||||
/>
|
||||
<label for="node-config-input-enableE2ee" style="width: auto;max-width:50%;">
|
||||
Enable end-to-end encryption (requires a Device ID to be set.)
|
||||
Enable end-to-end encryption
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
global.Olm = require('olm');
|
||||
const fs = require("fs-extra");
|
||||
const sdk = require("matrix-js-sdk");
|
||||
const { resolve } = require('path');
|
||||
const { LocalStorage } = require('node-localstorage');
|
||||
const { LocalStorageCryptoStore } = require('matrix-js-sdk/lib/crypto/store/localStorage-crypto-store');
|
||||
|
||||
@@ -10,19 +11,17 @@ module.exports = function(RED) {
|
||||
}
|
||||
|
||||
function MatrixServerNode(n) {
|
||||
let storageDir = './matrix-client-storage';
|
||||
|
||||
let node = this,
|
||||
storageDir = RED.settings.userDir + '/matrix-client-storage';
|
||||
RED.nodes.createNode(this, n);
|
||||
node.setMaxListeners(1000);
|
||||
|
||||
let node = this;
|
||||
node.log("Initializing Matrix Server Config node");
|
||||
|
||||
if(!this.credentials) {
|
||||
this.credentials = {};
|
||||
}
|
||||
|
||||
node.setMaxListeners(1000);
|
||||
|
||||
this.connected = null;
|
||||
this.name = n.name;
|
||||
this.userId = this.credentials.userId;
|
||||
@@ -34,6 +33,12 @@ module.exports = function(RED) {
|
||||
this.e2ee = (this.enableE2ee && this.deviceId);
|
||||
this.globalAccess = n.global;
|
||||
this.initializedAt = new Date();
|
||||
|
||||
if(!this.userId) {
|
||||
node.log("Matrix connection failed: missing user ID in configuration.");
|
||||
return;
|
||||
}
|
||||
|
||||
let localStorageDir = storageDir + '/' + MatrixFolderNameFromUserId(this.userId),
|
||||
localStorage = new LocalStorage(localStorageDir),
|
||||
initialSetup = false;
|
||||
@@ -41,11 +46,9 @@ module.exports = function(RED) {
|
||||
let retryStartTimeout = null;
|
||||
|
||||
if(!this.credentials.accessToken) {
|
||||
node.log("Matrix connection failed: missing access token.");
|
||||
node.error("Matrix connection failed: missing access token in configuration.");
|
||||
} else if(!this.url) {
|
||||
node.log("Matrix connection failed: missing server URL.");
|
||||
} else if(!this.userId) {
|
||||
node.log("Matrix connection failed: missing user ID.");
|
||||
node.error("Matrix connection failed: missing server URL in configuration.");
|
||||
} else {
|
||||
node.setConnected = function(connected, cb) {
|
||||
if (node.connected !== connected) {
|
||||
@@ -296,7 +299,6 @@ module.exports = function(RED) {
|
||||
// httpStatus: 401
|
||||
// }
|
||||
|
||||
console.log("Authentication failure: ", errorObj);
|
||||
node.error("Authentication failure: " + errorObj);
|
||||
stopClient();
|
||||
});
|
||||
@@ -392,7 +394,8 @@ module.exports = function(RED) {
|
||||
});
|
||||
|
||||
function upgradeDirectoryIfNecessary(node, storageDir) {
|
||||
let oldStorageDir = './matrix-local-storage';
|
||||
let oldStorageDir = './matrix-local-storage',
|
||||
oldStorageDir2 = './matrix-client-storage';
|
||||
|
||||
// if the old storage location exists lets move it to it's new location
|
||||
if(fs.pathExistsSync(oldStorageDir)){
|
||||
@@ -415,6 +418,18 @@ module.exports = function(RED) {
|
||||
node.log("archiving old config folder '" + oldStorageDir + "' to '" + oldStorageDir + "-backup");
|
||||
fs.renameSync(oldStorageDir, oldStorageDir + "-backup");
|
||||
}
|
||||
|
||||
if(RED.settings.userDir !== resolve('./')) {
|
||||
// user directory does not match running directory
|
||||
// check if we stored stuff in wrong directory and move it
|
||||
if(fs.pathExistsSync(oldStorageDir2)){
|
||||
fs.ensureDirSync(storageDir);
|
||||
node.log("found old '" + oldStorageDir2 + "' path, copying to new location '" + storageDir);
|
||||
fs.copySync(oldStorageDir2, storageDir);
|
||||
// rename folder to keep as a backup (and so we don't run again)
|
||||
fs.renameSync(oldStorageDir2, oldStorageDir2 + "-backup");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
module.exports = function(RED) {
|
||||
const got = require("got");
|
||||
const utf8 = require('utf8');
|
||||
const crypto = require('crypto');
|
||||
|
||||
@@ -22,7 +21,8 @@ module.exports = function(RED) {
|
||||
return;
|
||||
}
|
||||
|
||||
node.on("input", function (msg) {
|
||||
node.on("input", async function (msg) {
|
||||
const { got } = await import('got');
|
||||
|
||||
if(!msg.payload.username) {
|
||||
node.error("msg.payload.username is required");
|
||||
@@ -34,7 +34,7 @@ module.exports = function(RED) {
|
||||
return;
|
||||
}
|
||||
|
||||
(async () => {
|
||||
await (async () => {
|
||||
try {
|
||||
var response = await got.get(this.server + '/_synapse/admin/v1/register', {
|
||||
responseType: 'json'
|
||||
|
||||
Reference in New Issue
Block a user