1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-26 17:03:12 +03:00

Add MatrixEvent.attemptDecryption

... and use it from both MatrixClient and the megolm re-decryption code.

This will help us avoid races when decryption is asynchronous.
This commit is contained in:
Richard van der Hoff
2017-07-18 14:41:25 +01:00
parent d37cbb10a5
commit 86f2c86440
3 changed files with 54 additions and 44 deletions

View File

@@ -640,42 +640,6 @@ MatrixClient.prototype.importRoomKeys = async function(keys) {
this._crypto.importRoomKeys(keys); this._crypto.importRoomKeys(keys);
}; };
/**
* Decrypt a received event according to the algorithm specified in the event.
*
* @param {MatrixClient} client
* @param {MatrixEvent} event
*/
function _decryptEvent(client, event) {
if (!client._crypto) {
_badEncryptedMessage(event, "Encryption not enabled");
return;
}
try {
client._crypto.decryptEvent(event);
} catch (e) {
console.warn(
`Error decrypting event (id=${event.getId()}): ${e}`,
);
if (e.name !== "DecryptionError") {
throw e;
}
_badEncryptedMessage(event, e.message);
return;
}
}
function _badEncryptedMessage(event, reason) {
event.setClearData({
type: "m.room.message",
content: {
msgtype: "m.bad.encrypted",
body: "** Unable to decrypt: " + reason + " **",
},
});
}
// Room ops // Room ops
// ======== // ========
@@ -3223,7 +3187,7 @@ function _PojoToMatrixEventMapper(client) {
function mapper(plainOldJsObject) { function mapper(plainOldJsObject) {
const event = new MatrixEvent(plainOldJsObject); const event = new MatrixEvent(plainOldJsObject);
if (event.isEncrypted()) { if (event.isEncrypted()) {
_decryptEvent(client, event); event.attemptDecryption(client._crypto);
} }
return event; return event;
} }

View File

@@ -842,13 +842,7 @@ MegolmDecryption.prototype._retryDecryption = function(senderKey, sessionId) {
delete this._pendingEvents[k]; delete this._pendingEvents[k];
for (let i = 0; i < pending.length; i++) { for (let i = 0; i < pending.length; i++) {
try { pending[i].attemptDecryption(this._crypto);
// no point sending another m.room_key_request here.
this._decryptEvent(pending[i], false);
console.log("successful re-decryption of", pending[i]);
} catch (e) {
console.log("Still can't decrypt", pending[i], e.stack || e);
}
} }
}; };

View File

@@ -298,6 +298,58 @@ utils.extend(module.exports.MatrixEvent.prototype, {
this._claimedEd25519Key = claimedEd25519Key; this._claimedEd25519Key = claimedEd25519Key;
}, },
/**
* Attempt to decrypt this event.
*
* (This is used within the SDK: it isn't intended for use by applications)
*
* @internal
*
* @param {module:crypto} crypto crypto module
*/
attemptDecryption: function(crypto) {
if (!crypto) {
this._badEncryptedMessage("Encryption not enabled");
return;
}
if (!this.isEncrypted()) {
throw new Error("Attempt to decrypt event which isn't encrypted");
}
if (
this._clearEvent && this._clearEvent.content &&
this._clearEvent.content.msgtype !== "m.bad.encrypted"
) {
// we may want to just ignore this? let's start with rejecting it.
throw new Error(
"Attempt to decrypt event which has already been encrypted",
);
}
try {
crypto.decryptEvent(this);
} catch (e) {
console.warn(
`Error decrypting event (id=${this.getId()}): ${e}`,
);
if (e.name !== "DecryptionError") {
throw e;
}
this._badEncryptedMessage(e.message);
}
},
_badEncryptedMessage: function(reason) {
this.setClearData({
type: "m.room.message",
content: {
msgtype: "m.bad.encrypted",
body: "** Unable to decrypt: " + reason + " **",
},
});
},
/** /**
* Update the cleartext data on this event. * Update the cleartext data on this event.
* *