162 lines
6.2 KiB
JavaScript
162 lines
6.2 KiB
JavaScript
global.Olm = require('olm');
|
|
|
|
module.exports = function(RED) {
|
|
const sdk = require("matrix-js-sdk");
|
|
const { LocalStorage } = require('node-localstorage');
|
|
const localStorage = new LocalStorage('./matrix-local-storage');
|
|
const { LocalStorageCryptoStore } = require('matrix-js-sdk/lib/crypto/store/localStorage-crypto-store');
|
|
|
|
function MatrixServerNode(n) {
|
|
// we should add support for getting access token automatically from username/password
|
|
// ref: https://matrix.org/docs/guides/usage-of-the-matrix-js-sdk#login-with-an-access-token
|
|
|
|
RED.nodes.createNode(this, n);
|
|
|
|
let node = this;
|
|
node.log("Initializing Matrix Server Config node");
|
|
|
|
if(!this.credentials) {
|
|
this.credentials = {};
|
|
}
|
|
|
|
node.setMaxListeners(1000);
|
|
|
|
this.connected = false;
|
|
this.name = n.name;
|
|
this.userId = this.credentials.userId;
|
|
this.deviceId = this.credentials.deviceId || null;
|
|
this.url = this.credentials.url;
|
|
this.autoAcceptRoomInvites = n.autoAcceptRoomInvites;
|
|
this.enableE2ee = this.credentials.enableE2ee || false;
|
|
this.e2ee = this.enableE2ee && this.deviceId;
|
|
|
|
if(!this.credentials.accessToken) {
|
|
node.log("Matrix connection failed: missing access token.");
|
|
} else if(!this.url) {
|
|
node.log("Matrix connection failed: missing server URL.");
|
|
} else if(!this.userId) {
|
|
node.log("Matrix connection failed: missing user ID.");
|
|
} else {
|
|
node.matrixClient = sdk.createClient({
|
|
baseUrl: this.url,
|
|
accessToken: this.credentials.accessToken,
|
|
sessionStore: new sdk.WebStorageSessionStore(localStorage),
|
|
cryptoStore: new LocalStorageCryptoStore(localStorage),
|
|
userId: this.userId,
|
|
deviceId: this.deviceId || undefined,
|
|
});
|
|
|
|
node.on('close', function(done) {
|
|
if(node.matrixClient) {
|
|
node.matrixClient.close();
|
|
node.matrixClient.stopClient();
|
|
node.setConnected(false);
|
|
}
|
|
|
|
done();
|
|
});
|
|
|
|
node.setConnected = function(connected) {
|
|
if (node.connected !== connected) {
|
|
node.connected = connected;
|
|
if (connected) {
|
|
node.log("Matrix server connection ready.");
|
|
node.emit("connected");
|
|
} else {
|
|
node.emit("disconnected");
|
|
}
|
|
}
|
|
};
|
|
|
|
node.isConnected = function() {
|
|
return node.connected;
|
|
};
|
|
|
|
node.matrixClient.on("Room.timeline", async function(event, room, toStartOfTimeline, data) {
|
|
node.emit("Room.timeline", event, room, toStartOfTimeline, data);
|
|
});
|
|
|
|
// node.matrixClient.on("RoomMember.typing", async function(event, member) {
|
|
// let isTyping = member.typing;
|
|
// let roomId = member.roomId;
|
|
// });
|
|
|
|
// node.matrixClient.on("RoomMember.powerLevel", async function(event, member) {
|
|
// let newPowerLevel = member.powerLevel;
|
|
// let newNormPowerLevel = member.powerLevelNorm;
|
|
// let roomId = member.roomId;
|
|
// });
|
|
|
|
// node.matrixClient.on("RoomMember.name", async function(event, member) {
|
|
// let newName = member.name;
|
|
// let roomId = member.roomId;
|
|
// });
|
|
|
|
// handle auto-joining rooms
|
|
node.matrixClient.on("RoomMember.membership", async function(event, member) {
|
|
if (member.membership === "invite" && member.userId === node.userId) {
|
|
if(node.autoAcceptRoomInvites) {
|
|
node.matrixClient.joinRoom(member.roomId).then(function() {
|
|
node.log("Automatically accepted invitation to join room " + member.roomId);
|
|
}).catch(function(e) {
|
|
node.warn("Cannot join room (could be from being kicked/banned) " + member.roomId + ": " + e);
|
|
});
|
|
} else {
|
|
node.log("Got invite to join room " + member.roomId);
|
|
}
|
|
}
|
|
});
|
|
|
|
node.matrixClient.on("sync", async function(state, prevState, data) {
|
|
switch (state) {
|
|
case "ERROR":
|
|
node.error("Connection to Matrix server lost");
|
|
node.setConnected(false);
|
|
break;
|
|
|
|
case "RECONNECTING":
|
|
case "STOPPED":
|
|
node.setConnected(false);
|
|
break;
|
|
|
|
case "SYNCING":
|
|
break;
|
|
|
|
case "PREPARED":
|
|
node.setConnected(true);
|
|
break;
|
|
|
|
// case "PREPARED":
|
|
// // the client instance is ready to be queried.
|
|
// node.log("Matrix server connection ready.");
|
|
// node.setConnected(true);
|
|
// break;
|
|
}
|
|
});
|
|
|
|
async function run() {
|
|
if(node.e2ee){
|
|
node.matrixClient.initCrypto()
|
|
.catch((error) => node.error(error));
|
|
node.matrixClient.setGlobalErrorOnUnknownDevices(false);
|
|
}
|
|
|
|
node.matrixClient.startClient({ initialSyncLimit: 8 })
|
|
.catch((error) => node.error(error));
|
|
}
|
|
|
|
node.log("Connecting to Matrix server...");
|
|
run().catch((error) => node.error(error));
|
|
}
|
|
}
|
|
|
|
RED.nodes.registerType("matrix-server-config", MatrixServerNode, {
|
|
credentials: {
|
|
userId: { type:"text", required: true },
|
|
accessToken: { type:"text", required: true },
|
|
deviceId: { type: "text", required: true },
|
|
enableE2ee: { type: "checkbox", value: true },
|
|
url: { type: "text", required: true },
|
|
}
|
|
});
|
|
} |