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) { function MegolmDecryption(params) {
base.DecryptionAlgorithm.call(this, 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); utils.inherits(MegolmDecryption, base.DecryptionAlgorithm);
@@ -474,11 +478,15 @@ MegolmDecryption.prototype.decryptEvent = function(event) {
event.getRoomId(), content.sender_key, content.session_id, content.ciphertext event.getRoomId(), content.sender_key, content.session_id, content.ciphertext
); );
} catch (e) { } catch (e) {
if (e.message === 'OLM.UNKNOWN_MESSAGE_INDEX') {
this._addEventToPendingList(event);
}
throw new base.DecryptionError(e); throw new base.DecryptionError(e);
} }
if (res === null) { if (res === null) {
// We've got a message for a session we don't have. // We've got a message for a session we don't have.
this._addEventToPendingList(event);
throw new base.DecryptionError("Unknown inbound session id"); throw new base.DecryptionError("Unknown inbound session id");
} }
@@ -496,6 +504,24 @@ MegolmDecryption.prototype.decryptEvent = function(event) {
event.setClearData(payload, res.keysClaimed, res.keysProved); 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 * @inheritdoc
* *
@@ -517,6 +543,22 @@ MegolmDecryption.prototype.onRoomKeyEvent = function(event) {
content.room_id, event.getSenderKey(), content.session_id, content.room_id, event.getSenderKey(), content.session_id,
content.session_key, event.getKeysClaimed() 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( base.registerAlgorithm(

View File

@@ -21,6 +21,10 @@ limitations under the License.
* @module models/event * @module models/event
*/ */
var EventEmitter = require("events").EventEmitter;
var utils = require('../utils.js');
/** /**
* Enum for event statuses. * Enum for event statuses.
* @readonly * @readonly
@@ -79,8 +83,10 @@ module.exports.MatrixEvent = function MatrixEvent(
this._keysProved = {}; this._keysProved = {};
this._keysClaimed = {}; this._keysClaimed = {};
}; };
utils.inherits(module.exports.MatrixEvent, EventEmitter);
module.exports.MatrixEvent.prototype = {
utils.extend(module.exports.MatrixEvent.prototype, {
/** /**
* Get the event_id for this event. * Get the event_id for this event.
@@ -251,6 +257,7 @@ module.exports.MatrixEvent.prototype = {
this._clearEvent = clearEvent; this._clearEvent = clearEvent;
this._keysProved = keysProved || {}; this._keysProved = keysProved || {};
this._keysClaimed = keysClaimed || {}; this._keysClaimed = keysClaimed || {};
this.emit("Event.decrypted", this);
}, },
/** /**
@@ -367,7 +374,7 @@ module.exports.MatrixEvent.prototype = {
setPushActions: function(pushActions) { setPushActions: function(pushActions) {
this._pushActions = pushActions; this._pushActions = pushActions;
}, },
}; });
/* http://matrix.org/docs/spec/r0.0.1/client_server.html#redactions says: /* http://matrix.org/docs/spec/r0.0.1/client_server.html#redactions says:
@@ -408,3 +415,15 @@ var _REDACT_KEEP_CONTENT_MAP = {
}, },
'm.room.aliases': {'aliases': 1}, 'm.room.aliases': {'aliases': 1},
}; };
/**
* Fires when an event is decrypted
*
* @event module:models/event.MatrixEvent#"Event.decrypted"
*
* @param {module:models/event.MatrixEvent} event
* The matrix event which has been decrypted
*/