diff --git a/src/client.js b/src/client.js index 007bd8820..cd2ce969d 100644 --- a/src/client.js +++ b/src/client.js @@ -640,42 +640,6 @@ MatrixClient.prototype.importRoomKeys = async function(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 // ======== @@ -3223,7 +3187,7 @@ function _PojoToMatrixEventMapper(client) { function mapper(plainOldJsObject) { const event = new MatrixEvent(plainOldJsObject); if (event.isEncrypted()) { - _decryptEvent(client, event); + event.attemptDecryption(client._crypto); } return event; } diff --git a/src/crypto/algorithms/megolm.js b/src/crypto/algorithms/megolm.js index 161f93c58..9c7ac71b7 100644 --- a/src/crypto/algorithms/megolm.js +++ b/src/crypto/algorithms/megolm.js @@ -842,13 +842,7 @@ MegolmDecryption.prototype._retryDecryption = function(senderKey, sessionId) { delete this._pendingEvents[k]; for (let i = 0; i < pending.length; i++) { - try { - // 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); - } + pending[i].attemptDecryption(this._crypto); } }; diff --git a/src/models/event.js b/src/models/event.js index 748009d98..5ec20b384 100644 --- a/src/models/event.js +++ b/src/models/event.js @@ -298,6 +298,58 @@ utils.extend(module.exports.MatrixEvent.prototype, { 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. *