Skip to content

fix: include banned and invited servers in event destination set#390

Open
ggazzo wants to merge 2 commits intomainfrom
fix/include-banned-invited-servers-in-destination-set
Open

fix: include banned and invited servers in event destination set#390
ggazzo wants to merge 2 commits intomainfrom
fix/include-banned-invited-servers-in-destination-set

Conversation

@ggazzo
Copy link
Copy Markdown
Member

@ggazzo ggazzo commented Mar 27, 2026

Summary

  • getServerSetInRoom now includes servers with ban or invite membership in addition to join
  • Fixes broken state chain after ban+unban cycle that prevented re-invites in federated rooms

Context

Closes #388

getServerSetInRoom only considered join membership, so after banning a user, their server stopped receiving events — including the unban event. This broke the state chain and made re-invites fail with "no previous state for event".

Test plan

  • Ban a user from a federated room (only user from their server)
  • Unban the user — verify the leave event reaches the remote server
  • Re-invite the user — verify the invite succeeds
  • Verify getServerSetInRoom tests pass

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Updated server set retrieval to include servers hosting users with banned and invited membership statuses, in addition to joined users.

ggazzo added 2 commits March 27, 2026 12:18
getServerSetInRoom only considered servers with 'join' membership,
excluding servers whose users were banned or had pending invites.
This caused unban (leave) events to never reach the banned user's
server, breaking the state chain and preventing re-invites.

Include 'ban' and 'invite' memberships so these servers continue
receiving room events needed to maintain a consistent state.
The test previously asserted that banned and invited servers were
excluded from the destination set. Updated to match the new behavior
where these servers are included to ensure they receive room events.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 27, 2026

Walkthrough

The StateService.getServerSetInRoom method now includes servers hosting users with ban and invite membership states in addition to join, resolving a bug where unbanning users failed due to missing event delivery to the banned server.

Changes

Cohort / File(s) Summary
Membership state filtering
packages/federation-sdk/src/services/state.service.ts
Added residentMemberships set containing ['join', 'invite', 'ban'] and changed membership event filter to include users with these membership types instead of only join.
Test expectations
packages/federation-sdk/src/services/state.service.spec.ts
Updated getServerSetInRoom test assertions to expect 4 servers (creator + joined + banned + invited) with server assertions flipped from false to true for banned and invited servers.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested labels

type: bug

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main change: including banned and invited servers in the event destination set, which directly aligns with the core objective of the PR.
Linked Issues check ✅ Passed The changes fully implement the requirements from issue #388: servers with join, invite, or ban membership are now included in the server set returned by getServerSetInRoom, directly addressing the broken state chain and re-invite failure.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the getServerSetInRoom logic and updating corresponding tests; no unrelated modifications are present.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov-commenter
Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 50.86%. Comparing base (69d076d) to head (4136d6b).
⚠️ Report is 10 commits behind head on main.

Files with missing lines Patch % Lines
...kages/federation-sdk/src/services/state.service.ts 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #390      +/-   ##
==========================================
+ Coverage   50.60%   50.86%   +0.25%     
==========================================
  Files          99      101       +2     
  Lines       11259    11470     +211     
==========================================
+ Hits         5698     5834     +136     
- Misses       5561     5636      +75     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ee2bf8a5-a9f6-4e61-8232-784ce7da4125

📥 Commits

Reviewing files that changed from the base of the PR and between 18f8494 and 4136d6b.

📒 Files selected for processing (2)
  • packages/federation-sdk/src/services/state.service.spec.ts
  • packages/federation-sdk/src/services/state.service.ts
📜 Review details
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-10T22:18:31.655Z
Learnt from: sampaiodiego
Repo: RocketChat/homeserver PR: 224
File: packages/federation-sdk/src/services/event-authorization.service.ts:261-268
Timestamp: 2025-10-10T22:18:31.655Z
Learning: In packages/federation-sdk/src/services/state.service.ts, the method `StateService.getLatestRoomState(roomId: string)` has return type `Promise<State>` and never returns undefined. If the state is not found, it throws an error with message "No state found for room ${roomId}" instead of returning undefined.

Applied to files:

  • packages/federation-sdk/src/services/state.service.ts
  • packages/federation-sdk/src/services/state.service.spec.ts
🔇 Additional comments (1)
packages/federation-sdk/src/services/state.service.spec.ts (1)

2265-2289: Coverage update matches the new membership-destination behavior.

This test now correctly validates the intended include/exclude matrix (join/invite/ban included, leave excluded).

Comment on lines +700 to 704
const residentMemberships = new Set(['join', 'invite', 'ban']);

for (const event of state.values()) {
if (!event.isMembershipEvent() || event.getMembership() !== 'join') {
if (!event.isMembershipEvent() || !residentMemberships.has(event.getMembership() ?? '')) {
continue;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Scope ban inclusion to federation destination usage; current change can authorize banned servers.

getServerSetInRoom is also used by EventAuthorizationService.serverHasAccessToResource (packages/federation-sdk/src/services/event-authorization.service.ts:254-256), where membership in this set immediately grants access. Including ban here can let banned servers pass authorization checks.

🔧 Proposed fix (make memberships explicit per call site)
- async getServerSetInRoom(roomId: RoomID, roomState?: State) {
+ async getServerSetInRoom(
+   roomId: RoomID,
+   roomState?: State,
+   residentMemberships: ReadonlySet<string> = new Set(['join']),
+ ) {
   const state = roomState ?? (await this.getLatestRoomState(roomId));

   const servers = new Set<string>();

-  const residentMemberships = new Set(['join', 'invite', 'ban']);
-
   for (const event of state.values()) {
     if (!event.isMembershipEvent() || !residentMemberships.has(event.getMembership() ?? '')) {
       continue;
     }

Then only federation fanout paths that require state-chain continuity should pass:
new Set(['join', 'invite', 'ban']).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Include banned and invited servers in event destination set

2 participants