diff --git a/spec/integ/megolm.spec.js b/spec/integ/megolm.spec.js index a692cdca6..6909b348e 100644 --- a/spec/integ/megolm.spec.js +++ b/spec/integ/megolm.spec.js @@ -349,6 +349,69 @@ describe("megolm", function() { }).nodeify(done); }); + it("Alice receives a megolm message before the session keys", function(done) { + // https://github.com/vector-im/riot-web/issues/2273 + let roomKeyEncrypted; + + return aliceTestClient.start().then(function() { + const p2pSession = createOlmSession(testOlmAccount, aliceTestClient); + + const groupSession = new Olm.OutboundGroupSession(); + groupSession.create(); + + // make the room_key event, but don't send it yet + roomKeyEncrypted = encryptGroupSessionKey({ + senderKey: testSenderKey, + recipient: aliceTestClient, + p2pSession: p2pSession, + groupSession: groupSession, + room_id: ROOM_ID, + }); + + // encrypt a message with the group session + const messageEncrypted = encryptMegolmEvent({ + senderKey: testSenderKey, + groupSession: groupSession, + room_id: ROOM_ID, + }); + + // Alice just gets the message event to start with + const syncResponse = { + next_batch: 1, + rooms: { + join: {}, + }, + }; + syncResponse.rooms.join[ROOM_ID] = { + timeline: { + events: [messageEncrypted], + }, + }; + + aliceTestClient.httpBackend.when("GET", "/sync").respond(200, syncResponse); + return aliceTestClient.httpBackend.flush("/sync", 1); + }).then(function() { + const room = aliceTestClient.client.getRoom(ROOM_ID); + const event = room.getLiveTimeline().getEvents()[0]; + expect(event.getContent().msgtype).toEqual('m.bad.encrypted'); + + // now she gets the room_key event + const syncResponse = { + next_batch: 2, + to_device: { + events: [roomKeyEncrypted], + }, + }; + + aliceTestClient.httpBackend.when("GET", "/sync").respond(200, syncResponse); + return aliceTestClient.httpBackend.flush("/sync", 1); + }).then(function() { + const room = aliceTestClient.client.getRoom(ROOM_ID); + const event = room.getLiveTimeline().getEvents()[0]; + expect(event.getContent().body).toEqual('42'); + }).nodeify(done); + }); + it("Alice gets a second room_key message", function(done) { return aliceTestClient.start().then(function() { const p2pSession = createOlmSession(testOlmAccount, aliceTestClient); diff --git a/src/crypto/algorithms/megolm.js b/src/crypto/algorithms/megolm.js index 762a86459..df4fdb5af 100644 --- a/src/crypto/algorithms/megolm.js +++ b/src/crypto/algorithms/megolm.js @@ -595,22 +595,24 @@ MegolmDecryption.prototype._addEventToPendingList = function(event) { MegolmDecryption.prototype.onRoomKeyEvent = function(event) { console.log("Adding key from ", event); const content = event.getContent(); + const senderKey = event.getSenderKey(); if (!content.room_id || !content.session_id || - !content.session_key + !content.session_key || + !senderKey ) { console.error("key event is missing fields"); return; } this._olmDevice.addInboundGroupSession( - content.room_id, event.getSenderKey(), content.session_id, + content.room_id, senderKey, content.session_id, content.session_key, event.getKeysClaimed(), ); // have another go at decrypting events sent with this session. - this._retryDecryption(event.getSenderKey, content.session_id); + this._retryDecryption(senderKey, content.session_id); };