From b1df6911b31202fe4c04c50baacf458fd9dd4454 Mon Sep 17 00:00:00 2001 From: Ginger Date: Thu, 11 Sep 2025 09:13:50 -0400 Subject: [PATCH] feat: Do not sync invites from 4155-ignored users --- src/api/client/message.rs | 48 +++++++++++++++++++++++++++++---------- src/api/server/invite.rs | 3 +++ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/api/client/message.rs b/src/api/client/message.rs index 842036f5c..c32fcd33a 100644 --- a/src/api/client/message.rs +++ b/src/api/client/message.rs @@ -30,6 +30,8 @@ use ruma::{ events::{ AnyStateEvent, StateEventType, TimelineEventType::{self, *}, + invite_permission_config::FilterLevel, + room::member::{MembershipState, RoomMemberEventContent}, }, serde::Raw, }; @@ -267,7 +269,7 @@ pub(crate) async fn ignored_filter( pub(crate) async fn is_ignored_pdu( services: &Services, event: &Pdu, - user_id: &UserId, + recipient_user: &UserId, ) -> bool where Pdu: Event + Send + Sync, @@ -278,20 +280,42 @@ where return true; } - let ignored_type = IGNORED_MESSAGE_TYPES.binary_search(event.kind()).is_ok(); + if IGNORED_MESSAGE_TYPES.binary_search(event.kind()).is_ok() { + // this PDU is a non-state event which it is safe to ignore + return true; + } - let ignored_server = services + let sender_user = event.sender(); + + if services .moderation - .is_remote_server_ignored(event.sender().server_name()); - - if ignored_type - && (ignored_server - || (!services.config.send_messages_from_ignored_users_to_client - && services - .users - .user_is_ignored(event.sender(), user_id) - .await)) + .is_remote_server_ignored(sender_user.server_name()) { + // this PDU was sent by a remote server which we are ignoring + return true; + } + + if services + .users + .user_is_ignored(sender_user, recipient_user) + .await && !services.config.send_messages_from_ignored_users_to_client + { + // the recipient of this PDU has the sender ignored, and we're not + // configured to send ignored messages to clients + return true; + } + + if *event.kind() == RoomMember + && event + .get_content::() + .is_ok_and(|content| content.membership == MembershipState::Invite) + && services + .users + .invite_filter_level(sender_user, recipient_user) + .await == FilterLevel::Ignore + { + // this PDU is an invite from a sender that the recipient has ignored invites + // from return true; } diff --git a/src/api/server/invite.rs b/src/api/server/invite.rs index ac71513a6..261e2e099 100644 --- a/src/api/server/invite.rs +++ b/src/api/server/invite.rs @@ -117,6 +117,9 @@ pub(crate) async fn create_invite_route( .await; if matches!(recipient_invite_filter_level, FilterLevel::Block) { + // return an error for blocked invites. ignored invites aren't handled here + // since the recipient's membership should still be changed to `invite`. + // they're filtered out in api::client::message::is_ignored_pdu return Err!(Request(InviteBlocked( "{recipient_user} has blocked invites from {sender_user}." )));