diff --git a/package.json b/package.json
index ac968ff..1632efd 100644
--- a/package.json
+++ b/package.json
@@ -33,7 +33,8 @@
"matrix-synapse-join-room": "src/matrix-synapse-join-room.js",
"matrix-whois-user": "src/matrix-whois-user.js",
"matrix-room-users": "src/matrix-room-users.js",
- "matrix-device-verify": "src/matrix-device-verify.js"
+ "matrix-device-verify": "src/matrix-device-verify.js",
+ "matrix-secret-storage": "src/matrix-secret-storage.js"
}
},
"engines": {
diff --git a/src/matrix-device-verify.js b/src/matrix-device-verify.js
index e86c93c..41f01ed 100644
--- a/src/matrix-device-verify.js
+++ b/src/matrix-device-verify.js
@@ -39,13 +39,14 @@ module.exports = function(RED) {
* rejected.
*/
node.server.matrixClient.on("crypto.verification.request", async function(data){
- console.log("[######### crypto.verification.request #########]");
+ console.log("[######### crypto.verification.request #########]", data.phase, data.methods);
if(data.isSelfVerification) {
- if(data.requested && data.methods) {
+ if(data.requested || true) {
let verifyRequestId = data.targetDevice.userId + ':' + data.targetDevice.deviceId;
verificationRequests.set(verifyRequestId, data);
node.send({
- verifyRequestId: verifyRequestId, // internally used to reference between nodes
+ verifyRequestId: verifyRequestId, // internally used to reference between nodesc
+ verifyMethods: data.methods,
userId: data.targetDevice.userId,
deviceId: data.targetDevice.deviceId,
type: 'crypto.verification.request',
@@ -139,6 +140,7 @@ module.exports = function(RED) {
};
data._verifier.on('cancel', function(e){
+ node.warn("Device verificaiton cancelled " + e);
verifierCancel();
});
@@ -180,6 +182,8 @@ module.exports = function(RED) {
}
});
+ data.emit("change");
+
await data.accept();
} catch(e) {
console.log("ERROR", e);
diff --git a/src/matrix-secret-storage.html b/src/matrix-secret-storage.html
new file mode 100644
index 0000000..4c99aed
--- /dev/null
+++ b/src/matrix-secret-storage.html
@@ -0,0 +1,71 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/matrix-secret-storage.js b/src/matrix-secret-storage.js
new file mode 100644
index 0000000..9e11a18
--- /dev/null
+++ b/src/matrix-secret-storage.js
@@ -0,0 +1,92 @@
+module.exports = function(RED) {
+ const verificationRequests = new Map();
+
+ function MatrixSecretStorage(n) {
+ RED.nodes.createNode(this, n);
+
+ var node = this;
+
+ this.name = n.name;
+ this.server = RED.nodes.getNode(n.server);
+
+ if (!node.server) {
+ node.warn("No configuration node");
+ return;
+ }
+
+ node.status({ fill: "red", shape: "ring", text: "disconnected" });
+
+ node.server.on("disconnected", function(){
+ node.status({ fill: "red", shape: "ring", text: "disconnected" });
+ });
+
+ node.server.on("connected", function() {
+ node.status({ fill: "green", shape: "ring", text: "connected" });
+ });
+
+ node.on('input', async function(msg){
+ try {
+ msg.hasSecretStorage = await node.server.matrixClient.hasSecretStorageKey();
+ } catch(e) {
+ console.log("ERROR", e);
+ }
+
+ if(msg.action) {
+ if(msg.action === 'create') {
+ if(msg.hasSecretStorage && !msg.forceReset) {
+ node.error("Secret storage already setup. Pass msg.forceReset to bypass and regenerate.");
+ return;
+ }
+
+
+ // copying this from https://github.com/matrix-org/matrix-react-sdk/blob/e78a1adb6f1af2ea425b0bae9034fb7344a4b2e8/src/SecurityManager.ts#L294
+ const recoveryKey = await node.server.matrixClient.createRecoveryKeyFromPassphrase(msg.key || undefined);
+ if(msg.forceReset) {
+ await node.server.matrixClient.bootstrapSecretStorage({
+ createSecretStorageKey: async () => recoveryKey,
+ setupNewKeyBackup: true,
+ setupNewSecretStorage: true,
+ });
+ } else {
+ // For password authentication users after 2020-09, this cross-signing
+ // step will be a no-op since it is now setup during registration or login
+ // when needed. We should keep this here to cover other cases such as:
+ // * Users with existing sessions prior to 2020-09 changes
+ // * SSO authentication users which require interactive auth to upload
+ // keys (and also happen to skip all post-authentication flows at the
+ // moment via token login)
+ await node.server.matrixClient.bootstrapCrossSigning({
+ // maybe we can skip this?
+ // authUploadDeviceSigningKeys: this._doBootstrapUIAuth,
+ });
+ const backupState = await node.server.matrixClient.getKeyBackupVersion();
+ await node.server.matrixClient.bootstrapSecretStorage({
+ createSecretStorageKey: async () => this._recoveryKey,
+ keyBackupInfo: backupState.backupInfo,
+ setupNewKeyBackup: !backupState.backupInfo,
+ getKeyBackupPassphrase: () => {
+ // We may already have the backup key if we earlier went
+ // through the restore backup path, so pass it along
+ // rather than prompting again.
+ if (this._backupKey) {
+ return this._backupKey;
+ }
+ return promptForBackupPassphrase();
+ },
+ });
+ }
+ }
+
+ if(msg.action === 'download') {
+ if(!msg.hasSecretStorage) {
+ node.error("Secret storage not setup so cannot download.");
+ return;
+ }
+ }
+ }
+
+ node.send(msg);
+ });
+ }
+ RED.nodes.registerType("matrix-secret-storage", MatrixSecretStorage);
+}
\ No newline at end of file