1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-12-19 10:22:30 +03:00

Retry decryption after receiving keys

m.room_keys may arrive after the messages themselves, so allow events to be
decrypted after the event (haha).
This commit is contained in:
Richard van der Hoff
2016-11-14 15:05:49 +00:00
parent 1a03e534bd
commit a5d857945a
2 changed files with 63 additions and 2 deletions

View File

@@ -445,6 +445,10 @@ MegolmEncryption.prototype.onNewDevice = function(userId, deviceId) {
*/
function MegolmDecryption(params) {
base.DecryptionAlgorithm.call(this, params);
// events which we couldn't decrypt due to unknown sessions / indexes: map from
// senderKey|sessionId to list of MatrixEvents
this._pendingEvents = {};
}
utils.inherits(MegolmDecryption, base.DecryptionAlgorithm);
@@ -474,11 +478,15 @@ MegolmDecryption.prototype.decryptEvent = function(event) {
event.getRoomId(), content.sender_key, content.session_id, content.ciphertext
);
} catch (e) {
if (e.message === 'OLM.UNKNOWN_MESSAGE_INDEX') {
this._addEventToPendingList(event);
}
throw new base.DecryptionError(e);
}
if (res === null) {
// We've got a message for a session we don't have.
this._addEventToPendingList(event);
throw new base.DecryptionError("Unknown inbound session id");
}
@@ -496,6 +504,24 @@ MegolmDecryption.prototype.decryptEvent = function(event) {
event.setClearData(payload, res.keysClaimed, res.keysProved);
};
/**
* Add an event to the list of those we couldn't decrypt the first time we
* saw them.
*
* @private
*
* @param {module:models/event.MatrixEvent} event
*/
MegolmDecryption.prototype._addEventToPendingList = function(event) {
var content = event.getWireContent();
var k = content.sender_key + "|" + content.session_id;
if (!this._pendingEvents[k]) {
this._pendingEvents[k] = [];
}
this._pendingEvents[k].push(event);
};
/**
* @inheritdoc
*
@@ -517,6 +543,22 @@ MegolmDecryption.prototype.onRoomKeyEvent = function(event) {
content.room_id, event.getSenderKey(), content.session_id,
content.session_key, event.getKeysClaimed()
);
var k = event.getSenderKey() + "|" + content.session_id;
var pending = this._pendingEvents[k];
if (pending) {
// have another go at decrypting events sent with this session.
delete this._pendingEvents[k];
for (var i = 0; i < pending.length; i++) {
try {
this.decryptEvent(pending[i]);
console.log("successful re-decryption of", pending[i]);
} catch (e) {
console.log("Still can't decrypt", pending[i], e.stack || e);
}
}
}
};
base.registerAlgorithm(