diff --git a/src/client.js b/src/client.js index 505c109d880..2a0002df557 100644 --- a/src/client.js +++ b/src/client.js @@ -3625,6 +3625,12 @@ module.exports.CRYPTO_ENABLED = CRYPTO_ENABLED; * }); */ +/** + * Fires when we want to suggest to the user that they restore their megolm keys + * from backup or by cross-signing the device. + * + * @event module:client~MatrixClient#"crypto.suggestKeyRestore" + */ // EventEmitter JSDocs diff --git a/src/crypto/OlmDevice.js b/src/crypto/OlmDevice.js index cda14779c2b..656e4fddc05 100644 --- a/src/crypto/OlmDevice.js +++ b/src/crypto/OlmDevice.js @@ -91,6 +91,22 @@ function OlmDevice(sessionStore, cryptoStore) { this.deviceEd25519Key = null; this._maxOneTimeKeys = null; + // track whether this device's megolm keys are being backed up incrementally + // to the server or not. + // XXX: this should probably have a single source of truth from OlmAccount + this.backupKey = null; + + // track which of our other devices (if any) have cross-signed this device + // XXX: this should probably have a single source of truth in the /devices + // API store or whatever we use to track our self-signed devices. + this.crossSelfSigs = []; + + // track whether we have already suggested to the user that they should + // restore their keys from backup or by cross-signing the device. + // We use this to avoid repeatedly emitting the suggestion event. + // XXX: persist this somewhere! + this.suggestedKeyRestore = false; + // we don't bother stashing outboundgroupsessions in the sessionstore - // instead we keep them here. this._outboundGroupSessionStore = {}; @@ -921,6 +937,11 @@ OlmDevice.prototype.addInboundGroupSession = async function( this._cryptoStore.addEndToEndInboundGroupSession( senderKey, sessionId, sessionData, txn, ); + + if (this.backupKey) { + // get olm::Account::generate_backup_encryption_secret + // save sessionData (pickled with this secret) to the server + } } finally { session.free(); } diff --git a/src/sync.js b/src/sync.js index 2636460b91c..b85f838f625 100644 --- a/src/sync.js +++ b/src/sync.js @@ -1059,6 +1059,15 @@ SyncApi.prototype._processSyncResponse = async function( async function processRoomEvent(e) { client.emit("event", e); if (e.isState() && e.getType() == "m.room.encryption" && self.opts.crypto) { + + // XXX: get device + if (!device.getSuggestedKeyRestore() && + !device.backupKey && !device.selfCrossSigs.length) + { + client.emit("crypto.suggestKeyRestore"); + device.setSuggestedKeyRestore(true); + } + await self.opts.crypto.onCryptoEvent(e); } }