Skip to content

feat(federation): validate user email domain#38356

Merged
sampaiodiego merged 6 commits intodevelopfrom
federation-validate-user-domain
Feb 10, 2026
Merged

feat(federation): validate user email domain#38356
sampaiodiego merged 6 commits intodevelopfrom
federation-validate-user-domain

Conversation

@sampaiodiego
Copy link
Member

@sampaiodiego sampaiodiego commented Jan 26, 2026

Proposed changes (including videos or screenshots)

Create a new setting with an extra layer of validation to restrict the usage of federation to only users with a validated email address that matches the configured federation domain.

Issue(s)

FEDCORE-42

Steps to test or reproduce

Further comments

Summary by CodeRabbit

  • New Features

    • Admin setting to optionally validate users' email domains for federation access.
  • Refactor

    • Federation access checks now route through a centralized federation matrix that combines permission checks with optional domain validation.
  • Tests

    • Added comprehensive end-to-end tests covering verified/unverified/mismatched/missing emails and remote invitation scenarios.

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Jan 26, 2026

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

@changeset-bot
Copy link

changeset-bot bot commented Jan 26, 2026

🦋 Changeset detected

Latest commit: c2ece5b

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

This PR includes changesets to release 40 packages
Name Type
@rocket.chat/meteor Minor
@rocket.chat/core-typings Minor
@rocket.chat/rest-typings Minor
@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 Major
@rocket.chat/gazzodown Major
@rocket.chat/http-router Patch
@rocket.chat/livechat Patch
@rocket.chat/model-typings Patch
@rocket.chat/ui-avatar Major
@rocket.chat/ui-client Major
@rocket.chat/ui-contexts Major
@rocket.chat/ui-voip Major
@rocket.chat/web-ui-registration Major
@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/federation-matrix 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/models Patch
@rocket.chat/network-broker Patch
@rocket.chat/omni-core-ee Patch
@rocket.chat/mock-providers Patch
@rocket.chat/ui-video-conf Major
@rocket.chat/instance-status Patch
@rocket.chat/omni-core 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
Contributor

coderabbitai bot commented Jan 26, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Replaces direct access-federation permission checks with FederationMatrix.canUserAccessFederation(user); adds Federation_Service_Validate_User_Domain setting and implements optional email-domain + verification gating in FederationMatrix; updates callers, service typings, and E2E tests to use the new check.

Changes

Cohort / File(s) Summary
Callsites updated
apps/meteor/app/lib/server/functions/createRoom.ts, apps/meteor/ee/server/hooks/federation/index.ts, ee/packages/federation-matrix/src/api/_matrix/invite.ts, apps/meteor/server/services/room/service.ts
Replaced direct Authorization.hasPermission / hasPermissionAsync checks for access-federation with FederationMatrix.canUserAccessFederation(user); adjusted imports and RoomService.join parameter typing to accept full IUser.
Federation matrix core
ee/packages/federation-matrix/src/FederationMatrix.ts
Added private validateUserDomain: boolean, wired setting listener for Federation_Service_Validate_User_Domain, and new method canUserAccessFederation(user: IUser): Promise<boolean> implementing layered checks: permission → optional verified-email + domain match.
Settings & types
apps/meteor/server/settings/federation-service.ts, packages/core-services/src/types/IFederationMatrixService.ts
Added boolean setting Federation_Service_Validate_User_Domain (enterprise, default false) and exposed canUserAccessFederation(user): Promise<boolean> in IFederationMatrixService.
Tests
ee/packages/federation-matrix/tests/end-to-end/permissions.spec.ts
Large E2E suite added to validate the new setting across verified/unverified/matching/non-matching emails for federated room creation, user additions, and remote invites; added helper imports (e.g., getSubscriptionByRoomId).
Misc / Manifest
.changeset/..., package.json, single-line manifest edits
Added changeset entry and minor manifest adjustments related to the new setting and interface changes.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as Caller (Room/Invite/Hook)
    participant FederationMatrix as FederationMatrix
    participant Authorization as Authorization Service
    participant Settings as Settings Store

    Caller->>FederationMatrix: canUserAccessFederation(user)
    FederationMatrix->>Authorization: hasPermission(user._id, 'access-federation')
    Authorization-->>FederationMatrix: permissionResult

    alt permissionResult = false
        FederationMatrix-->>Caller: false
    else permissionResult = true
        FederationMatrix->>Settings: read Federation_Service_Validate_User_Domain
        Settings-->>FederationMatrix: flagValue

        alt flagValue = true
            FederationMatrix->>FederationMatrix: check user's verified email & domain == serverName
            alt email verified && domain matches
                FederationMatrix-->>Caller: true
            else
                FederationMatrix-->>Caller: false
            end
        else flagValue = false
            FederationMatrix-->>Caller: true
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I hopped through code to guard the gate,
Checking domains and if emails validate,
Matrix hums a careful tune,
Letting in the dawn or closing soon,
🥕 A tiny rabbit keeps federation straight.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat(federation): validate user email domain' directly and clearly describes the primary change—adding email domain validation for federation access.
Linked Issues check ✅ Passed The PR implements the core requirements from FEDCORE-42: adds a new Federation_Service_Validate_User_Domain setting, introduces canUserAccessFederation method with email domain and verification checks, and applies these controls across federation operations.
Out of Scope Changes check ✅ Passed All changes align with the stated objectives; modifications to permission checks, settings, and service interfaces are directly related to implementing the email domain validation feature.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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

codecov bot commented Jan 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.38%. Comparing base (c53312f) to head (c2ece5b).
⚠️ Report is 2 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #38356      +/-   ##
===========================================
+ Coverage    70.35%   70.38%   +0.02%     
===========================================
  Files         3162     3162              
  Lines       110705   110706       +1     
  Branches     19923    19933      +10     
===========================================
+ Hits         77892    77916      +24     
+ Misses       30788    30762      -26     
- Partials      2025     2028       +3     
Flag Coverage Δ
e2e 60.38% <ø> (-0.03%) ⬇️
e2e-api 47.77% <100.00%> (+0.04%) ⬆️
unit 71.37% <ø> (+0.02%) ⬆️

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.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 26, 2026

📦 Docker Image Size Report

➡️ Changes

Service Current Baseline Change Percent
sum of all images 0B 0B 0B
account-service 0B 0B 0B
authorization-service 0B 0B 0B
ddp-streamer-service 0B 0B 0B
omnichannel-transcript-service 0B 0B 0B
presence-service 0B 0B 0B
queue-worker-service 0B 0B 0B
rocketchat 0B 0B 0B

📊 Historical Trend

---
config:
  theme: "dark"
  xyChart:
    width: 900
    height: 400
---
xychart
  title "Image Size Evolution by Service (Last 30 Days + This PR)"
  x-axis ["11/18 22:53", "11/19 23:02", "11/21 16:49", "11/24 17:34", "11/27 22:32", "11/28 19:05", "12/01 23:01", "12/02 21:57", "12/03 21:00", "12/04 18:17", "12/05 21:56", "12/08 20:15", "12/09 22:17", "12/10 23:26", "12/11 21:56", "12/12 22:45", "12/13 01:34", "12/15 22:31", "12/16 22:18", "12/17 21:04", "12/18 23:12", "12/19 23:27", "12/20 21:03", "12/22 18:54", "12/23 16:16", "12/24 19:38", "12/25 17:51", "12/26 13:18", "12/29 19:01", "12/30 20:52", "02/10 20:41 (PR)"]
  y-axis "Size (GB)" 0 --> 0.5
  line "account-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.00]
  line "authorization-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.00]
  line "ddp-streamer-service" [0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.00]
  line "omnichannel-transcript-service" [0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.00]
  line "presence-service" [0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.11, 0.00]
  line "queue-worker-service" [0.14, 0.14, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.00]
  line "rocketchat" [0.35, 0.35, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.34, 0.00]
Loading

Statistics (last 30 days):

  • 📊 Average: 1.5GiB
  • ⬇️ Minimum: 1.4GiB
  • ⬆️ Maximum: 1.6GiB
  • 🎯 Current PR: 0B
ℹ️ About this report

This report compares Docker image sizes from this build against the develop baseline.

  • Tag: pr-38356
  • Baseline: develop
  • Timestamp: 2026-02-10 20:41:21 UTC
  • Historical data points: 30

Updated: Tue, 10 Feb 2026 20:41:22 GMT

@sampaiodiego sampaiodiego force-pushed the federation-validate-user-domain branch 2 times, most recently from fc57eb4 to 30988f5 Compare January 27, 2026 14:42
@sampaiodiego sampaiodiego marked this pull request as ready for review January 27, 2026 14:43
@sampaiodiego sampaiodiego requested a review from a team as a code owner January 27, 2026 14:43
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: 3

🤖 Fix all issues with AI agents
In `@apps/meteor/server/services/room/service.ts`:
- Line 152: RoomService.join expects a full IUser because
canUserAccessFederation reads user.emails; fix the two call sites so they pass a
complete user object: in the slashcommands-join caller (server.ts) include
emails in the Mongo projection when fetching the user (add "emails" to the
projection before calling RoomService.join), and in
getRoomByNameOrIdWithOptionToJoin adjust the parameter type (or the caller) so
it returns/passes a full IUser rather than Pick<IUser, '_id' | 'username' |
'federated' | 'federation'>; reference RoomService.join and
canUserAccessFederation when updating types/fetch logic to ensure user.emails is
present.

In `@ee/packages/federation-matrix/src/FederationMatrix.ts`:
- Around line 820-824: The domain comparison in the user email check is
case-sensitive; update the logic in the block using user.emails (the anonymous
callback that does email.address.split('@')[1]) to normalize both sides to the
same case before comparing: extract the domain safely from email.address, call
.toLowerCase() (or .toLocaleLowerCase()) on the extracted domain and on
this.serverName, then compare those lowercased values and keep the existing
email.verified requirement; ensure the code handles malformed addresses (no '@')
gracefully when extracting the domain.

In `@ee/packages/federation-matrix/tests/end-to-end/permissions.spec.ts`:
- Around line 711-713: The test is incorrectly checking subscription.name
against the invited user's username; change the lookup to match the room name
instead. In the getSubscriptions result (subscriptions.update) replace the
predicate used to find invitedSub (currently (sub) => sub.name ===
userWithNonMatchingEmail.username) with a check against the channel name, e.g.
(sub) => sub.fname?.includes(channelName) or (sub) => sub.name === channelName
so the test verifies the room subscription was rejected rather than relying on
username mismatch.

Copy link
Contributor

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

Choose a reason for hiding this comment

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

No issues found across 8 files

ggazzo
ggazzo previously approved these changes Jan 27, 2026
@ggazzo ggazzo added this to the 8.2.0 milestone Jan 27, 2026
@ggazzo ggazzo added the stat: QA assured Means it has been tested and approved by a company insider label Jan 27, 2026
@dionisio-bot dionisio-bot bot added stat: ready to merge PR tested and approved waiting for merge stat: QA assured Means it has been tested and approved by a company insider and removed 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 labels Jan 27, 2026
@sampaiodiego sampaiodiego removed the stat: QA assured Means it has been tested and approved by a company insider label Jan 27, 2026
@dionisio-bot dionisio-bot bot removed the stat: ready to merge PR tested and approved waiting for merge label Jan 27, 2026
@sampaiodiego sampaiodiego added the stat: QA assured Means it has been tested and approved by a company insider label Jan 27, 2026
@dionisio-bot dionisio-bot bot added the stat: ready to merge PR tested and approved waiting for merge label Jan 27, 2026
@sampaiodiego sampaiodiego force-pushed the federation-validate-user-domain branch 2 times, most recently from 05925f3 to cc112ef Compare January 27, 2026 21:25
@sampaiodiego sampaiodiego marked this pull request as ready for review January 27, 2026 21:26
Copy link
Contributor

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

Choose a reason for hiding this comment

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

No issues found across 8 files

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

🤖 Fix all issues with AI agents
In `@ee/packages/federation-matrix/tests/end-to-end/permissions.spec.ts`:
- Around line 283-362: Combine the two beforeAll hooks into a single beforeAll
inside the "Federation_Service_Validate_User_Domain Setting" describe block:
move the permissions.grant POST (the
rc1AdminRequestConfig.request.post(api('permissions.update')) call) and the RC
user creation steps (creating rcValidUser1 and rcValidUser2 via createUser,
marking them verified with users.update, and obtaining their configs via
getRequestConfig) into one sequential beforeAll so all setup runs in one place;
ensure you preserve the existing order (grant permission first, then
create/verify users and call getRequestConfig) and keep references to
rcValidUser1, rcValidUser2, rc1AdminRequestConfig, createUser, and
getRequestConfig intact.

@sampaiodiego sampaiodiego force-pushed the federation-validate-user-domain branch 2 times, most recently from 54367e9 to 121765e Compare January 28, 2026 18:00
ggazzo
ggazzo previously approved these changes Jan 28, 2026
Copy link
Member

@KevLehman KevLehman left a comment

Choose a reason for hiding this comment

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

Missing changeset :p

KevLehman
KevLehman previously approved these changes Feb 10, 2026
@dionisio-bot dionisio-bot bot removed the stat: ready to merge PR tested and approved waiting for merge label Feb 10, 2026
@sampaiodiego sampaiodiego added the stat: ready to merge PR tested and approved waiting for merge label Feb 10, 2026
@sampaiodiego sampaiodiego merged commit ba2ea2b into develop Feb 10, 2026
44 checks passed
@sampaiodiego sampaiodiego deleted the federation-validate-user-domain branch February 10, 2026 21:43
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.

4 participants