diff --git a/synapse/handlers/deactivate_account.py b/synapse/handlers/deactivate_account.py
index b13c4b6cb9..11ac377680 100644
--- a/synapse/handlers/deactivate_account.py
+++ b/synapse/handlers/deactivate_account.py
@@ -261,11 +261,22 @@ class DeactivateAccountHandler:
user = UserID.from_string(user_id)
rooms_for_user = await self.store.get_rooms_for_user(user_id)
+ requester = create_requester(user, authenticated_entity=self._server_name)
+ should_erase = await self.store.is_user_erased(user_id)
+
for room_id in rooms_for_user:
logger.info("User parter parting %r from %r", user_id, room_id)
try:
+ # Before parting the user, redact all membership events if requested
+ if should_erase:
+ event_ids = await self.store.get_membership_event_ids_for_user(
+ user_id, room_id
+ )
+ for event_id in event_ids:
+ await self.store.expire_event(event_id)
+
await self._room_member_handler.update_membership(
- create_requester(user, authenticated_entity=self._server_name),
+ requester,
user,
room_id,
"leave",
diff --git a/synapse/storage/databases/main/roommember.py b/synapse/storage/databases/main/roommember.py
index 5d51502595..9fddbb2caf 100644
--- a/synapse/storage/databases/main/roommember.py
+++ b/synapse/storage/databases/main/roommember.py
@@ -1234,6 +1234,28 @@ class RoomMemberWorkerStore(EventsWorkerStore, CacheInvalidationWorkerStore):
return set(room_ids)
+ async def get_membership_event_ids_for_user(
+ self, user_id: str, room_id: str
+ ) -> Set[str]:
+ """Get all event_ids for the given user and room.
+
+ Args:
+ user_id: The user ID to get the event IDs for.
+ room_id: The room ID to look up events for.
+
+ Returns:
+ Set of event IDs
+ """
+
+ event_ids = await self.db_pool.simple_select_onecol(
+ table="room_memberships",
+ keyvalues={"user_id": user_id, "room_id": room_id},
+ retcol="event_id",
+ desc="get_membership_event_ids_for_user",
+ )
+
+ return set(event_ids)
+
@cached(max_entries=5000)
async def _get_membership_from_event_id(
self, member_event_id: str
|