diff --git a/synapse/visibility.py b/synapse/visibility.py
index 1b970ce479..49519eb8f5 100644
--- a/synapse/visibility.py
+++ b/synapse/visibility.py
@@ -14,12 +14,7 @@
import logging
from typing import Dict, FrozenSet, List, Optional
-from synapse.api.constants import (
- AccountDataTypes,
- EventTypes,
- HistoryVisibility,
- Membership,
-)
+from synapse.api.constants import EventTypes, HistoryVisibility, Membership
from synapse.events import EventBase
from synapse.events.utils import prune_event
from synapse.storage import Storage
@@ -81,20 +76,14 @@ async def filter_events_for_client(
types = ((EventTypes.RoomHistoryVisibility, ""), (EventTypes.Member, user_id))
+ # we exclude outliers at this point, and then handle them separately later
event_id_to_state = await storage.state.get_state_for_events(
- frozenset(e.event_id for e in events),
+ frozenset(e.event_id for e in events if not e.internal_metadata.outlier),
state_filter=StateFilter.from_types(types),
)
- ignore_dict_content = await storage.main.get_global_account_data_by_type_for_user(
- user_id, AccountDataTypes.IGNORED_USER_LIST
- )
-
- ignore_list: FrozenSet[str] = frozenset()
- if ignore_dict_content:
- ignored_users_dict = ignore_dict_content.get("ignored_users", {})
- if isinstance(ignored_users_dict, dict):
- ignore_list = frozenset(ignored_users_dict.keys())
+ # Get the users who are ignored by the requesting user.
+ ignore_list = await storage.main.ignored_users(user_id)
erased_senders = await storage.main.are_users_erased(e.sender for e in events)
@@ -154,6 +143,17 @@ async def filter_events_for_client(
if event.event_id in always_include_ids:
return event
+ # we need to handle outliers separately, since we don't have the room state.
+ if event.internal_metadata.outlier:
+ # Normally these can't be seen by clients, but we make an exception for
+ # for out-of-band membership events (eg, incoming invites, or rejections of
+ # said invite) for the user themselves.
+ if event.type == EventTypes.Member and event.state_key == user_id:
+ logger.debug("Returning out-of-band-membership event %s", event)
+ return event
+
+ return None
+
state = event_id_to_state[event.event_id]
# get the room_visibility at the time of the event.
@@ -198,6 +198,9 @@ async def filter_events_for_client(
# Always allow the user to see their own leave events, otherwise
# they won't see the room disappear if they reject the invite
+ #
+ # (Note this doesn't work for out-of-band invite rejections, which don't
+ # have prev_state populated. They are handled above in the outlier code.)
if membership == "leave" and (
prev_membership == "join" or prev_membership == "invite"
):
|