chore: Enforce username over users inside endpoint context#39266
chore: Enforce username over users inside endpoint context#39266
Conversation
|
Looks like this PR is ready to merge! 🎉 |
|
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds a Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Router as "API Router"
participant ApiClass as "ApiClass (auth)"
participant Action as "Route Action"
participant AuditDB as "Audit/DB"
Client->>Router: HTTP request
Router->>ApiClass: dispatch request
ApiClass->>ApiClass: authenticate user
alt authRequired && not userWithoutUsername
ApiClass->>ApiClass: ensure user.username present
ApiClass-->>Client: 401 Unauthorized (if missing)
end
ApiClass->>Action: invoke action (this.user may lack username)
Action->>AuditDB: updateAuditedByUser(username: this.user.username)
Action-->>Client: success response
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
af3651b to
7d48050
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #39266 +/- ##
===========================================
+ Coverage 70.85% 70.89% +0.03%
===========================================
Files 3208 3208
Lines 113431 113432 +1
Branches 20542 20549 +7
===========================================
+ Hits 80376 80421 +45
+ Misses 31004 30961 -43
+ Partials 2051 2050 -1
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
…nhanced flexibility
… userWithoutUsername option to additional API routes
There was a problem hiding this comment.
🧹 Nitpick comments (1)
apps/meteor/app/api/server/ApiClass.ts (1)
829-857: Runtime username enforcement looks correct.The type guard and check ensure authenticated users have a username unless the route explicitly opts out via
userWithoutUsername. This aligns well with the updated type definitions.Minor observation: the
isUserWithUsernametype guard is defined inside the action handler, meaning it's recreated on each request. Consider hoisting it to module scope for a minor efficiency gain.,
♻️ Optional: Hoist type guard to module scope
+const isUserWithUsername = (user: IUser | null): user is Omit<IUser, 'username'> & Required<Pick<IUser, 'username'>> => { + return user !== null && typeof user === 'object' && 'username' in user && user.username !== undefined; +}; + export class APIClass<TBasePath extends string = '', TOperations extends Record<string, unknown> = Record<string, never>> {Then remove the inline definition at lines 830-832.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/meteor/app/api/server/ApiClass.ts` around lines 829 - 857, The inline type guard isUserWithUsername (user: IUser | null): user is Omit<IUser, 'username'> & Required<Pick<IUser, 'username'>>) should be hoisted to module scope to avoid recreating it per request; move its declaration out of the action handler into the top-level of the module, export or keep it private as needed, then remove the inline definition inside the handler and keep the existing runtime check (if (user && !options.userWithoutUsername && !isUserWithUsername(user)) ...) unchanged so it uses the hoisted helper.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@apps/meteor/app/api/server/ApiClass.ts`:
- Around line 829-857: The inline type guard isUserWithUsername (user: IUser |
null): user is Omit<IUser, 'username'> & Required<Pick<IUser, 'username'>>)
should be hoisted to module scope to avoid recreating it per request; move its
declaration out of the action handler into the top-level of the module, export
or keep it private as needed, then remove the inline definition inside the
handler and keep the existing runtime check (if (user &&
!options.userWithoutUsername && !isUserWithUsername(user)) ...) unchanged so it
uses the hoisted helper.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
apps/meteor/app/api/server/ApiClass.tsapps/meteor/app/api/server/definition.tsapps/meteor/app/api/server/v1/assets.tsapps/meteor/app/api/server/v1/misc.tsapps/meteor/app/api/server/v1/settings.tsapps/meteor/app/api/server/v1/users.tsapps/meteor/app/api/server/v1/videoConference.tsapps/meteor/app/livechat/imports/server/rest/appearance.tsapps/meteor/app/livechat/server/api/v1/integration.tsapps/meteor/ee/server/api/licenses.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: cubic · AI code reviewer
- GitHub Check: cubic · AI code reviewer
- GitHub Check: cubic · AI code reviewer
- GitHub Check: cubic · AI code reviewer
- GitHub Check: cubic · AI code reviewer
- GitHub Check: cubic · AI code reviewer
- GitHub Check: cubic · AI code reviewer
- GitHub Check: cubic · AI code reviewer
- GitHub Check: cubic · AI code reviewer
- GitHub Check: cubic · AI code reviewer
🧰 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:
apps/meteor/app/api/server/v1/settings.tsapps/meteor/ee/server/api/licenses.tsapps/meteor/app/api/server/v1/assets.tsapps/meteor/app/api/server/v1/users.tsapps/meteor/app/livechat/imports/server/rest/appearance.tsapps/meteor/app/api/server/v1/misc.tsapps/meteor/app/livechat/server/api/v1/integration.tsapps/meteor/app/api/server/v1/videoConference.tsapps/meteor/app/api/server/definition.tsapps/meteor/app/api/server/ApiClass.ts
🧠 Learnings (19)
📚 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:
apps/meteor/app/api/server/v1/settings.ts
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.
Applied to files:
apps/meteor/app/api/server/v1/settings.tsapps/meteor/ee/server/api/licenses.tsapps/meteor/app/api/server/v1/assets.tsapps/meteor/app/livechat/imports/server/rest/appearance.tsapps/meteor/app/livechat/server/api/v1/integration.tsapps/meteor/app/api/server/v1/videoConference.tsapps/meteor/app/api/server/definition.ts
📚 Learning: 2025-11-07T14:50:33.544Z
Learnt from: KevLehman
Repo: RocketChat/Rocket.Chat PR: 37423
File: packages/i18n/src/locales/en.i18n.json:18-18
Timestamp: 2025-11-07T14:50:33.544Z
Learning: Rocket.Chat settings: in apps/meteor/ee/server/settings/abac.ts, the Abac_Cache_Decision_Time_Seconds setting uses invalidValue: 0 as the fallback when ABAC is unlicensed. With a valid license, admins can still set the value to 0 to intentionally disable the ABAC decision cache.
Applied to files:
apps/meteor/app/api/server/v1/settings.tsapps/meteor/ee/server/api/licenses.ts
📚 Learning: 2026-02-23T17:53:06.802Z
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 35995
File: apps/meteor/app/api/server/v1/rooms.ts:1107-1112
Timestamp: 2026-02-23T17:53:06.802Z
Learning: During PR reviews that touch endpoint files under apps/meteor/app/api/server/v1, enforce strict scope: if a PR targets a specific endpoint (e.g., rooms.favorite), do not propose changes to unrelated endpoints (e.g., rooms.invite) unless maintainers explicitly request them. Focus feedback on the touched endpoint's behavior, API surface, and related tests; avoid broad cross-endpoint changes in the same PR unless requested.
Applied to files:
apps/meteor/app/api/server/v1/settings.tsapps/meteor/app/api/server/v1/assets.tsapps/meteor/app/api/server/v1/users.tsapps/meteor/app/api/server/v1/misc.tsapps/meteor/app/api/server/v1/videoConference.ts
📚 Learning: 2026-02-24T19:09:01.522Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38974
File: apps/meteor/app/api/server/v1/im.ts:220-221
Timestamp: 2026-02-24T19:09:01.522Z
Learning: In Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1, avoid introducing logic changes. Only perform scope-tight changes that preserve behavior; style-only cleanups (e.g., removing inline comments) may be deferred to follow-ups to keep the migration PR focused.
Applied to files:
apps/meteor/app/api/server/v1/settings.tsapps/meteor/app/api/server/v1/assets.tsapps/meteor/app/api/server/v1/users.tsapps/meteor/app/api/server/v1/misc.tsapps/meteor/app/api/server/v1/videoConference.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.
Applied to files:
apps/meteor/app/api/server/v1/settings.tsapps/meteor/ee/server/api/licenses.tsapps/meteor/app/api/server/v1/assets.tsapps/meteor/app/api/server/v1/users.tsapps/meteor/app/livechat/imports/server/rest/appearance.tsapps/meteor/app/api/server/v1/misc.tsapps/meteor/app/livechat/server/api/v1/integration.tsapps/meteor/app/api/server/v1/videoConference.tsapps/meteor/app/api/server/definition.tsapps/meteor/app/api/server/ApiClass.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.
Applied to files:
apps/meteor/app/api/server/v1/settings.tsapps/meteor/ee/server/api/licenses.tsapps/meteor/app/api/server/v1/assets.tsapps/meteor/app/api/server/v1/users.tsapps/meteor/app/livechat/imports/server/rest/appearance.tsapps/meteor/app/api/server/v1/misc.tsapps/meteor/app/livechat/server/api/v1/integration.tsapps/meteor/app/api/server/v1/videoConference.tsapps/meteor/app/api/server/definition.tsapps/meteor/app/api/server/ApiClass.ts
📚 Learning: 2026-02-25T20:10:16.987Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38913
File: packages/ddp-client/src/legacy/types/SDKLegacy.ts:34-34
Timestamp: 2026-02-25T20:10:16.987Z
Learning: In the RocketChat/Rocket.Chat monorepo, packages/ddp-client and apps/meteor do not use TypeScript project references. Module augmentations in apps/meteor (e.g., declare module 'rocket.chat/rest-typings') are not visible when compiling packages/ddp-client in isolation, which is why legacy SDK methods that depend on OperationResult types for OpenAPI-migrated endpoints must remain commented out.
Applied to files:
apps/meteor/app/api/server/v1/assets.tsapps/meteor/app/livechat/server/api/v1/integration.ts
📚 Learning: 2026-03-03T11:11:45.505Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39230
File: apps/meteor/app/api/server/v1/chat.ts:214-222
Timestamp: 2026-03-03T11:11:45.505Z
Learning: In apps/meteor/server/lib/moderation/reportMessage.ts, the reportMessage function validates that description is not empty or whitespace-only with `if (!description.trim())`. When migrating the chat.reportMessage endpoint to OpenAPI, adding minLength validation to the schema preserves this existing behavior.
Applied to files:
apps/meteor/app/livechat/imports/server/rest/appearance.tsapps/meteor/app/livechat/server/api/v1/integration.ts
📚 Learning: 2026-02-24T19:09:09.561Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38974
File: apps/meteor/app/api/server/v1/im.ts:220-221
Timestamp: 2026-02-24T19:09:09.561Z
Learning: In RocketChat/Rocket.Chat OpenAPI migration PRs for apps/meteor/app/api/server/v1 endpoints, maintainers prefer to avoid any logic changes; style-only cleanups (like removing inline comments) may be deferred to follow-ups to keep scope tight.
Applied to files:
apps/meteor/app/livechat/imports/server/rest/appearance.tsapps/meteor/app/livechat/server/api/v1/integration.tsapps/meteor/app/api/server/ApiClass.ts
📚 Learning: 2025-11-19T18:20:37.116Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37419
File: apps/meteor/server/services/media-call/service.ts:141-141
Timestamp: 2025-11-19T18:20:37.116Z
Learning: In apps/meteor/server/services/media-call/service.ts, the sendHistoryMessage method should use call.caller.id or call.createdBy?.id as the message author, not call.transferredBy?.id. Even for transferred calls, the message should appear in the DM between the two users who are calling each other, not sent by the person who transferred the call.
Applied to files:
apps/meteor/app/livechat/imports/server/rest/appearance.tsapps/meteor/app/livechat/server/api/v1/integration.tsapps/meteor/app/api/server/v1/videoConference.ts
📚 Learning: 2026-02-24T19:36:55.089Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 38493
File: apps/meteor/tests/e2e/page-objects/fragments/home-content.ts:60-82
Timestamp: 2026-02-24T19:36:55.089Z
Learning: In RocketChat/Rocket.Chat e2e tests (apps/meteor/tests/e2e/page-objects/fragments/home-content.ts), thread message preview listitems do not have aria-roledescription="message", so lastThreadMessagePreview locator cannot be scoped to messageListItems (which filters for aria-roledescription="message"). It should remain scoped to page.getByRole('listitem') or mainMessageList.getByRole('listitem').
Applied to files:
apps/meteor/app/livechat/imports/server/rest/appearance.tsapps/meteor/app/livechat/server/api/v1/integration.ts
📚 Learning: 2026-01-26T18:26:01.279Z
Learnt from: d-gubert
Repo: RocketChat/Rocket.Chat PR: 38227
File: apps/meteor/app/api/server/router.ts:44-49
Timestamp: 2026-01-26T18:26:01.279Z
Learning: In apps/meteor/app/api/server/router.ts, when retrieving bodyParams and queryParams from the Hono context via c.get(), do not add defensive defaults (e.g., ?? {}). The code should fail fast if these parameters are missing, as endpoint handlers expect them to be present and breaking here helps surface parsing problems rather than hiding them.
Applied to files:
apps/meteor/app/api/server/v1/misc.ts
📚 Learning: 2025-09-16T13:33:49.237Z
Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36890
File: apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts:21-26
Timestamp: 2025-09-16T13:33:49.237Z
Learning: The im.delete API endpoint accepts either a `roomId` parameter (requiring the actual DM room _id) or a `username` parameter (for the DM partner's username). Constructing slug-like identifiers like `user2${Users.userE2EE.data.username}` doesn't work for this endpoint.
Applied to files:
apps/meteor/app/api/server/v1/videoConference.ts
📚 Learning: 2025-09-16T13:33:49.237Z
Learnt from: cardoso
Repo: RocketChat/Rocket.Chat PR: 36890
File: apps/meteor/tests/e2e/e2e-encryption/e2ee-otr.spec.ts:21-26
Timestamp: 2025-09-16T13:33:49.237Z
Learning: In Rocket.Chat test files, the im.delete API endpoint accepts either a `roomId` parameter (requiring the actual DM room _id) or a `username` parameter (for the DM partner's username). It does not accept slug-like constructions such as concatenating usernames together.
Applied to files:
apps/meteor/app/api/server/v1/videoConference.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/api/server/v1/videoConference.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/api/server/v1/videoConference.ts
📚 Learning: 2025-09-15T06:21:00.139Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 36868
File: apps/meteor/app/apps/server/bridges/serverEndpoints.ts:35-48
Timestamp: 2025-09-15T06:21:00.139Z
Learning: In ServerEndpointsBridge.ts, the permission model distinguishes between token pass-through and true impersonation: `server-endpoints.call` is required for all endpoint access, while `server-endpoints.impersonate` is only required when `info.user.id` is provided without `info.user.token` (lines 48-53), meaning the bridge needs to mint a token. When both user ID and token are provided, it's considered legitimate credential usage, not impersonation.
Applied to files:
apps/meteor/app/api/server/definition.ts
📚 Learning: 2025-09-15T13:10:30.049Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 36868
File: packages/http-router/src/Router.ts:416-425
Timestamp: 2025-09-15T13:10:30.049Z
Learning: In packages/http-router/src/Router.ts, the dispatch() method's use of replaceAll('//', '/') on the full path is acceptable because URL normalization and query string handling is performed by the caller function before dispatch() is invoked.
Applied to files:
apps/meteor/app/api/server/ApiClass.ts
🧬 Code graph analysis (1)
apps/meteor/app/api/server/v1/videoConference.ts (1)
apps/meteor/app/authorization/server/functions/canSendMessage.ts (1)
canSendMessageAsync(54-66)
🔇 Additional comments (20)
apps/meteor/ee/server/api/licenses.ts (1)
59-64: LGTM!Removing the non-null assertion is safe here. Since this route has
authRequired: truewithoutuserWithoutUsername, the runtime check inApiClass.tsguaranteesusernameis present before this code executes.apps/meteor/app/api/server/definition.ts (3)
113-113: LGTM!The
userWithoutUsernameoption is correctly added to both union arms ofSharedOptions, ensuring it's available regardless of which branch of the type is used.Also applies to: 132-132
218-234: LGTM!The conditional typing for
userinActionThiscorrectly handles all authentication scenarios:
authRequired: true→ user is non-optional with username conditional onuserWithoutUsernameauthOrAnonRequired: true→ user is optional with same username conditional- Default → user is optional with same conditional
321-327: LGTM!The
TypedThisuser typing mirrors theActionThispattern, maintaining consistency across both typing utilities.apps/meteor/app/api/server/ApiClass.ts (3)
279-279: LGTM!The explicit cast to
SuccessResult<T>was redundant since the object literal already satisfies the type.
1085-1087: LGTM!The login route correctly sets
userWithoutUsername: truesince users may authenticate before having a username configured (e.g., during initial login flows or OAuth scenarios).
802-803: LGTM!Simplifying the action assignment and router registration by removing unnecessary intermediate casting improves readability.
Also applies to: 965-965
apps/meteor/app/api/server/v1/settings.ts (1)
213-218: LGTM!Removing the non-null assertion is safe. The route requires authentication and doesn't opt into
userWithoutUsername, so the runtime enforcement guaranteesusernameis present.apps/meteor/app/api/server/v1/videoConference.ts (1)
31-35: LGTM!Removing the non-null assertions is safe. For
username, the runtime check guarantees its presence. Fortype, thecanSendMessageAsyncfunction acceptsIUser['type']which already accounts for its optionality.apps/meteor/app/livechat/imports/server/rest/appearance.ts (1)
98-103: LGTM!Removing the non-null assertion is safe here. The route's
authRequired: truewithoutuserWithoutUsernameensures username presence at runtime.apps/meteor/app/api/server/v1/assets.ts (2)
40-45: LGTM!Safe removal of non-null assertion due to runtime username enforcement.
77-82: LGTM!Same as above - runtime enforcement guarantees username presence.
apps/meteor/app/api/server/v1/users.ts (3)
112-117: LGTM!The removal of the
|| ''fallback is safe. Since this route hasauthRequired: truewithoutuserWithoutUsername, the runtime now guarantees username presence, making the fallback unnecessary.
143-152: LGTM!Adding
userWithoutUsername: trueis appropriate forusers.updateOwnBasicInfosince users may be setting their username for the first time through this endpoint.
924-934: LGTM!Adding
userWithoutUsername: truetousers.getUsernameSuggestionis correct - this endpoint's primary use case is for users who don't yet have a username and need a suggestion.apps/meteor/app/livechat/server/api/v1/integration.ts (1)
54-59: Audit actor handling is correctly aligned with the new route typing.Line 56 now uses
this.user.usernamedirectly, which is appropriate here since this route remainsauthRequired: truewithoutuserWithoutUsername.apps/meteor/app/api/server/v1/misc.ts (4)
172-175:meroute option update is consistent with username-optional auth flows.Line 174 correctly opts this authenticated endpoint into
userWithoutUsername.
472-476:method.call/:methodnow explicitly supports authenticated users without usernames.Line 475 is a good fit for this endpoint’s auth model and current handler usage.
535-539:method.callAnon/:methodoption change is safely applied.Line 538 keeps this route aligned with the new username-optional context handling.
668-673: Audit payload updates are correct without non-null assertions.Lines 670 and 690 now rely on route/user context typing directly, which is cleaner and still consistent with authenticated enforcement on this endpoint.
Also applies to: 688-693
|
/jira ARCH-2021 |
…finition (#39292) Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: ggazzo <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/meteor/client/views/root/MainLayout/RegisterUsername.tsx`:
- Around line 76-77: In RegisterUsername.tsx remove the inline implementation
comment immediately preceding the call to location.reload() and leave the
location.reload() call unchanged; locate the comment near the
registration/onLogin retry logic in the RegisterUsername component and delete
that single-line comment so only the existing location.reload() remains.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/meteor/client/views/root/MainLayout/RegisterUsername.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: 📦 Build Packages
- GitHub Check: cubic · AI code reviewer
- GitHub Check: CodeQL-Build
- GitHub Check: CodeQL-Build
🧰 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:
apps/meteor/client/views/root/MainLayout/RegisterUsername.tsx
| // Reload to redo any onLogin request that may have failed without an username | ||
| location.reload(); |
There was a problem hiding this comment.
Remove inline implementation comment on Line 76; keep the reload call.
The inline comment at Line 76 violates the repository rule for TS/TSX implementation code. You can keep location.reload() at Line 77 and drop the comment.
Suggested diff
- // Reload to redo any onLogin request that may have failed without an username
location.reload();As per coding guidelines, **/*.{ts,tsx,js}: "Avoid code comments in the implementation".
📝 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.
| // Reload to redo any onLogin request that may have failed without an username | |
| location.reload(); | |
| location.reload(); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/meteor/client/views/root/MainLayout/RegisterUsername.tsx` around lines
76 - 77, In RegisterUsername.tsx remove the inline implementation comment
immediately preceding the call to location.reload() and leave the
location.reload() call unchanged; locate the comment near the
registration/onLogin retry logic in the RegisterUsername component and delete
that single-line comment so only the existing location.reload() remains.
Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: ggazzo <[email protected]>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/meteor/app/api/server/ApiClass.ts (1)
806-812:⚠️ Potential issue | 🟠 MajorUse merged endpoint options for the username bypass check.
_optionscontains the effective route/method options, but Line 855 checksoptions.userWithoutUsername. This can incorrectly block legacyaddRouteendpoints that setuserWithoutUsernamein the method config.Suggested fix
- if (user && !options.userWithoutUsername && !isUserWithUsername(user)) { + if (user && !_options.userWithoutUsername && !isUserWithUsername(user)) { throw new Meteor.Error('error-unauthorized', 'Users must have a username'); }Also applies to: 855-857
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/meteor/app/api/server/ApiClass.ts` around lines 806 - 812, The route username-bypass check is reading the original method config (`options.userWithoutUsername`) instead of the merged effective options in `_options`, so legacy endpoints that set `userWithoutUsername` in method-level config can be mis-blocked; update the check(s) that reference `options.userWithoutUsername` (around the username bypass logic) to use `_options.userWithoutUsername` (and any other places that read `options.*` after merging `extraOptions` from `operations[method]`) so the code uses the merged endpoint options when deciding whether to bypass username enforcement.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@apps/meteor/app/api/server/ApiClass.ts`:
- Around line 806-812: The route username-bypass check is reading the original
method config (`options.userWithoutUsername`) instead of the merged effective
options in `_options`, so legacy endpoints that set `userWithoutUsername` in
method-level config can be mis-blocked; update the check(s) that reference
`options.userWithoutUsername` (around the username bypass logic) to use
`_options.userWithoutUsername` (and any other places that read `options.*` after
merging `extraOptions` from `operations[method]`) so the code uses the merged
endpoint options when deciding whether to bypass username enforcement.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/meteor/app/api/server/ApiClass.ts
📜 Review details
🧰 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:
apps/meteor/app/api/server/ApiClass.ts
🧠 Learnings (7)
📚 Learning: 2026-02-24T19:09:09.561Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38974
File: apps/meteor/app/api/server/v1/im.ts:220-221
Timestamp: 2026-02-24T19:09:09.561Z
Learning: In RocketChat/Rocket.Chat OpenAPI migration PRs for apps/meteor/app/api/server/v1 endpoints, maintainers prefer to avoid any logic changes; style-only cleanups (like removing inline comments) may be deferred to follow-ups to keep scope tight.
Applied to files:
apps/meteor/app/api/server/ApiClass.ts
📚 Learning: 2026-02-25T20:10:16.987Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38913
File: packages/ddp-client/src/legacy/types/SDKLegacy.ts:34-34
Timestamp: 2026-02-25T20:10:16.987Z
Learning: In the RocketChat/Rocket.Chat monorepo, packages/ddp-client and apps/meteor do not use TypeScript project references. Module augmentations in apps/meteor (e.g., declare module 'rocket.chat/rest-typings') are not visible when compiling packages/ddp-client in isolation, which is why legacy SDK methods that depend on OperationResult types for OpenAPI-migrated endpoints must remain commented out.
Applied to files:
apps/meteor/app/api/server/ApiClass.ts
📚 Learning: 2026-03-03T11:11:45.505Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 39230
File: apps/meteor/app/api/server/v1/chat.ts:214-222
Timestamp: 2026-03-03T11:11:45.505Z
Learning: In apps/meteor/server/lib/moderation/reportMessage.ts, the reportMessage function validates that description is not empty or whitespace-only with `if (!description.trim())`. When migrating the chat.reportMessage endpoint to OpenAPI, adding minLength validation to the schema preserves this existing behavior.
Applied to files:
apps/meteor/app/api/server/ApiClass.ts
📚 Learning: 2026-01-17T01:51:47.764Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38219
File: packages/core-typings/src/cloud/Announcement.ts:5-6
Timestamp: 2026-01-17T01:51:47.764Z
Learning: In packages/core-typings/src/cloud/Announcement.ts, the AnnouncementSchema.createdBy field intentionally overrides IBannerSchema.createdBy (object with _id and optional username) with a string enum ['cloud', 'system'] to match existing runtime behavior. This is documented as technical debt with a FIXME comment at apps/meteor/app/cloud/server/functions/syncWorkspace/handleCommsSync.ts:53 and should not be flagged as an error until the runtime behavior is corrected.
Applied to files:
apps/meteor/app/api/server/ApiClass.ts
📚 Learning: 2025-09-15T13:10:30.049Z
Learnt from: Dnouv
Repo: RocketChat/Rocket.Chat PR: 36868
File: packages/http-router/src/Router.ts:416-425
Timestamp: 2025-09-15T13:10:30.049Z
Learning: In packages/http-router/src/Router.ts, the dispatch() method's use of replaceAll('//', '/') on the full path is acceptable because URL normalization and query string handling is performed by the caller function before dispatch() is invoked.
Applied to files:
apps/meteor/app/api/server/ApiClass.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.
Applied to files:
apps/meteor/app/api/server/ApiClass.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.
Applied to files:
apps/meteor/app/api/server/ApiClass.ts
🔇 Additional comments (1)
apps/meteor/app/api/server/ApiClass.ts (1)
1085-1088: Login opt-out is correctly scoped.Allowing
userWithoutUsername: trueon the login route is a good targeted exception and aligns with the new auth flow requirement.
… endpoint context type (#39306) Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: ggazzo <[email protected]>
It's crucial to enforce a stricter typing for the user object, particularly around the username field. Initially, the username was optional to accommodate user registration flows that don't require a username. However, within the core application logic, users without a username should not perform critical actions (like sending messages, inviting others, etc.). Thus, this stricter typing ensures we catch these cases at compile time. By propagating this type safety across the codebase, we reduce repetitive runtime checks, streamlining development and increasing confidence in user actions.
This pull request introduces improvements to API authentication handling, specifically around user objects and username requirements. The main change is the addition of a new option,
userWithoutUsername, which allows certain API routes to accept users without ausernameproperty. This enables more flexible authentication scenarios, such as login routes or anonymous access, while ensuring stricter type safety and runtime validation elsewhere. Several type definitions and runtime checks are updated to reflect this change, and usages ofthis.user.username!are made safer throughout the codebase.Authentication and User Handling Improvements:
userWithoutUsernameoption to API route definitions, allowing some routes to accept users without ausernameproperty. This is used, for example, in the login route. [1] [2] [3]ActionThis,TypedThis) to conditionally require theusernameproperty on theuserobject based on theuserWithoutUsernameoption. [1] [2]ApiClass.tsto ensure that, unlessuserWithoutUsernameis set, authenticated users must have ausername. Unauthorized requests without a username now throw an error. [1] [2]Codebase Safety and Consistency:
this.user.username!with safer accesses tothis.user.usernamein all API route implementations, ensuring compatibility with the new type definitions. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]Minor Code Quality Improvements:
ApiClass.tsfor better readability and maintainability. [1] [2] [3]Proposed changes (including videos or screenshots)
Issue(s)
Steps to test or reproduce
Further comments
Summary by CodeRabbit
New Features
Improvements
Bug Fixes
Task: ARCH-2024