From 14a30ca0648477def3fae0dab6bf1142cf4a4e37 Mon Sep 17 00:00:00 2001 From: Paul Chobert Date: Tue, 27 Oct 2026 17:20:41 +0100 Subject: [PATCH] Strip the user's real membership from announcement room timelines --- synapse/rest/client/sync.py | 8 ++++++++ tests/rest/client/test_sync.py | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/synapse/rest/client/sync.py b/synapse/rest/client/sync.py index cd53bb5e6f..0b840d9e44 100644 --- a/synapse/rest/client/sync.py +++ b/synapse/rest/client/sync.py @@ -612,6 +612,14 @@ class SyncRestServlet(RestServlet): for key, event in state_dict.items() if key != (EventTypes.Member, user_id) } + timeline_events = [ + filtered_event + for filtered_event in timeline_events + if not ( + filtered_event.event.type == EventTypes.Member + and filtered_event.event.state_key == user_id + ) + ] state_events = state_dict.values() diff --git a/tests/rest/client/test_sync.py b/tests/rest/client/test_sync.py index 29579c820a..3cfb3bcc6b 100644 --- a/tests/rest/client/test_sync.py +++ b/tests/rest/client/test_sync.py @@ -2361,6 +2361,15 @@ class ServerAnnouncementsSyncTestCase(unittest.HomeserverTestCase): ) self.assertEqual(self._timeline_ids(room), [event_id]) + def test_initial_sync_after_leaving(self) -> None: + """A former member who left on their own gets a single, synthetic join + on initial sync, even when their real leave is among the recent events. + """ + self.helper.leave(self.room_id, self.former, tok=self.former_tok) + self._announce("hello") + + self._assert_delivered(self._sync(self.former_tok), self.former) + def test_lazy_loaded_members(self) -> None: """The synthetic join is sent when members are lazy-loaded.""" self._announce("hello")