From 136d699bfda858b954de3b6ef388405022ec1de5 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 10 Jan 2023 16:18:10 +0000 Subject: [PATCH] Handle edits which are bundled with an event, per MSC3925 --- src/event-mapper.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/event-mapper.ts b/src/event-mapper.ts index 87db88d6407..828d87e9510 100644 --- a/src/event-mapper.ts +++ b/src/event-mapper.ts @@ -16,6 +16,7 @@ limitations under the License. import { MatrixClient } from "./client"; import { IEvent, MatrixEvent, MatrixEventEvent } from "./models/event"; +import { RelationType } from "./@types/event"; export type EventMapper = (obj: Partial) => MatrixEvent; @@ -55,6 +56,19 @@ export function eventMapperFor(client: MatrixClient, options: MapperOpts): Event preventReEmit = true; } + // if there is a complete edit bundled alongside the event, perform the replacement. + // (prior to MSC3925, events were automatically replaced on the server-side. MSC3925 proposes that that doesn't + // happen automatically but the server does provide us with the whole content of the edit event.) + const bundledEdit = event.getServerAggregatedRelation>(RelationType.Replace); + if (bundledEdit?.content) { + const replacement = mapper(bundledEdit); + // XXX: it's worth noting that the spec says we should only respect encrypted edits if, once decrypted, the + // replacement has a `m.new_content` property. The problem is that we haven't yet decrypted the replacement + // (it should be happening in the background), so we can't enforce this. Possibly we should for decryption + // to complete, but that sounds a bit racy. For now, we just assume it's ok. + event.makeReplaced(replacement); + } + const thread = room?.findThreadForEvent(event); if (thread) { event.setThread(thread);