From 9491be928d6ded74e8a2750dc52b7f299b9fd446 Mon Sep 17 00:00:00 2001 From: Ginger Date: Wed, 29 Apr 2026 09:26:13 -0400 Subject: [PATCH] fix: Fix panic when creating rooms --- src/service/rooms/timeline/append.rs | 158 ++++++++++++++------------- 1 file changed, 81 insertions(+), 77 deletions(-) diff --git a/src/service/rooms/timeline/append.rs b/src/service/rooms/timeline/append.rs index e4f439464..ab9081990 100644 --- a/src/service/rooms/timeline/append.rs +++ b/src/service/rooms/timeline/append.rs @@ -201,92 +201,96 @@ where drop(insert_lock); // See if the event matches any known pushers via power level - let power_levels = self - .services - .state_accessor - .get_room_power_levels(room_id) - .await; - let mut push_target: HashSet<_> = self + if *pdu.kind() != TimelineEventType::RoomCreate { + let power_levels = self .services - .state_cache - .active_local_users_in_room(room_id) - // Don't notify the sender of their own events, and dont send from ignored users - .ready_filter(|user| *user != pdu.sender()) - .filter_map(|recipient_user| async move { (!self.services.users.user_is_ignored(pdu.sender(), &recipient_user).await).then_some(recipient_user) }) - .collect() + .state_accessor + .get_room_power_levels(room_id) .await; + let mut push_target: HashSet<_> = self + .services + .state_cache + .active_local_users_in_room(room_id) + // Don't notify the sender of their own events, and dont send from ignored users + .ready_filter(|user| *user != pdu.sender()) + .filter_map(|recipient_user| async move { (!self.services.users.user_is_ignored(pdu.sender(), &recipient_user).await).then_some(recipient_user) }) + .collect() + .await; - let mut notifies = Vec::with_capacity(push_target.len().saturating_add(1)); - let mut highlights = Vec::with_capacity(push_target.len().saturating_add(1)); + let mut notifies = Vec::with_capacity(push_target.len().saturating_add(1)); + let mut highlights = Vec::with_capacity(push_target.len().saturating_add(1)); - if *pdu.kind() == TimelineEventType::RoomMember { - if let Some(state_key) = pdu.state_key() { - let target_user_id = UserId::parse(state_key)?; + if *pdu.kind() == TimelineEventType::RoomMember { + if let Some(state_key) = pdu.state_key() { + let target_user_id = UserId::parse(state_key)?; - if self.services.users.is_active_local(&target_user_id).await { - push_target.insert(target_user_id.clone()); + if self.services.users.is_active_local(&target_user_id).await { + push_target.insert(target_user_id.clone()); + } } } + + let serialized = pdu.to_format(); + for user in &push_target { + let rules_for_user = self + .services + .account_data + .get_global(user, GlobalAccountDataEventType::PushRules) + .await + .map_or_else( + |_| Ruleset::server_default(user), + |ev: PushRulesEvent| ev.content.global, + ); + + let mut highlight = false; + let mut notify = false; + + for action in self + .services + .pusher + .get_actions(user, &rules_for_user, power_levels.clone(), &serialized, room_id) + .await + { + match action { + | Action::Notify => notify = true, + | Action::SetTweak(Tweak::Highlight( + ruma::push::HighlightTweakValue::Yes, + )) => { + highlight = true; + }, + | _ => {}, + } + + // Break early if both conditions are true + if notify && highlight { + break; + } + } + + if notify { + notifies.push(user.clone()); + } + + if highlight { + highlights.push(user.clone()); + } + + self.services + .pusher + .get_pushkeys(user) + .ready_for_each(|push_key| { + self.services + .sending + .send_pdu_push(&pdu_id, user, push_key.to_owned()) + .expect("TODO: replace with future"); + }) + .await; + } + + self.db + .increment_notification_counts(room_id, notifies, highlights); } - let serialized = pdu.to_format(); - for user in &push_target { - let rules_for_user = self - .services - .account_data - .get_global(user, GlobalAccountDataEventType::PushRules) - .await - .map_or_else( - |_| Ruleset::server_default(user), - |ev: PushRulesEvent| ev.content.global, - ); - - let mut highlight = false; - let mut notify = false; - - for action in self - .services - .pusher - .get_actions(user, &rules_for_user, power_levels.clone(), &serialized, room_id) - .await - { - match action { - | Action::Notify => notify = true, - | Action::SetTweak(Tweak::Highlight(ruma::push::HighlightTweakValue::Yes)) => { - highlight = true; - }, - | _ => {}, - } - - // Break early if both conditions are true - if notify && highlight { - break; - } - } - - if notify { - notifies.push(user.clone()); - } - - if highlight { - highlights.push(user.clone()); - } - - self.services - .pusher - .get_pushkeys(user) - .ready_for_each(|push_key| { - self.services - .sending - .send_pdu_push(&pdu_id, user, push_key.to_owned()) - .expect("TODO: replace with future"); - }) - .await; - } - - self.db - .increment_notification_counts(room_id, notifies, highlights); - match *pdu.kind() { | TimelineEventType::RoomRedaction => { use RoomVersionId::*;