diff --git a/spec/integ/megolm-integ.spec.ts b/spec/integ/megolm-integ.spec.ts index c10ed85ce..f69d2ebdc 100644 --- a/spec/integ/megolm-integ.spec.ts +++ b/spec/integ/megolm-integ.spec.ts @@ -114,7 +114,7 @@ function encryptMegolmEvent(opts: { } return { - event_id: 'test_megolm_event', + event_id: 'test_megolm_event_' + Math.random(), content: { algorithm: "m.megolm.v1.aes-sha2", ciphertext: opts.groupSession.encrypt(JSON.stringify(plaintext)), @@ -980,4 +980,69 @@ describe("megolm", () => { expect(decryptedEvent.getContent()).toEqual({}); expect(decryptedEvent.getClearContent()).toBeUndefined(); }); + + it( + "should successfully decrypt bundled redaction events that don't include a room_id in their /sync data", + async () => { + await aliceTestClient.start(); + const p2pSession = await createOlmSession(testOlmAccount, aliceTestClient); + const groupSession = new Olm.OutboundGroupSession(); + groupSession.create(); + + // make the room_key event + const 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, + }); + + const redactionEncrypted = encryptMegolmEvent({ + senderKey: testSenderKey, + groupSession: groupSession, + plaintext: { + room_id: ROOM_ID, + type: "m.room.redaction", + redacts: messageEncrypted.event_id, + content: { reason: "redaction test" }, + }, + }); + + const messageEncryptedWithRedaction = { + ...messageEncrypted, + unsigned: { redacted_because: redactionEncrypted }, + }; + + const syncResponse = { + next_batch: 1, + to_device: { + events: [roomKeyEncrypted], + }, + rooms: { + join: { + [ROOM_ID]: { timeline: { events: [messageEncryptedWithRedaction] } }, + }, + }, + }; + + aliceTestClient.httpBackend.when("GET", "/sync").respond(200, syncResponse); + await aliceTestClient.flushSync(); + + const room = aliceTestClient.client.getRoom(ROOM_ID); + const event = room.getLiveTimeline().getEvents()[0]; + expect(event.isEncrypted()).toBe(true); + await event.attemptDecryption(aliceTestClient.client.crypto); + expect(event.getContent()).toEqual({}); + const redactionEvent: any = event.getRedactionEvent(); + expect(redactionEvent.content.reason).toEqual("redaction test"); + }, + ); }); diff --git a/src/crypto/index.ts b/src/crypto/index.ts index afa5c4b8a..4438edc8a 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -2859,7 +2859,10 @@ export class Crypto extends TypedEventEmitter { if (event.isRedacted()) { - const redactionEvent = new MatrixEvent(event.getUnsigned().redacted_because); + const redactionEvent = new MatrixEvent({ + room_id: event.getRoomId(), + ...event.getUnsigned().redacted_because, + }); const decryptedEvent = await this.decryptEvent(redactionEvent); return {