Skip to content

Conversation

@ricardogarim
Copy link
Contributor

@ricardogarim ricardogarim commented Nov 24, 2025

Proposed changes (including videos or screenshots)

As per FB-25, this PR implements a pre-federation validation shield that blocks outbound federation actions (invites, DMs, and room creation involving remote users) unless the destination domain is allowed, reachable, and the target user exists.

Works along with RocketChat/homeserver#305.

This introduces a sequential validation layer composed of three checks that run before any federation transaction is executed.

1. Policy vetting check (allow list enforcement)

Validates whether the remote domain is authorized according to the organization's Federation Domain Allow List.

If the domain is not allowed, the server immediately returns:

  • HTTP 403 Forbidden
  • Error code: federation-policy-denied

Message returned: "Action Blocked. Communication with one of the domains in the list is restricted by your organization's security policy."

2. Domain existence check (DNS / reachability)

Ensures that the remote homeserver domain resolves and is reachable.

If DNS lookup fails or the server is unreachable, the server returns:

  • Error code: federation-connection-failed

Message: "Connection Failed. The server domain could not be reached or does not support federation."

3. User existence check (protocol lookup)

Queries the remote homeserver for the given user ID.

If the remote server responds with a 404 for the user, the server blocks the request with:

  • Error code: federation-user-not-found

Message: "Invitation blocked. The specified user couldn’t be found on their homeserver."

Issue(s)

Test cases

Test Category Scenario Pathways Tested Input Expected Result Error Code UI Feedback
General Rule Invite multiple users where one fails Room creation modal, DM modal, inside room Mixed users Entire operation fails Depends on failure type Error message displayed

POLICY VETTING (RC ALLOW LIST)

Test Category Scenario Pathways Tested Input Expected Result Error Code UI Feedback
Policy Vetting RC Allow List contains only hs1, inviting user from hs2 Room creation modal @admin:hs2 Fail federation-policy-denied Policy message
Policy Vetting Same case tested via DM creation DM creation modal @admin:hs2 Fail Same Same
Policy Vetting Same case tested via inside-room invite Inside room ("Continue adding?") @admin:hs2 Status POLICY_DENIED; failing on continue federation-policy-denied Tooltip and final error
Policy Vetting Same case tested via /invite Slash command /invite @admin:hs2 Fail federation-policy-denied Same policy message
Policy Vetting RC Allow List contains only hs1, inviting user from hs1 All entry points @admin:hs1 Success None None
Policy Vetting Empty allow list allows all domains All entry points Any domain Success None None

DOMAIN EXISTENCE

Test Category Scenario Pathways Tested Input Expected Result Error Code UI Feedback
Domain Check Non-existent domain Room creation modal @admin:hs3 Fail federation-connection-failed Connection failed message
Domain Check Same case via DM creation DM creation modal @admin:hs3 Fail Same Same
Domain Check Same case inside room Inside room @admin:hs3 Status CONNECTION_FAILED None (status-level) + failure on continue Tooltip: "Unable to verify user"
Domain Check Same case via /invite Slash command /invite @admin:hs3 Fail federation-connection-failed Same

USER EXISTENCE

Test Category Scenario Pathways Tested Input Expected Result Error Code UI Feedback
User Existence Non-existent user on valid domain Room creation modal @admin2:hs1 Fail federation-user-not-found User-not-found message
User Existence Same case via DM creation DM creation modal @admin2:hs1 Fail Same Same
User Existence Same case inside room Inside room @admin2:hs1 Status USER_NOT_FOUND, continue disabled None (status-level) Tooltip: "User is unverified"
User Existence Same case via /invite Slash command /invite @admin2:hs1 Fail federation-user-not-found Same

Summary by CodeRabbit

  • New Features

    • Enforced federation domain allowlist for username-based members and when adding users to rooms.
    • Validates federated users before direct room creation with clearer mapped error responses.
    • Exposed federation validation helpers and a federation validation error type for federation flows.
  • Chores

    • Added configurable federation validation timeouts for network and user checks.

✏️ Tip: You can customize this high-level summary in your review settings.

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Nov 24, 2025

Looks like this PR is not ready to merge, because of the following issues:

  • This PR has conflicts, please resolve them before merging
  • This PR is not mergeable
  • This PR is targeting the wrong base branch. It should target 7.14.0, but it targets 7.13.0

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link

changeset-bot bot commented Nov 24, 2025

⚠️ No Changeset found

Latest commit: d33035d

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 24, 2025

Warning

Rate limit exceeded

@ricardogarim has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 7 minutes and 28 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 82fa056 and d33035d.

📒 Files selected for processing (1)
  • ee/packages/federation-matrix/src/FederationMatrix.ts (3 hunks)

Walkthrough

Adds pre-federation checks: enforces domain allowlist for federated usernames and validates outbound federated users before creating rooms or adding users; surfaces federation-specific errors as Meteor errors; exposes domain-allowlist utilities and validation timeouts in the federation-matrix package.

Changes

Cohort / File(s) Summary
Room creation & hooks
apps/meteor/app/lib/server/functions/createRoom.ts, apps/meteor/ee/server/hooks/federation/index.ts
Enforce domain allowlist for federated usernames and validate federated users when creating rooms or adding users; throw federation-policy-denied for blocked domains; map FederationValidationError to Meteor.Error (including original error and userMessage).
FederationMatrix core
ee/packages/federation-matrix/src/FederationMatrix.ts
Added validateFederatedUsers(usernames: string[]); enhanced verifyMatrixIds to enforce domain allowlist, validate outbound users via SDK, and map SDK error codes to internal verification results; removed some verbose post-creation logs.
Allowlist utilities
ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts
New isFederationDomainAllowed(domains: string[]) and isFederationDomainAllowedForUsernames(usernames: string[]) with exact, wildcard, and suffix matching; domain extraction from federated IDs and lowercase normalization.
Public exports
ee/packages/federation-matrix/src/index.ts
Re-exported FederationValidationError and exported isFederationDomainAllowed / isFederationDomainAllowedForUsernames.
Config / setup
ee/packages/federation-matrix/src/setup.ts
Added federation.validation settings: networkCheckTimeoutMs and userCheckTimeoutMs (env-driven, default 3000ms).

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant API as Room API
    participant Domain as DomainAllowlist\nisFederationDomainAllowedForUsernames
    participant FedMatrix as FederationMatrix\nvalidateFederatedUsers
    participant SDK as Federation SDK\nvalidateOutboundUser
    participant DB as Room DB

    Client->>API: createRoom(federated, members)
    rect "#DCE6FF"
      API->>Domain: check member domains allowed
      alt domain blocked
        Domain-->>API: policy denied
        API-->>Client: Error (federation-policy-denied)
      else domain allowed
        Domain-->>API: allowed
      end
    end

    rect "#E6FFEA"
      API->>FedMatrix: validate federated users exist
      FedMatrix->>SDK: validateOutboundUser (per user)
      alt validation/network error
        SDK-->>FedMatrix: error (mapped to FederationValidationError)
        FedMatrix-->>API: Meteor.Error (translated)
        API-->>Client: Error (validation failed)
      else all validated
        SDK-->>FedMatrix: OK
        FedMatrix-->>API: all valid
      end
    end

    rect "#FFF5C8"
      API->>DB: create room
      DB-->>API: success
      API-->>Client: Success
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • Areas needing extra attention:
    • Domain matching logic (exact, wildcard, suffix) and domain normalization in isFederationDomainAllowed.ts
    • Error translation/mapping from FederationValidationError to Meteor.Error across call sites
    • Timeouts/config propagation from setup.ts into validation calls
    • Sequencing and potential rollback around room creation in FederationMatrix after pre-validation

Possibly related PRs

Suggested labels

stat: ready to merge, stat: QA assured

Suggested reviewers

  • ggazzo
  • rodrigok
  • sampaiodiego

Poem

🐰 I hopped through domains both near and far,
Checked every name and each federated star.
Policies stood guard, bad invites kept at bay,
Valid friends joined in, the room found its way.
Hooray — federation safe for everyone today! ✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title mentions 'improved errors messaging' but the PR primarily implements pre-federation validation checks (policy, domain, user existence), not just error messaging improvements. Consider renaming to 'feat(federation): add pre-federation validation checks' or similar to accurately reflect the main changes.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The PR implements all three required validation checks (policy via domain allowlist, domain reachability, user existence) with appropriate error handling and mapping as specified in FB-25.
Out of Scope Changes check ✅ Passed All changes focus on API-level validation logic, error handling, and security gates as specified in FB-25 scope; no UI/UX enhancements detected.

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.

Copy link
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)
apps/meteor/ee/server/hooks/federation/index.ts (1)

3-3: Federation hooks correctly integrate allow‑list and outbound user validation

The new checks in beforeAddUserToRoom and beforeCreateDirectRoom are properly gated on native federation, reuse the shared allow‑list helper, and translate FederationValidationError into Meteor errors as per the permission/error‑handling patterns used in this module.

You may later want to centralize the repeated federation-policy-denied message into a constant to avoid divergence across call sites.
Based on learnings, this matches the intended federation permission behavior.

Also applies to: 91-97, 207-223

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5ef03e2 and 1ef7c23.

📒 Files selected for processing (6)
  • apps/meteor/app/lib/server/functions/createRoom.ts (2 hunks)
  • apps/meteor/ee/server/hooks/federation/index.ts (3 hunks)
  • ee/packages/federation-matrix/src/FederationMatrix.ts (4 hunks)
  • ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts (3 hunks)
  • ee/packages/federation-matrix/src/index.ts (1 hunks)
  • ee/packages/federation-matrix/src/setup.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
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.
Learnt from: rodrigok
Repo: RocketChat/Rocket.Chat PR: 36991
File: apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts:219-221
Timestamp: 2025-09-19T15:15:04.642Z
Learning: The Federation_Matrix_homeserver_domain setting in apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts is part of the old federation system and is being deprecated/removed, so configuration issues with this setting should not be flagged for improvement.
📚 Learning: 2025-09-19T15:15:04.642Z
Learnt from: rodrigok
Repo: RocketChat/Rocket.Chat PR: 36991
File: apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts:219-221
Timestamp: 2025-09-19T15:15:04.642Z
Learning: The Federation_Matrix_homeserver_domain setting in apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts is part of the old federation system and is being deprecated/removed, so configuration issues with this setting should not be flagged for improvement.

Applied to files:

  • ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts
  • ee/packages/federation-matrix/src/index.ts
  • apps/meteor/ee/server/hooks/federation/index.ts
  • ee/packages/federation-matrix/src/FederationMatrix.ts
  • ee/packages/federation-matrix/src/setup.ts
  • apps/meteor/app/lib/server/functions/createRoom.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/api/middlewares/isFederationDomainAllowed.ts
  • ee/packages/federation-matrix/src/index.ts
  • apps/meteor/ee/server/hooks/federation/index.ts
  • ee/packages/federation-matrix/src/FederationMatrix.ts
  • apps/meteor/app/lib/server/functions/createRoom.ts
📚 Learning: 2025-11-05T21:04:35.787Z
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 37357
File: ee/packages/federation-matrix/src/setup.ts:103-120
Timestamp: 2025-11-05T21:04:35.787Z
Learning: In Rocket.Chat's federation-matrix setup (ee/packages/federation-matrix/src/setup.ts and apps/meteor/ee/server/startup/federation.ts), configureFederationMatrixSettings does not need to be called before setupFederationMatrix. The SDK's init() establishes infrastructure (database, event handlers, APIs) first, and the configuration can be applied later via settings watchers before actual federation events are processed. The config only matters when events actually occur, at which point all infrastructure is already configured.

Applied to files:

  • ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts
  • ee/packages/federation-matrix/src/index.ts
  • apps/meteor/ee/server/hooks/federation/index.ts
  • ee/packages/federation-matrix/src/FederationMatrix.ts
  • ee/packages/federation-matrix/src/setup.ts
  • apps/meteor/app/lib/server/functions/createRoom.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:

  • ee/packages/federation-matrix/src/index.ts
  • apps/meteor/ee/server/hooks/federation/index.ts
  • ee/packages/federation-matrix/src/FederationMatrix.ts
  • apps/meteor/app/lib/server/functions/createRoom.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:

  • ee/packages/federation-matrix/src/FederationMatrix.ts
  • apps/meteor/app/lib/server/functions/createRoom.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:

  • ee/packages/federation-matrix/src/FederationMatrix.ts
  • apps/meteor/app/lib/server/functions/createRoom.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: UserBridge.doGetUserRoomIds in packages/apps-engine/src/server/bridges/UserBridge.ts has a bug where it implicitly returns undefined when the app lacks read permission (missing return statement in the else case of the permission check).

Applied to files:

  • apps/meteor/app/lib/server/functions/createRoom.ts
🧬 Code graph analysis (3)
apps/meteor/ee/server/hooks/federation/index.ts (2)
ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts (1)
  • isFederationDomainAllowedFromUsernames (44-54)
ee/packages/federation-matrix/src/FederationMatrix.ts (1)
  • FederationMatrix (138-935)
ee/packages/federation-matrix/src/FederationMatrix.ts (2)
ee/packages/federation-matrix/src/index.ts (2)
  • validateFederatedUsername (3-3)
  • isFederationDomainAllowed (11-11)
ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts (1)
  • isFederationDomainAllowed (20-42)
apps/meteor/app/lib/server/functions/createRoom.ts (4)
ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts (1)
  • isFederationDomainAllowedFromUsernames (44-54)
ee/packages/federation-matrix/src/index.ts (2)
  • isFederationDomainAllowedFromUsernames (11-11)
  • FederationMatrix (3-3)
ee/packages/federation-matrix/src/FederationMatrix.ts (1)
  • FederationMatrix (138-935)
packages/core-services/src/index.ts (1)
  • FederationMatrix (199-199)
🪛 GitHub Actions: CI
ee/packages/federation-matrix/src/FederationMatrix.ts

[error] 218-218: Property 'validateOutboundUser' does not exist on type 'FederationSDK'.

🔇 Additional comments (5)
ee/packages/federation-matrix/src/setup.ts (1)

100-105: Federation validation timeout wiring looks good

Timeouts are parsed safely with sensible 3s defaults and hooked cleanly under the federation.validation config without affecting existing behavior.

apps/meteor/app/lib/server/functions/createRoom.ts (1)

7-7: Pre‑federation allow‑list and user validation in createRoom are well‑placed

The checks run only for federated rooms with username lists, correctly gate on the domain allow‑list, and translate FederationValidationError into Meteor errors with user‑facing messages without impacting local or non‑federated rooms.

Also applies to: 182-202

ee/packages/federation-matrix/src/index.ts (1)

5-5: New federation exports are coherent with the public surface

Re‑exporting FederationValidationError and the domain allow‑list helpers here cleanly exposes the new validation capabilities to callers without changing existing APIs.

Also applies to: 11-11

ee/packages/federation-matrix/src/FederationMatrix.ts (2)

227-229: Room creation rollback behavior is a clear improvement

Tracking matrixRoomCreated and attempting a best‑effort leaveRoom when post‑creation steps fail avoids leaving orphaned Matrix membership and is correctly guarded so cleanup only runs when a room was actually created. Errors during cleanup are logged but do not swallow the original failure, which is the right trade‑off.

Also applies to: 235-237, 258-267


211-220: Let me search for the actual federation-sdk v0.3.0 API to confirm:

Let me search more specifically for federation-sdk package information:

Based on my thorough codebase inspection, I can now provide the rewritten review comment:


Normalize homeserver domain before domain allowlist check

In verifyMatrixIds, homeserverUrl includes port (per the comment "so we keep any port in the homeserver"), but you pass the full homeserverUrl directly to isFederationDomainAllowed([homeserverUrl]) without stripping the port. This means the allowlist check requires admins to configure domain:port pairs, not just domains.

To align with isFederationDomainAllowedFromUsernames, which uses extractDomainFromId to isolate the domain, consider normalizing homeserverUrl before the allowlist check:

if (!(await isFederationDomainAllowed([extractDomainFromId(matrixId)]))) {

This way, admins configure only the domain in the allowlist and port variations are handled transparently.

@ricardogarim ricardogarim force-pushed the feat/fed-errors-messaging branch from 1ef7c23 to eb46bb2 Compare November 25, 2025 22:12
Copy link
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

♻️ Duplicate comments (1)
ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts (1)

26-42: Security issue: over-permissive domain suffix matching still present.

The fallback on line 37 (domain.endsWith(pattern)) allows unrelated domains that happen to share a suffix. For example, if bar.com is in the allow-list, evilbar.com would also be permitted.

Apply the fix from the previous review to enforce proper domain label boundaries:

-		return domain.endsWith(pattern);
+		// Treat a bare pattern like "bar.com" as that exact domain or any proper subdomain,
+		// but do not match unrelated suffixes like "evilbar.com".
+		return domain.endsWith(`.${pattern}`);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1ef7c23 and eb46bb2.

📒 Files selected for processing (6)
  • apps/meteor/app/lib/server/functions/createRoom.ts (2 hunks)
  • apps/meteor/ee/server/hooks/federation/index.ts (3 hunks)
  • ee/packages/federation-matrix/src/FederationMatrix.ts (3 hunks)
  • ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts (3 hunks)
  • ee/packages/federation-matrix/src/index.ts (1 hunks)
  • ee/packages/federation-matrix/src/setup.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/meteor/ee/server/hooks/federation/index.ts
  • ee/packages/federation-matrix/src/index.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{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:

  • ee/packages/federation-matrix/src/setup.ts
  • apps/meteor/app/lib/server/functions/createRoom.ts
  • ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts
  • ee/packages/federation-matrix/src/FederationMatrix.ts
🧠 Learnings (7)
📓 Common learnings
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.
Learnt from: rodrigok
Repo: RocketChat/Rocket.Chat PR: 36991
File: apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts:219-221
Timestamp: 2025-09-19T15:15:04.642Z
Learning: The Federation_Matrix_homeserver_domain setting in apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts is part of the old federation system and is being deprecated/removed, so configuration issues with this setting should not be flagged for improvement.
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 37357
File: ee/packages/federation-matrix/src/setup.ts:103-120
Timestamp: 2025-11-05T21:04:35.787Z
Learning: In Rocket.Chat's federation-matrix setup (ee/packages/federation-matrix/src/setup.ts and apps/meteor/ee/server/startup/federation.ts), configureFederationMatrixSettings does not need to be called before setupFederationMatrix. The SDK's init() establishes infrastructure (database, event handlers, APIs) first, and the configuration can be applied later via settings watchers before actual federation events are processed. The config only matters when events actually occur, at which point all infrastructure is already configured.
📚 Learning: 2025-11-05T21:04:35.787Z
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 37357
File: ee/packages/federation-matrix/src/setup.ts:103-120
Timestamp: 2025-11-05T21:04:35.787Z
Learning: In Rocket.Chat's federation-matrix setup (ee/packages/federation-matrix/src/setup.ts and apps/meteor/ee/server/startup/federation.ts), configureFederationMatrixSettings does not need to be called before setupFederationMatrix. The SDK's init() establishes infrastructure (database, event handlers, APIs) first, and the configuration can be applied later via settings watchers before actual federation events are processed. The config only matters when events actually occur, at which point all infrastructure is already configured.

Applied to files:

  • ee/packages/federation-matrix/src/setup.ts
  • apps/meteor/app/lib/server/functions/createRoom.ts
  • ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts
  • ee/packages/federation-matrix/src/FederationMatrix.ts
📚 Learning: 2025-09-19T15:15:04.642Z
Learnt from: rodrigok
Repo: RocketChat/Rocket.Chat PR: 36991
File: apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts:219-221
Timestamp: 2025-09-19T15:15:04.642Z
Learning: The Federation_Matrix_homeserver_domain setting in apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts is part of the old federation system and is being deprecated/removed, so configuration issues with this setting should not be flagged for improvement.

Applied to files:

  • ee/packages/federation-matrix/src/setup.ts
  • apps/meteor/app/lib/server/functions/createRoom.ts
  • ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts
  • ee/packages/federation-matrix/src/FederationMatrix.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/app/lib/server/functions/createRoom.ts
  • ee/packages/federation-matrix/src/FederationMatrix.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:

  • apps/meteor/app/lib/server/functions/createRoom.ts
  • ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts
  • ee/packages/federation-matrix/src/FederationMatrix.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/app/lib/server/functions/createRoom.ts
  • ee/packages/federation-matrix/src/FederationMatrix.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/app/lib/server/functions/createRoom.ts
  • ee/packages/federation-matrix/src/FederationMatrix.ts
🧬 Code graph analysis (3)
apps/meteor/app/lib/server/functions/createRoom.ts (4)
ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts (1)
  • isFederationDomainAllowedForUsernames (44-54)
ee/packages/federation-matrix/src/index.ts (3)
  • isFederationDomainAllowedForUsernames (11-11)
  • FederationMatrix (3-3)
  • FederationValidationError (5-5)
ee/packages/federation-matrix/src/FederationMatrix.ts (1)
  • FederationMatrix (138-924)
packages/core-services/src/index.ts (1)
  • FederationMatrix (199-199)
ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts (1)
ee/packages/federation-matrix/src/index.ts (2)
  • isFederationDomainAllowed (11-11)
  • isFederationDomainAllowedForUsernames (11-11)
ee/packages/federation-matrix/src/FederationMatrix.ts (2)
ee/packages/federation-matrix/src/index.ts (3)
  • validateFederatedUsername (3-3)
  • FederationValidationError (5-5)
  • isFederationDomainAllowed (11-11)
ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts (1)
  • isFederationDomainAllowed (20-42)
⏰ 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 comments (9)
ee/packages/federation-matrix/src/setup.ts (1)

100-105: LGTM!

The validation timeout configuration is well-integrated and follows existing patterns in the file for environment variable parsing with sensible defaults.

apps/meteor/app/lib/server/functions/createRoom.ts (2)

7-7: LGTM!

Imports are correctly added for the new federation validation utilities.


182-202: Well-structured federation validation flow.

The sequential validation (policy check → user existence) aligns with the PR objectives. Error mapping from FederationValidationError to Meteor.Error correctly preserves the error code and user message for proper UI feedback. Based on learnings, throwing MeteorError for user-initiated actions is the correct pattern here.

ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts (3)

2-2: LGTM!

Correct import for extracting domains from federated user IDs.


44-54: LGTM!

The function correctly filters federated usernames (containing :), extracts their domains, and delegates to isFederationDomainAllowed. Returning true when no federated users are present is the correct behavior.


92-94: Good refactor to centralized domain validation.

The middleware now delegates to isFederationDomainAllowed, ensuring consistent domain checking logic across all code paths.

ee/packages/federation-matrix/src/FederationMatrix.ts (3)

11-11: LGTM!

Correct import of FederationValidationError for validation error handling.


18-18: LGTM!

Import added for domain allowlist validation.


892-917: LGTM - Comprehensive verification with proper error mapping.

The verifyMatrixIds method now correctly:

  1. Checks domain allowlist before network validation (line 895)
  2. Validates outbound user existence via SDK (line 900)
  3. Maps specific error codes to appropriate verification statuses

The error code handling (lines 904-915) properly distinguishes between connection failures, user not found, and policy denials.

Copy link
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: 0

🧹 Nitpick comments (2)
ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts (2)

57-57: TODO: Extract authorization header parser if reused.

The comment suggests extracting parseMatrixAuthorizationHeader as a shared utility if needed elsewhere.

Would you like me to open an issue to track this refactoring, or help identify other locations where this parser might be useful?


6-6: Consider removing inline comments per coding guidelines.

The coding guidelines for TypeScript files recommend avoiding code comments in the implementation. Most comments here explain "what" the code does rather than "why", which can be inferred from well-named functions and variables.

As per coding guidelines, consider removing comments at lines 6, 29, 41, 44, and 60. The code is self-explanatory with clear function and variable names.

Also applies to: 29-29, 41-41, 44-44, 60-60

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between eb46bb2 and 3461604.

📒 Files selected for processing (1)
  • ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{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:

  • ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts
🧠 Learnings (4)
📓 Common learnings
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: rodrigok
Repo: RocketChat/Rocket.Chat PR: 36991
File: apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts:219-221
Timestamp: 2025-09-19T15:15:04.642Z
Learning: The Federation_Matrix_homeserver_domain setting in apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts is part of the old federation system and is being deprecated/removed, so configuration issues with this setting should not be flagged for improvement.
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.
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 37357
File: ee/packages/federation-matrix/src/setup.ts:103-120
Timestamp: 2025-11-05T21:04:35.787Z
Learning: In Rocket.Chat's federation-matrix setup (ee/packages/federation-matrix/src/setup.ts and apps/meteor/ee/server/startup/federation.ts), configureFederationMatrixSettings does not need to be called before setupFederationMatrix. The SDK's init() establishes infrastructure (database, event handlers, APIs) first, and the configuration can be applied later via settings watchers before actual federation events are processed. The config only matters when events actually occur, at which point all infrastructure is already configured.
📚 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/api/middlewares/isFederationDomainAllowed.ts
📚 Learning: 2025-09-19T15:15:04.642Z
Learnt from: rodrigok
Repo: RocketChat/Rocket.Chat PR: 36991
File: apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts:219-221
Timestamp: 2025-09-19T15:15:04.642Z
Learning: The Federation_Matrix_homeserver_domain setting in apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts is part of the old federation system and is being deprecated/removed, so configuration issues with this setting should not be flagged for improvement.

Applied to files:

  • ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts
📚 Learning: 2025-11-05T21:04:35.787Z
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 37357
File: ee/packages/federation-matrix/src/setup.ts:103-120
Timestamp: 2025-11-05T21:04:35.787Z
Learning: In Rocket.Chat's federation-matrix setup (ee/packages/federation-matrix/src/setup.ts and apps/meteor/ee/server/startup/federation.ts), configureFederationMatrixSettings does not need to be called before setupFederationMatrix. The SDK's init() establishes infrastructure (database, event handlers, APIs) first, and the configuration can be applied later via settings watchers before actual federation events are processed. The config only matters when events actually occur, at which point all infrastructure is already configured.

Applied to files:

  • ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts
🧬 Code graph analysis (1)
ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts (1)
ee/packages/federation-matrix/src/index.ts (2)
  • isFederationDomainAllowed (11-11)
  • isFederationDomainAllowedForUsernames (11-11)
⏰ 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 comments (3)
ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts (3)

20-38: LGTM! Domain allow-list logic is secure and correct.

The pattern matching correctly handles wildcards (subdomains only) and non-wildcard entries (exact + subdomains), preventing suffix-abuse attacks like evilbar.com matching bar.com. The use of .every() ensures fail-fast behavior when any domain is disallowed.


88-88: Clean refactoring to use shared validation.

The middleware correctly delegates to isFederationDomainAllowed, improving code reuse and maintainability while preserving the same security validation logic.


40-50: I'll verify the concerns in this review comment by examining how extractDomainFromId is used and whether error handling is necessary.
<function_calls>


#!/bin/bash

Check extractDomainFromId usage and error handling patterns

Find all usages of extractDomainFromId in the codebase

echo "=== All usages of extractDomainFromId ==="
rg -n --type=ts 'extractDomainFromId' -B2 -A2

Check for try-catch patterns around it

echo -e "\n=== Try-catch or error handling around extractDomainFromId ==="
rg -n --type=ts -B3 -A3 'try.*extractDomainFromId|extractDomainFromId.*catch|catch.*extractDomainFromId'

Look for import statement to understand the source

echo -e "\n=== Import statements for extractDomainFromId ==="
rg -n --type=ts 'import.*extractDomainFromId|extractDomainFromId.*from'


</function_calls>

#!/bin/bash # Search federation-sdk documentation or type definitions echo "=== Look for @rocket.chat/federation-sdk references ===" rg -n --type=ts '@rocket.chat/federation-sdk' -A1 | head -30

Check if there's any JSDoc or type info on extractDomainFromId

echo -e "\n=== Search for extractDomainFromId function definition ==="
rg -n --type=ts 'export.*extractDomainFromId|function extractDomainFromId|const extractDomainFromId'


</function_calls>

#!/bin/bash # Examine the current file to understand context echo "=== Current file context ===" wc -l ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts

Show the full file to understand imports and usage

cat -n ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts


</function_calls>

#!/bin/bash # Check if there are any tests for this function to understand expected behavior echo "=== Look for tests ===" fd -e test.ts -e spec.ts -e test.js | xargs rg -l 'isFederationDomainAllowedForUsernames' 2>/dev/null

Check for any Matrix ID validation utilities

echo -e "\n=== Look for Matrix ID or username validation patterns ==="
rg -n --type=ts 'includes.*:.*username|username.includes.:' -B2 -A2 | head -30


</function_calls>

Copy link
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)
apps/meteor/app/lib/server/functions/createRoom.ts (1)

193-206: Type annotations and filter logic can be simplified since members is already string[].

At line 182, onlyUsernames(members) guarantees that members is string[]. The type annotations (member: string | IUser) on lines 196-198 are unnecessary and potentially confusing since the IUser branch is never taken.

Additionally, the federated user detection here (line 197) only checks for :, while hasFederatedMembers (lines 140-145) checks for both : and @. While validateFederatedUsers will catch invalid formats, aligning the detection logic would improve consistency.

-		try {
-			// TODO: Use common function to extract and validate federated users
-			const federatedUsers = members
-				.filter((member: string | IUser) => (typeof member === 'string' ? member.includes(':') : member.username?.includes(':')))
-				.map((member: string | IUser) => (typeof member === 'string' ? member : member.username!));
-			await FederationMatrix.validateFederatedUsers(federatedUsers);
+		try {
+			const federatedUsers = members.filter((member) => member.includes(':') && member.includes('@'));
+			await FederationMatrix.validateFederatedUsers(federatedUsers);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3461604 and 82fa056.

📒 Files selected for processing (3)
  • apps/meteor/app/lib/server/functions/createRoom.ts (2 hunks)
  • apps/meteor/ee/server/hooks/federation/index.ts (3 hunks)
  • ee/packages/federation-matrix/src/FederationMatrix.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{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:

  • ee/packages/federation-matrix/src/FederationMatrix.ts
  • apps/meteor/ee/server/hooks/federation/index.ts
  • apps/meteor/app/lib/server/functions/createRoom.ts
🧠 Learnings (7)
📓 Common learnings
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: rodrigok
Repo: RocketChat/Rocket.Chat PR: 36991
File: apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts:219-221
Timestamp: 2025-09-19T15:15:04.642Z
Learning: The Federation_Matrix_homeserver_domain setting in apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts is part of the old federation system and is being deprecated/removed, so configuration issues with this setting should not be flagged for improvement.
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.
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 37357
File: ee/packages/federation-matrix/src/setup.ts:103-120
Timestamp: 2025-11-05T21:04:35.787Z
Learning: In Rocket.Chat's federation-matrix setup (ee/packages/federation-matrix/src/setup.ts and apps/meteor/ee/server/startup/federation.ts), configureFederationMatrixSettings does not need to be called before setupFederationMatrix. The SDK's init() establishes infrastructure (database, event handlers, APIs) first, and the configuration can be applied later via settings watchers before actual federation events are processed. The config only matters when events actually occur, at which point all infrastructure is already configured.
📚 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:

  • ee/packages/federation-matrix/src/FederationMatrix.ts
  • apps/meteor/ee/server/hooks/federation/index.ts
  • apps/meteor/app/lib/server/functions/createRoom.ts
📚 Learning: 2025-09-19T15:15:04.642Z
Learnt from: rodrigok
Repo: RocketChat/Rocket.Chat PR: 36991
File: apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts:219-221
Timestamp: 2025-09-19T15:15:04.642Z
Learning: The Federation_Matrix_homeserver_domain setting in apps/meteor/server/services/federation/infrastructure/rocket-chat/adapters/Settings.ts is part of the old federation system and is being deprecated/removed, so configuration issues with this setting should not be flagged for improvement.

Applied to files:

  • ee/packages/federation-matrix/src/FederationMatrix.ts
  • apps/meteor/ee/server/hooks/federation/index.ts
  • apps/meteor/app/lib/server/functions/createRoom.ts
📚 Learning: 2025-11-05T21:04:35.787Z
Learnt from: sampaiodiego
Repo: RocketChat/Rocket.Chat PR: 37357
File: ee/packages/federation-matrix/src/setup.ts:103-120
Timestamp: 2025-11-05T21:04:35.787Z
Learning: In Rocket.Chat's federation-matrix setup (ee/packages/federation-matrix/src/setup.ts and apps/meteor/ee/server/startup/federation.ts), configureFederationMatrixSettings does not need to be called before setupFederationMatrix. The SDK's init() establishes infrastructure (database, event handlers, APIs) first, and the configuration can be applied later via settings watchers before actual federation events are processed. The config only matters when events actually occur, at which point all infrastructure is already configured.

Applied to files:

  • ee/packages/federation-matrix/src/FederationMatrix.ts
  • apps/meteor/ee/server/hooks/federation/index.ts
  • apps/meteor/app/lib/server/functions/createRoom.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/FederationMatrix.ts
  • apps/meteor/ee/server/hooks/federation/index.ts
  • apps/meteor/app/lib/server/functions/createRoom.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:

  • ee/packages/federation-matrix/src/FederationMatrix.ts
  • apps/meteor/app/lib/server/functions/createRoom.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:

  • ee/packages/federation-matrix/src/FederationMatrix.ts
  • apps/meteor/app/lib/server/functions/createRoom.ts
🧬 Code graph analysis (2)
ee/packages/federation-matrix/src/FederationMatrix.ts (2)
ee/packages/federation-matrix/src/index.ts (3)
  • validateFederatedUsername (3-3)
  • FederationValidationError (5-5)
  • isFederationDomainAllowed (11-11)
ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts (1)
  • isFederationDomainAllowed (20-38)
apps/meteor/ee/server/hooks/federation/index.ts (2)
ee/packages/federation-matrix/src/api/middlewares/isFederationDomainAllowed.ts (1)
  • isFederationDomainAllowedForUsernames (40-50)
ee/packages/federation-matrix/src/FederationMatrix.ts (1)
  • FederationMatrix (138-924)
⏰ 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 comments (3)
apps/meteor/ee/server/hooks/federation/index.ts (1)

90-97: LGTM!

The domain allowlist check is correctly positioned after the authorization check and properly throws MeteorError for user-initiated actions. Based on learnings, this pattern is correct for federation permission checks in user-initiated flows.

ee/packages/federation-matrix/src/FederationMatrix.ts (2)

211-229: LGTM!

The validateFederatedUsers method correctly:

  1. Validates format upfront, providing clear error messages for invalid federated usernames
  2. Returns early for empty arrays
  3. Validates each federated user via the SDK

The callers pre-filter to federated usernames before calling this method, which aligns with the expected input.


892-916: LGTM!

The enhanced verifyMatrixIds method now properly:

  1. Enforces the domain allowlist before attempting validation (fail-fast)
  2. Maps SDK error codes to appropriate verification statuses
  3. Falls back to UNABLE_TO_VERIFY for unexpected errors

The error code mapping aligns with the PR objectives for pre-federation validation (CONNECTION_FAILED → UNABLE_TO_VERIFY, USER_NOT_FOUND → UNVERIFIED, POLICY_DENIED → POLICY_DENIED).

Comment on lines +207 to +224
const isAllowed = await isFederationDomainAllowedForUsernames(members);
if (!isAllowed) {
throw new Meteor.Error(
'federation-policy-denied',
"Action Blocked. Communication with one of the domains in the list is restricted by your organization's security policy.",
{ method: 'createRoom' },
);
}

try {
const federatedUsers = members.filter((username) => username.includes(':'));
await FederationMatrix.validateFederatedUsers(federatedUsers);
} catch (error) {
if (error instanceof FederationValidationError) {
throw new Meteor.Error(error.error, error.userMessage);
}
throw error;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Inconsistent error class usage: Meteor.Error vs MeteorError.

Lines 209 and 221 use Meteor.Error, but Meteor is not explicitly imported. The file imports MeteorError from @rocket.chat/core-services (line 1) and uses it correctly in lines 93-97.

For consistency with the rest of the file and to ensure TypeScript type checking works correctly, use MeteorError instead.

-			throw new Meteor.Error(
+			throw new MeteorError(
 				'federation-policy-denied',
 				"Action Blocked. Communication with one of the domains in the list is restricted by your organization's security policy.",
-				{ method: 'createRoom' },
 			);
 		}

 		try {
 			const federatedUsers = members.filter((username) => username.includes(':'));
 			await FederationMatrix.validateFederatedUsers(federatedUsers);
 		} catch (error) {
 			if (error instanceof FederationValidationError) {
-				throw new Meteor.Error(error.error, error.userMessage);
+				throw new MeteorError(error.error, error.userMessage);
 			}
 			throw error;
 		}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const isAllowed = await isFederationDomainAllowedForUsernames(members);
if (!isAllowed) {
throw new Meteor.Error(
'federation-policy-denied',
"Action Blocked. Communication with one of the domains in the list is restricted by your organization's security policy.",
{ method: 'createRoom' },
);
}
try {
const federatedUsers = members.filter((username) => username.includes(':'));
await FederationMatrix.validateFederatedUsers(federatedUsers);
} catch (error) {
if (error instanceof FederationValidationError) {
throw new Meteor.Error(error.error, error.userMessage);
}
throw error;
}
const isAllowed = await isFederationDomainAllowedForUsernames(members);
if (!isAllowed) {
throw new MeteorError(
'federation-policy-denied',
"Action Blocked. Communication with one of the domains in the list is restricted by your organization's security policy.",
);
}
try {
const federatedUsers = members.filter((username) => username.includes(':'));
await FederationMatrix.validateFederatedUsers(federatedUsers);
} catch (error) {
if (error instanceof FederationValidationError) {
throw new MeteorError(error.error, error.userMessage);
}
throw error;
}
🤖 Prompt for AI Agents
In apps/meteor/ee/server/hooks/federation/index.ts around lines 207 to 224,
replace uses of Meteor.Error with the imported MeteorError to match the rest of
the file and TypeScript types; update both throw sites so they construct and
throw MeteorError with the same arguments (code, user-facing message, optional
details) and ensure the existing import of MeteorError from
@rocket.chat/core-services is used (no new import needed).

@scuciatto scuciatto added this to the 7.14.0 milestone Dec 1, 2025
@jessicaschelly jessicaschelly added the stat: QA assured Means it has been tested and approved by a company insider label Dec 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stat: conflict stat: QA assured Means it has been tested and approved by a company insider

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants