From 22fa049aa4f0a137fd41d643ff1531b931e99436 Mon Sep 17 00:00:00 2001 From: Jason Little Date: Thu, 14 May 2026 10:28:58 -0500 Subject: [PATCH 1/6] fix MSC3912-relation-based-redaction for room versions > 10(moved the 'redacts' key in v11) --- synapse/handlers/relations.py | 26 +++++++++++++++++++------- synapse/rest/client/room.py | 1 + 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/synapse/handlers/relations.py b/synapse/handlers/relations.py index ee4f8d672ee..593ea10b44b 100644 --- a/synapse/handlers/relations.py +++ b/synapse/handlers/relations.py @@ -38,6 +38,7 @@ from synapse.logging.opentracing import trace from synapse.storage.databases.main.relations import ThreadsNextBatch, _RelatedEvent from synapse.streams.config import PaginationConfig +from synapse.synapse_rust.room_versions import RoomVersion from synapse.types import JsonDict, Requester, UserID from synapse.util.async_helpers import gather_results from synapse.visibility import filter_and_transform_events_for_client @@ -211,6 +212,7 @@ async def redact_events_related_to( event_id: str, initial_redaction_event: EventBase, relation_types: list[str], + room_version: RoomVersion, ) -> None: """Redacts all events related to the given event ID with one of the given relation types. @@ -228,6 +230,8 @@ async def redact_events_related_to( event_id. relation_types: The types of relations to look for. If "*" is in the list, all related events will be redacted regardless of the type. + room_version: The RoomVersion of the room, for deciding where the 'redacts' + key should go in the event dict Raises: ShadowBanError if the requester is shadow-banned @@ -244,16 +248,24 @@ async def redact_events_related_to( ) for related_event_id in related_event_ids: + # Depending on the room version involved, the "redacts" key can go in one of + # two places. If we only use what was provided in the initial event, it will + # only target an event that was already redacted and nothing will happen. + new_redaction_content = dict(initial_redaction_event.content) + event_dict: JsonDict = { + "type": EventTypes.Redaction, + "content": new_redaction_content, + "room_id": initial_redaction_event.room_id, + "sender": requester.user.to_string(), + } + if room_version.updated_redaction_rules: + event_dict["content"].update({"redacts": related_event_id}) + else: + event_dict["redacts"] = related_event_id try: await self._event_creation_handler.create_and_send_nonmember_event( requester, - { - "type": EventTypes.Redaction, - "content": initial_redaction_event.content, - "room_id": initial_redaction_event.room_id, - "sender": requester.user.to_string(), - "redacts": related_event_id, - }, + event_dict, ratelimit=False, ) except SynapseError as e: diff --git a/synapse/rest/client/room.py b/synapse/rest/client/room.py index 48ef42c7d6f..2a9613a7e03 100644 --- a/synapse/rest/client/room.py +++ b/synapse/rest/client/room.py @@ -1438,6 +1438,7 @@ async def _do( event_id=event_id, initial_redaction_event=event, relation_types=with_relations, + room_version=room_version, ) event_id = event.event_id From bc59663a804a0e29e94e3145a986777f8e76bf9c Mon Sep 17 00:00:00 2001 From: Jason Little Date: Thu, 14 May 2026 11:15:08 -0500 Subject: [PATCH 2/6] changlog --- changelog.d/19782.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/19782.misc diff --git a/changelog.d/19782.misc b/changelog.d/19782.misc new file mode 100644 index 00000000000..7f3e374278a --- /dev/null +++ b/changelog.d/19782.misc @@ -0,0 +1 @@ +Fix [MSC3912](https://github.com/matrix-org/matrix-spec-proposals/pull/3912) (relation based redaction) for room versions greater than 10. Contributed by @famedly. From 9ed84aae13a09bd9c39c0abc1de067fbde8ec6c4 Mon Sep 17 00:00:00 2001 From: Jason Little Date: Tue, 23 Jun 2026 10:18:44 -0500 Subject: [PATCH 3/6] update and move comment --- synapse/handlers/relations.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/synapse/handlers/relations.py b/synapse/handlers/relations.py index 593ea10b44b..6540af0c375 100644 --- a/synapse/handlers/relations.py +++ b/synapse/handlers/relations.py @@ -248,9 +248,6 @@ async def redact_events_related_to( ) for related_event_id in related_event_ids: - # Depending on the room version involved, the "redacts" key can go in one of - # two places. If we only use what was provided in the initial event, it will - # only target an event that was already redacted and nothing will happen. new_redaction_content = dict(initial_redaction_event.content) event_dict: JsonDict = { "type": EventTypes.Redaction, @@ -258,6 +255,14 @@ async def redact_events_related_to( "room_id": initial_redaction_event.room_id, "sender": requester.user.to_string(), } + # Depending on the room version involved, the "redacts" key can go in one of + # two places. If we only use what was provided in the initial event, it will + # only target an event that was already redacted and nothing will happen. + # + # The Matrix Spec page for changes in Room Version 11 asks that we maintain + # a backward and forwards compatibility for clients over that API. That + # compatibility fixup will be in the client Event serialization code. Here + # we form and persist the Event strictly by the version of the room. if room_version.updated_redaction_rules: event_dict["content"].update({"redacts": related_event_id}) else: From 4609868e94a979a7a7d2d881e63330334c578103 Mon Sep 17 00:00:00 2001 From: Jason Little Date: Tue, 23 Jun 2026 10:20:19 -0500 Subject: [PATCH 4/6] incorporate suggested change for the docstring --- synapse/handlers/relations.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/synapse/handlers/relations.py b/synapse/handlers/relations.py index 6540af0c375..90d29ca4e34 100644 --- a/synapse/handlers/relations.py +++ b/synapse/handlers/relations.py @@ -230,8 +230,8 @@ async def redact_events_related_to( event_id. relation_types: The types of relations to look for. If "*" is in the list, all related events will be redacted regardless of the type. - room_version: The RoomVersion of the room, for deciding where the 'redacts' - key should go in the event dict + room_version: The RoomVersion of the room. Used for deciding where the + 'redacts' key should go in the event dict. Raises: ShadowBanError if the requester is shadow-banned From 16364cd10da7d8531e4ba0bcfc76c61c3d0f2ada Mon Sep 17 00:00:00 2001 From: Jason Little Date: Tue, 23 Jun 2026 10:23:31 -0500 Subject: [PATCH 5/6] don't always have to capitalize Event --- synapse/handlers/relations.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/synapse/handlers/relations.py b/synapse/handlers/relations.py index 90d29ca4e34..4173d2b31b6 100644 --- a/synapse/handlers/relations.py +++ b/synapse/handlers/relations.py @@ -261,8 +261,8 @@ async def redact_events_related_to( # # The Matrix Spec page for changes in Room Version 11 asks that we maintain # a backward and forwards compatibility for clients over that API. That - # compatibility fixup will be in the client Event serialization code. Here - # we form and persist the Event strictly by the version of the room. + # compatibility fixup will be in the client event serialization code. Here + # we form and persist the event strictly by the version of the room. if room_version.updated_redaction_rules: event_dict["content"].update({"redacts": related_event_id}) else: From 1014c9ca1c33f231b8c567a291761ee1b51eac91 Mon Sep 17 00:00:00 2001 From: Jason Little Date: Thu, 25 Jun 2026 08:42:27 -0500 Subject: [PATCH 6/6] apply feedback --- changelog.d/19782.misc | 2 +- synapse/handlers/relations.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/changelog.d/19782.misc b/changelog.d/19782.misc index 7f3e374278a..35f6c323854 100644 --- a/changelog.d/19782.misc +++ b/changelog.d/19782.misc @@ -1 +1 @@ -Fix [MSC3912](https://github.com/matrix-org/matrix-spec-proposals/pull/3912) (relation based redaction) for room versions greater than 10. Contributed by @famedly. +Put the `redacts` key under `content` when generating [MSC3912](https://github.com/matrix-org/matrix-spec-proposals/pull/3912) (relation based redactions) for room versions greater than 10. Contributed by @famedly. diff --git a/synapse/handlers/relations.py b/synapse/handlers/relations.py index 4173d2b31b6..7bad4fe8d3c 100644 --- a/synapse/handlers/relations.py +++ b/synapse/handlers/relations.py @@ -256,8 +256,7 @@ async def redact_events_related_to( "sender": requester.user.to_string(), } # Depending on the room version involved, the "redacts" key can go in one of - # two places. If we only use what was provided in the initial event, it will - # only target an event that was already redacted and nothing will happen. + # two places. # # The Matrix Spec page for changes in Room Version 11 asks that we maintain # a backward and forwards compatibility for clients over that API. That