Skip to content

fix(federation): re-invite after ban#40114

Merged
sampaiodiego merged 11 commits intodevelopfrom
fix/federation-second-reinvite-error
Apr 20, 2026
Merged

fix(federation): re-invite after ban#40114
sampaiodiego merged 11 commits intodevelopfrom
fix/federation-second-reinvite-error

Conversation

@sampaiodiego
Copy link
Copy Markdown
Member

@sampaiodiego sampaiodiego commented Apr 10, 2026

Proposed changes (including videos or screenshots)

Issue(s)

FGA-65

Steps to test or reproduce

Further comments

Summary by CodeRabbit

  • New Features

    • Allow restoring previously banned users to an invited state so they can rejoin federated rooms.
  • Bug Fixes

    • Better handling of out-of-order invite/join/leave events, including treating certain leaves as unbans.
    • Require invites from registered users and correctly reprocess invites for banned subscriptions.
  • Tests

    • Added end-to-end test covering ban, re-invite/unban, and messaging across federation.
  • Chores

    • Added release note entry for the patch.

@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot Bot commented Apr 10, 2026

Looks like this PR is ready to merge! 🎉
If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 10, 2026

🦋 Changeset detected

Latest commit: 7d4ed64

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 41 packages
Name Type
@rocket.chat/federation-matrix Patch
@rocket.chat/meteor Patch
@rocket.chat/core-typings Patch
@rocket.chat/rest-typings Patch
@rocket.chat/uikit-playground Patch
@rocket.chat/api-client Patch
@rocket.chat/apps Patch
@rocket.chat/core-services Patch
@rocket.chat/cron Patch
@rocket.chat/ddp-client Patch
@rocket.chat/fuselage-ui-kit Patch
@rocket.chat/gazzodown Patch
@rocket.chat/http-router Patch
@rocket.chat/livechat Patch
@rocket.chat/model-typings Patch
@rocket.chat/models Patch
@rocket.chat/ui-avatar Patch
@rocket.chat/ui-client Patch
@rocket.chat/ui-contexts Patch
@rocket.chat/ui-voip Patch
@rocket.chat/web-ui-registration Patch
@rocket.chat/account-service Patch
@rocket.chat/authorization-service Patch
@rocket.chat/ddp-streamer Patch
@rocket.chat/omnichannel-transcript Patch
@rocket.chat/presence-service Patch
@rocket.chat/queue-worker Patch
@rocket.chat/abac Patch
@rocket.chat/license Patch
@rocket.chat/media-calls Patch
@rocket.chat/omnichannel-services Patch
@rocket.chat/pdf-worker Patch
@rocket.chat/presence Patch
rocketchat-services Patch
@rocket.chat/network-broker Patch
@rocket.chat/omni-core-ee Patch
@rocket.chat/mock-providers Patch
@rocket.chat/instance-status Patch
@rocket.chat/omni-core Patch
@rocket.chat/server-fetch Patch
@rocket.chat/ui-video-conf Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 10, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e4a34f55-49ba-4021-b9db-7ebda679b646

📥 Commits

Reviewing files that changed from the base of the PR and between 7812797 and 7d4ed64.

📒 Files selected for processing (4)
  • apps/meteor/app/lib/server/functions/executeUnbanUserFromRoom.ts
  • apps/meteor/server/services/room/service.ts
  • ee/packages/federation-matrix/src/events/member.ts
  • packages/core-services/src/types/IRoomService.ts

Walkthrough

Adds an unban→invite flow: model support for atomic unban-to-invited update, a new RoomService.unbanAndInviteUser method (including optional system message), federation member handlers invoke the flow for invite/leave events when encountering banned subscriptions, and E2E tests covering ban, unban, re-invite, and messaging.

Changes

Cohort / File(s) Summary
Type Definitions
packages/core-services/src/types/IRoomService.ts, packages/model-typings/src/models/ISubscriptionsModel.ts
Added unbanAndInviteUser(...) to IRoomService and unbanToInvitedById(...) to ISubscriptionsModel to expose the unban→invite contract.
Service Implementation
apps/meteor/server/services/room/service.ts
Added RoomService.unbanAndInviteUser(subscription, inviteeUser, inviterUser) which awaits Subscriptions.unbanToInvitedById(...), fires notifyOnSubscriptionChangedById(...) (fire-and-forget), and, when inviteeUser.username is present, saves a system message attributed to the inviter.
Model Implementation
packages/models/src/models/Subscriptions.ts
Added SubscriptionsRaw.unbanToInvitedById(subId, inviter) performing an atomic updateOne on { _id: subId, status: 'BANNED' } to set status: 'INVITED' and adjust subscription fields plus inviter.
Federation Event Handling
ee/packages/federation-matrix/src/events/member.ts
handleInvite now requires inviter to be a registered user and, if an existing subscription is found and is banned, calls Room.unbanAndInviteUser(...) instead of returning. handleLeave inspects unsigned.prev_content.prevContent and treats a leave from prior ban as an unban, invoking Room.performUserUnban(...). (handleJoin still throws when subscription is missing in this diff.)
App Unban Flow
apps/meteor/app/lib/server/functions/executeUnbanUserFromRoom.ts
Subscription lookup changed to general findOneByRoomIdAndUserId; if subscription is no longer banned, the function now sends a user-unbanned system message and returns early instead of deleting the subscription.
End-to-End Tests
ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
Added E2E scenario validating Synapse→RC invite/accept, ban propagation, unban→re-invite flow, re-join, and messaging assertions before/after unban; includes new sendMessage use and retries.
Changelog
.changeset/red-kings-notice.md
Added changeset noting the fix for users being unable to re-join after ban→unban cycles.

Sequence Diagram(s)

sequenceDiagram
    participant Synapse
    participant Federation
    participant RoomService
    participant SubscriptionsModel
    participant NotificationService

    Synapse->>Federation: invite / join / leave event (may include unsigned.prev_content)
    activate Federation
    Federation->>Federation: lookup subscription
    alt subscription exists and status == BANNED
        Federation->>RoomService: unbanAndInviteUser(subscription, invitee, inviter)
        activate RoomService
        RoomService->>SubscriptionsModel: unbanToInvitedById(subId, inviter)
        activate SubscriptionsModel
        SubscriptionsModel-->>RoomService: UpdateResult (BANNED → INVITED)
        deactivate SubscriptionsModel
        RoomService->>NotificationService: notifyOnSubscriptionChangedById(subId, 'updated') (fire-and-forget)
        RoomService->>Federation: (optional) save system message attributed to inviter
        deactivate RoomService
    else subscription missing or not banned
        Federation->>Federation: default invite/join handling (may throw if missing subscription)
    end
    Federation-->>Synapse: ack / follow-up actions
    deactivate Federation
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly and concisely summarizes the main change: fixing re-invitation after a ban in the federation system.
Linked Issues check ✅ Passed The code changes directly address FGA-65 by implementing unbanAndInviteUser method to handle re-invite after ban cycles, allowing users to rejoin after being banned and unbanned.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the ban/re-invite issue: new unbanAndInviteUser method, updated federation member event handling, subscription model updates, and comprehensive end-to-end tests.

✏️ 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
Copy link
Copy Markdown

codecov Bot commented Apr 10, 2026

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.84%. Comparing base (5dc8d2b) to head (7d4ed64).
⚠️ Report is 2 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #40114      +/-   ##
===========================================
- Coverage    69.86%   69.84%   -0.03%     
===========================================
  Files         3294     3296       +2     
  Lines       119050   119163     +113     
  Branches     21463    21490      +27     
===========================================
+ Hits         83180    83230      +50     
- Misses       32576    32637      +61     
- Partials      3294     3296       +2     
Flag Coverage Δ
unit 70.53% <ø> (-0.05%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 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.

@sampaiodiego sampaiodiego force-pushed the fix/federation-second-reinvite-error branch 5 times, most recently from 2a3c2b5 to 2ca7d6a Compare April 20, 2026 18:32
@sampaiodiego sampaiodiego marked this pull request as ready for review April 20, 2026 18:33
@sampaiodiego sampaiodiego requested review from a team as code owners April 20, 2026 18:33
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: 2

🧹 Nitpick comments (1)
ee/packages/federation-matrix/src/events/member.ts (1)

296-303: Move the join-recovery explanation into code structure.

The new implementation comments can be replaced with a narrowly named guard/helper so the recovery path stays self-documenting without inline commentary.

As per coding guidelines, **/*.{ts,tsx,js} should “Avoid code comments in the implementation”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ee/packages/federation-matrix/src/events/member.ts` around lines 296 - 303,
Extract the join-recovery logic into a clearly named helper (e.g.,
recoverSubscriptionForLateJoin or ensureSubscriptionForJoin) and replace the
inline explanatory comment and inlined code in the member handling flow with a
single call to that helper; the helper should locate the subscription using
Subscriptions.findOneByRoomIdAndUserId(room._id, joiningUser._1) and, if
missing, perform the inviter-guessing using unsigned?.prev_content?.membership
and unsigned?.prev_sender and create the subscription then accept the invite as
the current code intends, so the high-level flow in the main function remains
self-documenting without inline comments.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ee/packages/federation-matrix/src/events/member.ts`:
- Around line 245-249: The current logic unconditionally treats any subscription
in INVITED state as an invite to be left alone, which lets a stale "unban" leave
slip through and prevents Room.performUserRemoval from cleaning up real invite
rejections; update handleLeave to only short-circuit when the leave corresponds
to the stale unban case by checking that the incoming leave is the unban action
that follows isBannedSubscription and Room.unbanAndInviteUser (e.g., correlate
event metadata or previous ban transition), otherwise allow normal processing so
Room.performUserRemoval still runs for genuine invite leaves; specifically
modify the branch that currently returns after calling
Room.unbanAndInviteUser(subscription, inviterUser) to guard only the stale unban
scenario and not all INVITED subscriptions so invite rejection via
federationSDK.rejectInvite() continues to trigger cleanup.

In `@packages/core-services/src/types/IRoomService.ts`:
- Line 82: The interface method unbanAndInviteUser currently accepts
inviterUser: Pick<IUser, '_id' | 'username' | 'name'> which allows missing
username; change the signature so username is required to match the
implementation and model (e.g. inviterUser: Required<Pick<IUser, '_id' |
'username'>> & Partial<Pick<IUser, 'name'>>), updating the IRoomService method
declaration to use that stricter type for inviterUser.

---

Nitpick comments:
In `@ee/packages/federation-matrix/src/events/member.ts`:
- Around line 296-303: Extract the join-recovery logic into a clearly named
helper (e.g., recoverSubscriptionForLateJoin or ensureSubscriptionForJoin) and
replace the inline explanatory comment and inlined code in the member handling
flow with a single call to that helper; the helper should locate the
subscription using Subscriptions.findOneByRoomIdAndUserId(room._id,
joiningUser._1) and, if missing, perform the inviter-guessing using
unsigned?.prev_content?.membership and unsigned?.prev_sender and create the
subscription then accept the invite as the current code intends, so the
high-level flow in the main function remains self-documenting without inline
comments.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6e41ff09-727d-4e10-84e9-d8e4fcefcd0e

📥 Commits

Reviewing files that changed from the base of the PR and between 80c7f9d and 2ca7d6a.

📒 Files selected for processing (6)
  • apps/meteor/server/services/room/service.ts
  • ee/packages/federation-matrix/src/events/member.ts
  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
  • packages/core-services/src/types/IRoomService.ts
  • packages/model-typings/src/models/ISubscriptionsModel.ts
  • packages/models/src/models/Subscriptions.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • packages/core-services/src/types/IRoomService.ts
  • apps/meteor/server/services/room/service.ts
  • packages/model-typings/src/models/ISubscriptionsModel.ts
  • ee/packages/federation-matrix/src/events/member.ts
  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
  • packages/models/src/models/Subscriptions.ts
**/*.spec.ts

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.spec.ts: Use descriptive test names that clearly communicate expected behavior in Playwright tests
Use .spec.ts extension for test files (e.g., login.spec.ts)

Files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
🧠 Learnings (29)
📓 Common learnings
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 37532
File: ee/packages/federation-matrix/src/FederationMatrix.ts:920-927
Timestamp: 2025-12-09T20:01:07.355Z
Learning: In Rocket.Chat's federation invite handling (ee/packages/federation-matrix/src/FederationMatrix.ts), when a user rejects an invite via federationSDK.rejectInvite(), the subscription cleanup happens automatically through an event-driven flow: Matrix emits a leave event back, which is processed by handleLeave() in ee/packages/federation-matrix/src/events/member.ts, and that function calls Room.performUserRemoval() to clean up the subscription. No explicit cleanup is needed in the reject branch of handleInvite() because the leave event handler takes care of it.
<!-- </add_learning>
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37377
File: apps/meteor/ee/server/hooks/federation/index.ts:86-88
Timestamp: 2025-11-04T16:49:19.107Z
Learning: In Rocket.Chat's federation system (apps/meteor/ee/server/hooks/federation/), permission checks follow two distinct patterns: (1) User-initiated federation actions (creating rooms, adding users to federated rooms, joining from invites) should throw MeteorError to inform users they lack 'access-federation' permission. (2) Remote server-initiated federation events should silently skip/ignore when users lack permission. The beforeAddUserToRoom hook only executes for local user-initiated actions, so throwing an error there is correct. Remote federation events are handled separately by the federation Matrix package with silent skipping logic.
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37205
File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301
Timestamp: 2025-10-28T16:53:42.761Z
Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37205
File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301
Timestamp: 2025-10-28T16:53:42.761Z
Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.
📚 Learning: 2026-03-09T18:39:21.178Z
Learnt from: Harxhit
Repo: RocketChat/Rocket.Chat PR: 39476
File: apps/meteor/server/methods/addAllUserToRoom.ts:0-0
Timestamp: 2026-03-09T18:39:21.178Z
Learning: In apps/meteor/server/methods/addAllUserToRoom.ts, the implementation uses a single cursor pass (Users.find(userFilter).batchSize(100)) that collects both the full user objects (collectedUsers: IUser[]) and their usernames (usernames: string[]) in one iteration. `beforeAddUserToRoom` is then called once with the full usernames batch (preserving batch-validation semantics), and the subsequent subscription/message processing loop iterates over the same stable `collectedUsers` array — no second DB query is made. This avoids any race condition between validation and processing while preserving the original batch-validation behavior.

Applied to files:

  • packages/core-services/src/types/IRoomService.ts
  • apps/meteor/server/services/room/service.ts
  • packages/model-typings/src/models/ISubscriptionsModel.ts
  • ee/packages/federation-matrix/src/events/member.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings by mapping subscription documents to room IDs, never undefined, even when user has no room subscriptions.

Applied to files:

  • packages/core-services/src/types/IRoomService.ts
  • apps/meteor/server/services/room/service.ts
  • packages/model-typings/src/models/ISubscriptionsModel.ts
  • ee/packages/federation-matrix/src/events/member.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings (mapping subscription documents to room IDs), never undefined, even when user has no room subscriptions.

Applied to files:

  • packages/core-services/src/types/IRoomService.ts
  • apps/meteor/server/services/room/service.ts
  • packages/model-typings/src/models/ISubscriptionsModel.ts
  • ee/packages/federation-matrix/src/events/member.ts
📚 Learning: 2025-12-09T20:01:07.355Z
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 37532
File: ee/packages/federation-matrix/src/FederationMatrix.ts:920-927
Timestamp: 2025-12-09T20:01:07.355Z
Learning: In Rocket.Chat's federation invite handling (ee/packages/federation-matrix/src/FederationMatrix.ts), when a user rejects an invite via federationSDK.rejectInvite(), the subscription cleanup happens automatically through an event-driven flow: Matrix emits a leave event back, which is processed by handleLeave() in ee/packages/federation-matrix/src/events/member.ts, and that function calls Room.performUserRemoval() to clean up the subscription. No explicit cleanup is needed in the reject branch of handleInvite() because the leave event handler takes care of it.
<!-- </add_learning>

Applied to files:

  • packages/core-services/src/types/IRoomService.ts
  • apps/meteor/server/services/room/service.ts
📚 Learning: 2025-10-28T16:53:42.761Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37205
File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301
Timestamp: 2025-10-28T16:53:42.761Z
Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.

Applied to files:

  • packages/core-services/src/types/IRoomService.ts
  • apps/meteor/server/services/room/service.ts
  • ee/packages/federation-matrix/src/events/member.ts
  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Applied to files:

  • packages/core-services/src/types/IRoomService.ts
  • apps/meteor/server/services/room/service.ts
  • packages/model-typings/src/models/ISubscriptionsModel.ts
  • ee/packages/federation-matrix/src/events/member.ts
  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
  • packages/models/src/models/Subscriptions.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Applied to files:

  • packages/core-services/src/types/IRoomService.ts
  • apps/meteor/server/services/room/service.ts
  • packages/model-typings/src/models/ISubscriptionsModel.ts
  • ee/packages/federation-matrix/src/events/member.ts
  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
  • packages/models/src/models/Subscriptions.ts
📚 Learning: 2026-03-11T22:04:20.529Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 39545
File: apps/meteor/client/views/room/body/hooks/useHasNewMessages.ts:59-61
Timestamp: 2026-03-11T22:04:20.529Z
Learning: In `apps/meteor/client/views/room/body/hooks/useHasNewMessages.ts`, the `msg.u._id === uid` early-return in the `streamNewMessage` handler is intentional: the "New messages" indicator is designed to notify about messages from other users only. Self-sent messages — including those sent from a different session/device — are always skipped, by design. Do not flag this as a multi-session regression.

Applied to files:

  • apps/meteor/server/services/room/service.ts
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.

Applied to files:

  • apps/meteor/server/services/room/service.ts
  • packages/models/src/models/Subscriptions.ts
📚 Learning: 2026-04-17T18:33:24.670Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 39858
File: apps/meteor/tests/e2e/apps/uikit-interactions.spec.ts:123-151
Timestamp: 2026-04-17T18:33:24.670Z
Learning: In RocketChat/Rocket.Chat (`apps/meteor/tests/e2e/apps/uikit-interactions.spec.ts`), `executeBlockActionHandler` invocations originating from a **modal** surface intentionally do NOT include a `block_action_room` (room property) in the interaction payload. Modals are not scoped to a room, so no room id is available in that context. Do not flag the absence of a room assertion in the modal block-action test as a missing coverage bug; instead, document it explicitly with a `test.step` asserting the room entry is `undefined`.

Applied to files:

  • apps/meteor/server/services/room/service.ts
  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-10-06T20:32:23.658Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 37152
File: packages/apps-engine/tests/test-data/utilities.ts:557-573
Timestamp: 2025-10-06T20:32:23.658Z
Learning: In packages/apps-engine/tests/test-data/utilities.ts, the field name `isSubscripbedViaBundle` in the `IMarketplaceSubscriptionInfo` type should not be flagged as a typo, as it may match the upstream API's field name.

Applied to files:

  • packages/model-typings/src/models/ISubscriptionsModel.ts
  • packages/models/src/models/Subscriptions.ts
📚 Learning: 2025-12-09T20:01:00.324Z
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 37532
File: ee/packages/federation-matrix/src/FederationMatrix.ts:920-927
Timestamp: 2025-12-09T20:01:00.324Z
Learning: When reviewing federation invite handling in Rocket.Chat (specifically under ee/packages/federation-matrix), understand that rejecting an invite via federationSDK.rejectInvite() triggers an event-driven cleanup: a leave event is emitted and handled by handleLeave() in ee/packages/federation-matrix/src/events/member.ts, which calls Room.performUserRemoval() to remove the subscription. Do not add explicit cleanup in the reject branch of handleInvite(); rely on the existing leave-event flow for cleanup. If making changes, ensure this invariant remains and that any related paths still funnel cleanup through the leave event to avoid duplicate or missing removals.

Applied to files:

  • ee/packages/federation-matrix/src/events/member.ts
  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-04T16:49:19.107Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37377
File: apps/meteor/ee/server/hooks/federation/index.ts:86-88
Timestamp: 2025-11-04T16:49:19.107Z
Learning: In Rocket.Chat's federation system (apps/meteor/ee/server/hooks/federation/), permission checks follow two distinct patterns: (1) User-initiated federation actions (creating rooms, adding users to federated rooms, joining from invites) should throw MeteorError to inform users they lack 'access-federation' permission. (2) Remote server-initiated federation events should silently skip/ignore when users lack permission. The beforeAddUserToRoom hook only executes for local user-initiated actions, so throwing an error there is correct. Remote federation events are handled separately by the federation Matrix package with silent skipping logic.

Applied to files:

  • ee/packages/federation-matrix/src/events/member.ts
  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `test.step()` for complex test scenarios to improve organization in Playwright tests

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-12-10T21:00:54.909Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37091
File: ee/packages/abac/jest.config.ts:4-7
Timestamp: 2025-12-10T21:00:54.909Z
Learning: Rocket.Chat monorepo: Jest testMatch pattern '<rootDir>/src/**/*.spec.(ts|js|mjs)' is valid in this repo and used across multiple packages (e.g., packages/tools, ee/packages/omnichannel-services). Do not flag it as invalid in future reviews.

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2026-03-15T14:31:23.493Z
Learnt from: amitb0ra
Repo: RocketChat/Rocket.Chat PR: 39647
File: apps/meteor/app/api/server/v1/users.ts:891-899
Timestamp: 2026-03-15T14:31:23.493Z
Learning: In RocketChat/Rocket.Chat, `IUser.inactiveReason` in `packages/core-typings/src/IUser.ts` is typed as `'deactivated' | 'pending_approval' | 'idle_too_long'` (optional, no `null`), but the database stores `null` for newly created users. The Typia-generated `$ref: '#/components/schemas/IUser'` schema therefore correctly rejects `null` for `inactiveReason`. This causes the test "should create a new user with default roles" to fail when response validation is active (TEST_MODE). The fix is to add `| null` to `inactiveReason` in core-typings and rebuild Typia schemas in a separate PR. Do not flag this test failure as a bug introduced by the users.create OpenAPI migration (PR `#39647`). Do not suggest inlining a custom schema to work around it, as migration rules require using `$ref` when a Typia schema exists.

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Maintain test isolation between test cases in Playwright tests

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Utilize Playwright fixtures (`test`, `page`, `expect`) for consistency in test files

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/page-objects/**/*.ts : Utilize existing page objects pattern from `apps/meteor/tests/e2e/page-objects/`

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Group related tests in the same file

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,spec.ts} : Store commonly used locators in variables/constants for reuse

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : All test files must be created in `apps/meteor/tests/e2e/` directory

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `expect` matchers for assertions (`toEqual`, `toContain`, `toBeTruthy`, `toHaveLength`, etc.) instead of `assert` statements in Playwright tests

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-12-16T17:29:45.163Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37834
File: apps/meteor/tests/e2e/page-objects/fragments/admin-flextab-emoji.ts:12-22
Timestamp: 2025-12-16T17:29:45.163Z
Learning: In page object files under `apps/meteor/tests/e2e/page-objects/`, always import `expect` from `../../utils/test` (Playwright's async expect), not from Jest. Jest's `expect` has a synchronous signature and will cause TypeScript errors when used with web-first assertions like `toBeVisible()`.

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure clean state for each test execution in Playwright tests

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2026-02-24T19:22:48.358Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 38493
File: apps/meteor/tests/e2e/omnichannel/omnichannel-send-pdf-transcript.spec.ts:66-67
Timestamp: 2026-02-24T19:22:48.358Z
Learning: In Playwright end-to-end tests (e.g., under apps/meteor/tests/e2e/...), prefer locating elements by translated text (getByText) and ARIA roles (getByRole) over data-qa attributes. If translation values change, update the corresponding test locators accordingly. Never use data-qa locators. This guideline applies to all Playwright e2e test specs in the repository and helps keep tests robust to UI text changes and accessible semantics.

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2026-03-06T18:10:15.268Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39397
File: packages/gazzodown/src/code/CodeBlock.spec.tsx:47-68
Timestamp: 2026-03-06T18:10:15.268Z
Learning: In tests (especially those using testing-library/dom/jsdom) for Rocket.Chat components, the HTML <code> element has an implicit ARIA role of 'code'. Therefore, screen.getByRole('code') or screen.findByRole('code') will locate <code> elements even without a role attribute. Do not flag findByRole('code') as invalid in reviews; prefer using the implicit role instead of adding role="code" unless necessary for accessibility.

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts

Comment thread ee/packages/federation-matrix/src/events/member.ts Outdated
Comment thread packages/core-services/src/types/IRoomService.ts Outdated
When a user undergoes multiple Ban -> Unban -> Re-invite cycles in a
federated room, the leave event from the unban can arrive after a new
INVITED subscription has been created. The handleLeave function currently
treats any non-banned subscription as a regular leave, deleting the new
INVITED subscription and locking the user out with "You've been removed
from room" error.
When a federated user is unbanned and re-invited in a single operation,
the unban sends a leave event to Matrix. If this leave event arrives
after a new INVITED subscription has already been created, handleLeave
was incorrectly treating it as a regular leave and calling
performUserRemoval — deleting the valid INVITED subscription and showing
"You've been removed from room" to the user.

Now handleLeave checks for INVITED status before removing, and skips the
stale leave event so the pending invite is preserved.
@sampaiodiego sampaiodiego force-pushed the fix/federation-second-reinvite-error branch from 2ca7d6a to 16e2081 Compare April 20, 2026 19:20
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

🧹 Nitpick comments (1)
ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts (1)

316-445: LGTM — end-to-end coverage closely follows the FGA-65 reproduction.

The new describe exercises the exact reported flow (invite → accept → ban on Synapse → unban → re-invite → accept → post-rejoin message), and each propagation point is wrapped in retry to handle asynchronous federation settling. The final message roundtrip via Synapse (findMessageInRoom) is the right way to validate the re-join, since the sendMessage helper only returns the HTTP response and does not itself wait for federation propagation.

One optional nit: the first it (lines 321-358) doubles as setup for all subsequent tests in this describe — if it fails, every later test will fail with confusing errors. The other describes in this file colocate that setup in beforeAll. Consider moving the room-create / initial-accept into a beforeAll (keeping the it('should create...') only if you want it as an explicit assertion) for consistency and clearer failure attribution. Not blocking.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts` around lines 316
- 445, The current first it('should create room on Synapse and have RC user
accept invite') double-purposes as setup for the whole describe and can cause
cascading failures; refactor the setup into a beforeAll: move the room creation
(hs1AdminApp.createRoom), initial invite (hs1AdminApp.inviteUserToRoom), polling
for the RC room (the retry block that sets federatedChannelId), and
acceptRoomInvite/follow-up Synapse join check (acceptRoomInvite and
hs1AdminApp.findRoomMember retry) into a beforeAll block and keep or convert the
existing it to a simple assertion if you want it as an explicit test; ensure
variables channelName, federatedChannelId and synapseRoomId remain in the
describe scope so subsequent its (ban/unban/reinvite/sendMessage) can use them.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/meteor/server/services/room/service.ts`:
- Around line 379-386: unbanAndInviteUser currently calls
Subscriptions.unbanToInvitedById and notifies subscribers but does not persist a
'ui' (user-invited) system message, so the re-invite is silent; mirror the
behavior in createUserSubscription by saving the same 'ui' system message when
you transition the subscription to 'INVITED' (include inviterUser info and
target subscription/room identifiers) immediately after
Subscriptions.unbanToInvitedById and before notifyOnSubscriptionChangedById so
the room history/audit trail matches normal invites.

---

Nitpick comments:
In `@ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts`:
- Around line 316-445: The current first it('should create room on Synapse and
have RC user accept invite') double-purposes as setup for the whole describe and
can cause cascading failures; refactor the setup into a beforeAll: move the room
creation (hs1AdminApp.createRoom), initial invite
(hs1AdminApp.inviteUserToRoom), polling for the RC room (the retry block that
sets federatedChannelId), and acceptRoomInvite/follow-up Synapse join check
(acceptRoomInvite and hs1AdminApp.findRoomMember retry) into a beforeAll block
and keep or convert the existing it to a simple assertion if you want it as an
explicit test; ensure variables channelName, federatedChannelId and
synapseRoomId remain in the describe scope so subsequent its
(ban/unban/reinvite/sendMessage) can use them.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5a32f5a7-8a46-4444-8a6c-603eecadf6be

📥 Commits

Reviewing files that changed from the base of the PR and between 2ca7d6a and 16e2081.

📒 Files selected for processing (6)
  • apps/meteor/server/services/room/service.ts
  • ee/packages/federation-matrix/src/events/member.ts
  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
  • packages/core-services/src/types/IRoomService.ts
  • packages/model-typings/src/models/ISubscriptionsModel.ts
  • packages/models/src/models/Subscriptions.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/model-typings/src/models/ISubscriptionsModel.ts
  • packages/models/src/models/Subscriptions.ts
  • ee/packages/federation-matrix/src/events/member.ts
  • packages/core-services/src/types/IRoomService.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/server/services/room/service.ts
  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
**/*.spec.ts

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.spec.ts: Use descriptive test names that clearly communicate expected behavior in Playwright tests
Use .spec.ts extension for test files (e.g., login.spec.ts)

Files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
🧠 Learnings (25)
📓 Common learnings
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 37532
File: ee/packages/federation-matrix/src/FederationMatrix.ts:920-927
Timestamp: 2025-12-09T20:01:07.355Z
Learning: In Rocket.Chat's federation invite handling (ee/packages/federation-matrix/src/FederationMatrix.ts), when a user rejects an invite via federationSDK.rejectInvite(), the subscription cleanup happens automatically through an event-driven flow: Matrix emits a leave event back, which is processed by handleLeave() in ee/packages/federation-matrix/src/events/member.ts, and that function calls Room.performUserRemoval() to clean up the subscription. No explicit cleanup is needed in the reject branch of handleInvite() because the leave event handler takes care of it.
<!-- </add_learning>
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37377
File: apps/meteor/ee/server/hooks/federation/index.ts:86-88
Timestamp: 2025-11-04T16:49:19.107Z
Learning: In Rocket.Chat's federation system (apps/meteor/ee/server/hooks/federation/), permission checks follow two distinct patterns: (1) User-initiated federation actions (creating rooms, adding users to federated rooms, joining from invites) should throw MeteorError to inform users they lack 'access-federation' permission. (2) Remote server-initiated federation events should silently skip/ignore when users lack permission. The beforeAddUserToRoom hook only executes for local user-initiated actions, so throwing an error there is correct. Remote federation events are handled separately by the federation Matrix package with silent skipping logic.
📚 Learning: 2026-03-09T18:39:21.178Z
Learnt from: Harxhit
Repo: RocketChat/Rocket.Chat PR: 39476
File: apps/meteor/server/methods/addAllUserToRoom.ts:0-0
Timestamp: 2026-03-09T18:39:21.178Z
Learning: In apps/meteor/server/methods/addAllUserToRoom.ts, the implementation uses a single cursor pass (Users.find(userFilter).batchSize(100)) that collects both the full user objects (collectedUsers: IUser[]) and their usernames (usernames: string[]) in one iteration. `beforeAddUserToRoom` is then called once with the full usernames batch (preserving batch-validation semantics), and the subsequent subscription/message processing loop iterates over the same stable `collectedUsers` array — no second DB query is made. This avoids any race condition between validation and processing while preserving the original batch-validation behavior.

Applied to files:

  • apps/meteor/server/services/room/service.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings by mapping subscription documents to room IDs, never undefined, even when user has no room subscriptions.

Applied to files:

  • apps/meteor/server/services/room/service.ts
📚 Learning: 2025-12-09T20:01:07.355Z
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 37532
File: ee/packages/federation-matrix/src/FederationMatrix.ts:920-927
Timestamp: 2025-12-09T20:01:07.355Z
Learning: In Rocket.Chat's federation invite handling (ee/packages/federation-matrix/src/FederationMatrix.ts), when a user rejects an invite via federationSDK.rejectInvite(), the subscription cleanup happens automatically through an event-driven flow: Matrix emits a leave event back, which is processed by handleLeave() in ee/packages/federation-matrix/src/events/member.ts, and that function calls Room.performUserRemoval() to clean up the subscription. No explicit cleanup is needed in the reject branch of handleInvite() because the leave event handler takes care of it.
<!-- </add_learning>

Applied to files:

  • apps/meteor/server/services/room/service.ts
📚 Learning: 2025-09-25T09:59:26.461Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 37057
File: packages/apps-engine/src/definition/accessors/IUserRead.ts:23-27
Timestamp: 2025-09-25T09:59:26.461Z
Learning: AppUserBridge.getUserRoomIds in apps/meteor/app/apps/server/bridges/users.ts always returns an array of strings (mapping subscription documents to room IDs), never undefined, even when user has no room subscriptions.

Applied to files:

  • apps/meteor/server/services/room/service.ts
📚 Learning: 2026-03-11T22:04:20.529Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 39545
File: apps/meteor/client/views/room/body/hooks/useHasNewMessages.ts:59-61
Timestamp: 2026-03-11T22:04:20.529Z
Learning: In `apps/meteor/client/views/room/body/hooks/useHasNewMessages.ts`, the `msg.u._id === uid` early-return in the `streamNewMessage` handler is intentional: the "New messages" indicator is designed to notify about messages from other users only. Self-sent messages — including those sent from a different session/device — are always skipped, by design. Do not flag this as a multi-session regression.

Applied to files:

  • apps/meteor/server/services/room/service.ts
📚 Learning: 2025-10-28T16:53:42.761Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37205
File: ee/packages/federation-matrix/src/FederationMatrix.ts:296-301
Timestamp: 2025-10-28T16:53:42.761Z
Learning: In the Rocket.Chat federation-matrix integration (ee/packages/federation-matrix/), the createRoom method from rocket.chat/federation-sdk will support a 4-argument signature (userId, roomName, visibility, displayName) in newer versions. Code using this 4-argument call is forward-compatible with planned library updates and should not be flagged as an error.

Applied to files:

  • apps/meteor/server/services/room/service.ts
  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.

Applied to files:

  • apps/meteor/server/services/room/service.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Applied to files:

  • apps/meteor/server/services/room/service.ts
  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Applied to files:

  • apps/meteor/server/services/room/service.ts
  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2026-04-17T18:33:24.670Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 39858
File: apps/meteor/tests/e2e/apps/uikit-interactions.spec.ts:123-151
Timestamp: 2026-04-17T18:33:24.670Z
Learning: In RocketChat/Rocket.Chat (`apps/meteor/tests/e2e/apps/uikit-interactions.spec.ts`), `executeBlockActionHandler` invocations originating from a **modal** surface intentionally do NOT include a `block_action_room` (room property) in the interaction payload. Modals are not scoped to a room, so no room id is available in that context. Do not flag the absence of a room assertion in the modal block-action test as a missing coverage bug; instead, document it explicitly with a `test.step` asserting the room entry is `undefined`.

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-12-09T20:01:00.324Z
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 37532
File: ee/packages/federation-matrix/src/FederationMatrix.ts:920-927
Timestamp: 2025-12-09T20:01:00.324Z
Learning: When reviewing federation invite handling in Rocket.Chat (specifically under ee/packages/federation-matrix), understand that rejecting an invite via federationSDK.rejectInvite() triggers an event-driven cleanup: a leave event is emitted and handled by handleLeave() in ee/packages/federation-matrix/src/events/member.ts, which calls Room.performUserRemoval() to remove the subscription. Do not add explicit cleanup in the reject branch of handleInvite(); rely on the existing leave-event flow for cleanup. If making changes, ensure this invariant remains and that any related paths still funnel cleanup through the leave event to avoid duplicate or missing removals.

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Utilize Playwright fixtures (`test`, `page`, `expect`) for consistency in test files

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/page-objects/**/*.ts : Utilize existing page objects pattern from `apps/meteor/tests/e2e/page-objects/`

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Group related tests in the same file

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.{ts,spec.ts} : Store commonly used locators in variables/constants for reuse

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : All test files must be created in `apps/meteor/tests/e2e/` directory

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Maintain test isolation between test cases in Playwright tests

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `expect` matchers for assertions (`toEqual`, `toContain`, `toBeTruthy`, `toHaveLength`, etc.) instead of `assert` statements in Playwright tests

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-12-16T17:29:45.163Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37834
File: apps/meteor/tests/e2e/page-objects/fragments/admin-flextab-emoji.ts:12-22
Timestamp: 2025-12-16T17:29:45.163Z
Learning: In page object files under `apps/meteor/tests/e2e/page-objects/`, always import `expect` from `../../utils/test` (Playwright's async expect), not from Jest. Jest's `expect` has a synchronous signature and will cause TypeScript errors when used with web-first assertions like `toBeVisible()`.

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure clean state for each test execution in Playwright tests

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2025-11-04T16:49:19.107Z
Learnt from: ricardogarim
Repo: RocketChat/Rocket.Chat PR: 37377
File: apps/meteor/ee/server/hooks/federation/index.ts:86-88
Timestamp: 2025-11-04T16:49:19.107Z
Learning: In Rocket.Chat's federation system (apps/meteor/ee/server/hooks/federation/), permission checks follow two distinct patterns: (1) User-initiated federation actions (creating rooms, adding users to federated rooms, joining from invites) should throw MeteorError to inform users they lack 'access-federation' permission. (2) Remote server-initiated federation events should silently skip/ignore when users lack permission. The beforeAddUserToRoom hook only executes for local user-initiated actions, so throwing an error there is correct. Remote federation events are handled separately by the federation Matrix package with silent skipping logic.

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2026-02-24T19:22:48.358Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 38493
File: apps/meteor/tests/e2e/omnichannel/omnichannel-send-pdf-transcript.spec.ts:66-67
Timestamp: 2026-02-24T19:22:48.358Z
Learning: In Playwright end-to-end tests (e.g., under apps/meteor/tests/e2e/...), prefer locating elements by translated text (getByText) and ARIA roles (getByRole) over data-qa attributes. If translation values change, update the corresponding test locators accordingly. Never use data-qa locators. This guideline applies to all Playwright e2e test specs in the repository and helps keep tests robust to UI text changes and accessible semantics.

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts
📚 Learning: 2026-03-06T18:10:15.268Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39397
File: packages/gazzodown/src/code/CodeBlock.spec.tsx:47-68
Timestamp: 2026-03-06T18:10:15.268Z
Learning: In tests (especially those using testing-library/dom/jsdom) for Rocket.Chat components, the HTML <code> element has an implicit ARIA role of 'code'. Therefore, screen.getByRole('code') or screen.findByRole('code') will locate <code> elements even without a role attribute. Do not flag findByRole('code') as invalid in reviews; prefer using the implicit role instead of adding role="code" unless necessary for accessibility.

Applied to files:

  • ee/packages/federation-matrix/tests/end-to-end/ban.spec.ts

Comment thread apps/meteor/server/services/room/service.ts
ggazzo
ggazzo previously approved these changes Apr 20, 2026
@ggazzo ggazzo added this to the 8.4.0 milestone Apr 20, 2026
@ggazzo ggazzo added the stat: QA assured Means it has been tested and approved by a company insider label Apr 20, 2026
@dionisio-bot dionisio-bot Bot removed the stat: QA assured Means it has been tested and approved by a company insider label Apr 20, 2026
@ggazzo ggazzo added the stat: QA assured Means it has been tested and approved by a company insider label Apr 20, 2026
@dionisio-bot dionisio-bot Bot added the stat: ready to merge PR tested and approved waiting for merge label Apr 20, 2026
@dionisio-bot dionisio-bot Bot enabled auto-merge April 20, 2026 19:56
@ricardogarim ricardogarim self-assigned this Apr 20, 2026
@sampaiodiego sampaiodiego disabled auto-merge April 20, 2026 21:27
@sampaiodiego sampaiodiego merged commit f3649b2 into develop Apr 20, 2026
8 of 11 checks passed
@sampaiodiego sampaiodiego deleted the fix/federation-second-reinvite-error branch April 20, 2026 21:27
@coderabbitai coderabbitai Bot removed the type: bug label Apr 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stat: QA assured Means it has been tested and approved by a company insider stat: ready to merge PR tested and approved waiting for merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants