diff --git a/src/models/event.ts b/src/models/event.ts index 20fb72745..c2cdd5d89 100644 --- a/src/models/event.ts +++ b/src/models/event.ts @@ -285,8 +285,28 @@ export class MatrixEvent extends EventEmitter { * @returns {IEvent} The event in wire format. */ public getEffectiveEvent(): IEvent { - // clearEvent doesn't have all the fields, so we'll copy what we can from this.event - return Object.assign({}, this.event, this.clearEvent) as IEvent; + const content = Object.assign({}, this.getContent()); // clone for mutation + + if (this.getWireType() === EventType.RoomMessageEncrypted) { + // Encrypted events sometimes aren't symmetrical on the `content` so we'll copy + // that over too, but only for missing properties. We don't copy over mismatches + // between the plain and decrypted copies of `content` because we assume that the + // app is relying on the decrypted version, so we want to expose that as a source + // of truth here too. + for (const [key, value] of Object.entries(this.getWireContent())) { + // Skip fields from the encrypted event schema though - we don't want to leak + // these. + if (["algorithm", "ciphertext", "device_id", "sender_key", "session_id"].includes(key)) { + continue; + } + + if (content[key] === undefined) content[key] = value; + } + } + + // clearEvent doesn't have all the fields, so we'll copy what we can from this.event. + // We also copy over our "fixed" content key. + return Object.assign({}, this.event, this.clearEvent, { content }) as IEvent; } /**