Skip to content

Comments

chore: remove Meteor user invocation from rest api #38017

Merged
ggazzo merged 6 commits intodevelopfrom
chore/remove-invocation-from-rest
Jan 28, 2026
Merged

chore: remove Meteor user invocation from rest api #38017
ggazzo merged 6 commits intodevelopfrom
chore/remove-invocation-from-rest

Conversation

@ggazzo
Copy link
Member

@ggazzo ggazzo commented Dec 30, 2025

rocketchat.atlassian.net/browse/ARCH-1654

Proposed changes (including videos or screenshots)

Issue(s)

Steps to test or reproduce

Further comments

Summary by CodeRabbit

  • Refactor
    • Improved two-factor authentication processing with cleaner error handling and context management.
    • Enhanced tracking of who performs user operations for better audit trails and event logging.
    • Optimized API route execution with improved Meteor context handling for authenticated operations.
    • Removed internal utility dependencies to reduce code complexity.

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

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Dec 30, 2025

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

  • This PR is targeting the wrong base branch. It should target 8.2.0, but it targets 8.1.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 Dec 30, 2025

⚠️ No Changeset found

Latest commit: 468ab81

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 Dec 30, 2025

Walkthrough

Refactors APIClass to replace implicit Meteor context dependency with explicit parameters. Removes safeGetMeteorUser utility, introducing performedBy parameter passing throughout user creation flow. Adds applyMeteorContext option flag and new createMeteorInvocation static helper for conditional Meteor context handling in routes.

Changes

Cohort / File(s) Summary
API Class Refactoring
apps/meteor/app/api/server/ApiClass.ts, apps/meteor/app/api/server/definition.ts
Refactored processTwoFactor to drop invocation parameter and return boolean instead of void. Added new static helper createMeteorInvocation to construct Meteor DDP invocation with account registration. Added optional applyMeteorContext field to SharedOptions and twoFactorChecked to ActionThis.
Route Updates
apps/meteor/app/api/server/v1/misc.ts, apps/meteor/ee/server/apps/communication/rest.ts
Enabled applyMeteorContext: true on method.call routes (authenticated and anonymous) and AppsRestApi management routes. Changed response construction to directly await Meteor.callAsync within mountResult.
User Creation Flow
apps/meteor/app/lib/server/functions/saveUser/saveNewUser.ts, apps/meteor/app/lib/server/functions/saveUser/saveUser.ts
Extended saveNewUser signature to accept new performedBy: IUser parameter. Introduced findUserById helper in saveUser. Updated saveUser to compute performedBy explicitly and pass to saveNewUser and afterSaveUser event payloads.
Dependency Removal & Updates
apps/meteor/app/utils/server/functions/safeGetMeteorUser.ts, apps/meteor/app/authentication/server/startup/index.js
Removed safeGetMeteorUser utility entirely. Updated post-user-created event to use options.performedBy instead of implicit Meteor user context.
Room Type Updates
apps/meteor/server/lib/rooms/roomTypes/direct.ts
Removed Meteor dependency and getCurrentUserId helper. Renamed userId parameter to uid and updated roomName logic to use uid directly when provided, with fallback to generic subscription lookup.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • ricardogarim
  • KevLehman

Poem

🐰 Hops through the code with newfound grace,
No more implicit Meteor space—
PerformedBy now explicit and clear,
Meteor context when needed here,
Cleaner flows as we disappear!

🚥 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 title 'chore: remove Meteor user invocation from rest api' is specific and reflects a primary change: removing Meteor user invocation logic from the REST API layer, which aligns with the refactoring shown across APIClass and related files.
Linked Issues check ✅ Passed The PR refactors APIClass error-handling by removing safeGetMeteorUser and inlining Meteor invocation logic into a new createMeteorInvocation helper, which addresses the ARCH-1654 objective to refactor try/catch to prevent internal server errors.
Out of Scope Changes check ✅ Passed All changes are in-scope: the APIClass refactoring, the new createMeteorInvocation helper, processTwoFactor signature update, applyMeteorContext additions to routes, and the removal of safeGetMeteorUser all directly support the Meteor invocation removal objective.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/remove-invocation-from-rest

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 Dec 30, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.78%. Comparing base (f4d7cc7) to head (468ab81).
⚠️ Report is 3 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #38017      +/-   ##
===========================================
- Coverage    70.78%   70.78%   -0.01%     
===========================================
  Files         3159     3159              
  Lines       109388   109384       -4     
  Branches     19710    19674      -36     
===========================================
- Hits         77429    77423       -6     
- Misses       29928    29936       +8     
+ Partials      2031     2025       -6     
Flag Coverage Δ
unit 71.96% <ø> (-0.01%) ⬇️

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 Dec 30, 2025

📦 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", "01/27 19:25 (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-38017
  • Baseline: develop
  • Timestamp: 2026-01-27 19:25:03 UTC
  • Historical data points: 30

Updated: Tue, 27 Jan 2026 19:25:04 GMT

@d-gubert d-gubert changed the title chore: remove user invocation from rest api chore: remove Meteor user invocation from rest api Jan 8, 2026
@ggazzo ggazzo force-pushed the chore/remove-invocation-from-rest branch from c2fea9d to adde004 Compare January 26, 2026 14:49
@ggazzo ggazzo force-pushed the chore/remove-invocation-from-rest branch 2 times, most recently from 1432e63 to 617afd0 Compare January 27, 2026 13:18
@ggazzo ggazzo changed the base branch from develop to chore/stop-using-ids-for-functions January 27, 2026 13:18
@ggazzo ggazzo force-pushed the chore/stop-using-ids-for-functions branch 2 times, most recently from c0f1958 to 671e348 Compare January 27, 2026 13:30
@ggazzo ggazzo force-pushed the chore/remove-invocation-from-rest branch from 617afd0 to 34c0088 Compare January 27, 2026 13:34
@ggazzo ggazzo force-pushed the chore/stop-using-ids-for-functions branch from 671e348 to d531c0e Compare January 27, 2026 13:47
@ggazzo ggazzo force-pushed the chore/remove-invocation-from-rest branch 3 times, most recently from 32d30db to c203b32 Compare January 27, 2026 19:11
@ggazzo ggazzo marked this pull request as ready for review January 27, 2026 19:56
@ggazzo ggazzo requested a review from a team as a code owner January 27, 2026 19:56
@ggazzo ggazzo added this to the 8.2.0 milestone Jan 27, 2026
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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/meteor/server/lib/rooms/roomTypes/direct.ts (1)

54-72: Mark uid parameter as optional in the function signature to match the interface contract.

The roomName method in direct.ts should mark the uid parameter as optional (uid?) to match the IRoomTypeServerDirectives interface definition, which declares userId?: string. Currently, the signature async roomName(room, uid) doesn't reflect this, even though the implementation handles the undefined case with a fallback (picking any subscription). While the fallback behavior is intentional, the type signature should accurately reflect that uid is optional.

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

15-30: Store only the minimal identifier for audit trail instead of the full user object.

Accounts.createUserAsync will persist the performedBy object directly to the user document, which includes the services field containing sensitive data (OAuth tokens, login tokens, password hashes, 2FA credentials). This risks PII leakage and unnecessarily bloats the user document. Since performedBy is not queried from user records anywhere, it should store only essential audit information.

Follow the codebase pattern (e.g., createdBy in other domains) and persist a minimal identifier:

Suggested fix
-		performedBy,
+		performedBy: { _id: performedBy._id, username: performedBy.username, name: performedBy.name },
🤖 Fix all issues with AI agents
In `@apps/meteor/app/api/server/definition.ts`:
- Line 195: The readonly property twoFactorChecked is declared as a non-optional
boolean but not initialized; set a default (e.g. initialize twoFactorChecked =
false as a property initializer or assign this.twoFactorChecked = false inside
the class constructor) so the non-optional type cannot be undefined at runtime;
ensure you update the class that declares readonly twoFactorChecked accordingly
(initialize in the constructor if readonly must be set there).

In `@apps/meteor/app/authentication/server/startup/index.js`:
- Around line 380-385: The IPostUserCreated event is being called with
performedBy possibly undefined because many callers of Accounts.insertUserDoc
(e.g., SAML.ts, registerUser.ts, createNewUser.ts, UserConverter.ts) don't pass
performedBy; update the insertUserDoc call sites to accept and forward a
required performedBy (or derive a sensible default like the current user id or a
system user id) and ensure the startup code that triggers
Apps.self.triggerEvent(AppEvents.IPostUserCreated, { user, performedBy:
options.performedBy }) always supplies a non-undefined performedBy;
specifically, add performedBy to the insertUserDoc signature/parameters where
missing, propagate it through user creation flows, and/or set
options.performedBy to a default before calling Apps.self?.triggerEvent so
IPostUserCreated receives a valid actor identifier.

readonly queryOperations: TOptions extends { queryOperations: infer T } ? T : never;
readonly queryFields: TOptions extends { queryFields: infer T } ? T : never;

readonly twoFactorChecked: boolean;
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

🧩 Analysis chain

🏁 Script executed:

rg -n "twoFactorChecked" -C3 apps/meteor/app/api/server

Repository: RocketChat/Rocket.Chat

Length of output: 1145


Initialize twoFactorChecked with a default boolean
Assign a default value (e.g. this.twoFactorChecked = false; in the class constructor or as a property initializer) so the non-optional type never yields undefined at runtime.

🤖 Prompt for AI Agents
In `@apps/meteor/app/api/server/definition.ts` at line 195, The readonly property
twoFactorChecked is declared as a non-optional boolean but not initialized; set
a default (e.g. initialize twoFactorChecked = false as a property initializer or
assign this.twoFactorChecked = false inside the class constructor) so the
non-optional type cannot be undefined at runtime; ensure you update the class
that declares readonly twoFactorChecked accordingly (initialize in the
constructor if readonly must be set there).

Comment on lines 380 to 385
if (!options.skipAppsEngineEvent) {
// `post` triggered events don't need to wait for the promise to resolve
Apps.self?.triggerEvent(AppEvents.IPostUserCreated, { user, performedBy: await safeGetMeteorUser() }).catch((e) => {
Apps.self?.triggerEvent(AppEvents.IPostUserCreated, { user, performedBy: options.performedBy }).catch((e) => {
Apps.self?.getRocketChatLogger().error({ msg: 'Error while executing post user created event', err: e });
});
}
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 | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for calls to insertUserDoc and inspect arguments
rg -nP --type=ts --type=js -C3 'insertUserDoc\s*\(' | head -100

Repository: RocketChat/Rocket.Chat

Length of output: 3583


🏁 Script executed:

sed -n '350,430p' apps/meteor/app/authentication/server/startup/index.js

Repository: RocketChat/Rocket.Chat

Length of output: 2581


Ensure performedBy is passed to IPostUserCreated event.

Several Accounts.insertUserDoc call sites (e.g. SAML.ts, registerUser.ts, createNewUser.ts, UserConverter.ts) invoke insertUserDoc({…}, user) without supplying performedBy, causing the IPostUserCreated event to receive undefined. Require callers to include a valid performedBy or provide a sensible default before triggering the event.

🤖 Prompt for AI Agents
In `@apps/meteor/app/authentication/server/startup/index.js` around lines 380 -
385, The IPostUserCreated event is being called with performedBy possibly
undefined because many callers of Accounts.insertUserDoc (e.g., SAML.ts,
registerUser.ts, createNewUser.ts, UserConverter.ts) don't pass performedBy;
update the insertUserDoc call sites to accept and forward a required performedBy
(or derive a sensible default like the current user id or a system user id) and
ensure the startup code that triggers
Apps.self.triggerEvent(AppEvents.IPostUserCreated, { user, performedBy:
options.performedBy }) always supplies a non-undefined performedBy;
specifically, add performedBy to the insertUserDoc signature/parameters where
missing, propagate it through user creation flows, and/or set
options.performedBy to a default before calling Apps.self?.triggerEvent so
IPostUserCreated receives a valid actor identifier.

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 12 files

token?: string,
) {
const invocation = new DDPCommon.MethodInvocation({
connection,
Copy link
Member

Choose a reason for hiding this comment

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

not totally sure, so maybe worth it for another PR, but I think we can generate the connection only on this context, so we could remove it from:

const connection = { ...generateConnection(this.requestIp, this.request.headers), token: this.token };
this.connection = connection;

sampaiodiego
sampaiodiego previously approved these changes 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
Base automatically changed from chore/stop-using-ids-for-functions to develop January 28, 2026 13:47
@ggazzo ggazzo dismissed sampaiodiego’s stale review January 28, 2026 13:47

The base branch was changed.

@ggazzo ggazzo force-pushed the chore/remove-invocation-from-rest branch from c203b32 to 468ab81 Compare January 28, 2026 13:49
@ggazzo ggazzo merged commit 464adcb into develop Jan 28, 2026
24 checks passed
@ggazzo ggazzo deleted the chore/remove-invocation-from-rest branch January 28, 2026 13:59
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.

2 participants