Skip to content

Conversation

@d-gubert
Copy link
Member

@d-gubert d-gubert commented Dec 5, 2025

Proposed changes (including videos or screenshots)

Current auth for ApiClass does not run extra auth methods registered with addAuthMethod, causing third-party login to not work.

Issue(s)

SUP-943
#35419

Steps to test or reproduce

Using the Zapier app from the Marketplace is the most straightforward way to test this.

Without the changes here, you can authenticate your Zap with your Rocket.Chat workspace, but the zap can't perform any actions on your behalf.

With the changes applied, zaps are able to perform actions on your behalf.

Further comments

Summary by CodeRabbit

  • Bug Fixes

    • Restored third‑party login reliability and improved OAuth token handling for more consistent authentication.
  • Refactor

    • Standardized route execution context and authentication flow across server endpoints.
    • Made query parsing and request/header handling more defensive and type‑safe; added clearer logging exposure.
  • Tests

    • Added end‑to‑end OAuth credential tests validating bearer token access to core API endpoints.
  • Chores

    • Added a changeset file documenting the patch.

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

@changeset-bot
Copy link

changeset-bot bot commented Dec 5, 2025

🦋 Changeset detected

Latest commit: e61f209

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

This PR includes changesets to release 41 packages
Name Type
@rocket.chat/meteor Patch
@rocket.chat/core-typings Patch
@rocket.chat/rest-typings Patch
@rocket.chat/uikit-playground Patch
@rocket.chat/api-client Patch
@rocket.chat/apps Patch
@rocket.chat/core-services Patch
@rocket.chat/cron Patch
@rocket.chat/ddp-client Patch
@rocket.chat/freeswitch Patch
@rocket.chat/fuselage-ui-kit Patch
@rocket.chat/gazzodown Patch
@rocket.chat/http-router Patch
@rocket.chat/livechat Patch
@rocket.chat/model-typings Patch
@rocket.chat/ui-avatar Patch
@rocket.chat/ui-client Patch
@rocket.chat/ui-contexts Patch
@rocket.chat/ui-voip Patch
@rocket.chat/web-ui-registration Patch
@rocket.chat/account-service Patch
@rocket.chat/authorization-service Patch
@rocket.chat/ddp-streamer Patch
@rocket.chat/omnichannel-transcript Patch
@rocket.chat/presence-service Patch
@rocket.chat/queue-worker Patch
@rocket.chat/stream-hub-service 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 Patch
@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 Dec 5, 2025

Walkthrough

Replaces PartialThis with a route-context model (GenericRouteExecutionContext) across API auth and parsing paths, converts auth methods to async route-context functions returning IUser | undefined, tightens OAuth2 header/query types and return shape, and updates middleware, integrations, and handlers to use the new context and safer runtime guards.

Changes

Cohort / File(s) Summary
Changeset documentation
\.changeset/rich-dogs-wonder.md``
Adds a patch-level changeset noting a fix for third-party login.
API core & typings
apps/meteor/app/api/server/ApiClass.ts, apps/meteor/app/api/server/definition.ts, apps/meteor/app/api/server/helpers/parseJsonQuery.ts
Replace PartialThis with GenericRouteExecutionContext/RouteExecutionContext; add logger and queryFields to ActionThis; change APIClass auth method types and addAuthMethod to accept `(routeContext) => Promise<IUser
OAuth2 server & integration
apps/meteor/app/oauth2-server-config/server/oauth/oauth2-server.ts
Tighten oAuth2ServerAuth input types to `{ headers: Record<string,string
Authentication middleware
apps/meteor/app/api/server/middlewares/authentication.ts
Call oAuth2ServerAuth with explicit { headers, query } typed as `Record<string,string
Integrations & handlers
apps/meteor/app/integrations/server/api/api.ts, apps/meteor/ee/server/apps/communication/endpoints/appLogsExportHandler.ts
Update authenticatedRoute signatures to accept route-context (GenericRouteExecutionContext) and adapt internal header/access patterns and super calls to use routeContext.request.*; guard bodyParams/query with isPlainObject.
Utility typing
apps/meteor/lib/utils/isPlainObject.ts
Make isPlainObject a TypeScript type predicate: `value is Record<string
Tests
apps/meteor/tests/end-to-end/api/oauth-server.ts
Add end-to-end OAuth credential tests exercising refreshed access token for v1 endpoints.
Manifest / package
package.json, other manifest entries
Changes included in diff manifest (changeset added); no other manifest details in summary.

Sequence Diagram(s)

sequenceDiagram
  participant Client as Client (HTTP)
  participant Middleware as Auth Middleware
  participant API as APIClass / Router
  participant OAuth as oAuth2ServerAuth
  participant DB as Token / User Store

  Client->>Middleware: HTTP request -> build routeContext (request, headers, query)
  Middleware->>API: pass routeContext to handler
  API->>API: for each authMethod: call authMethod(routeContext)
  alt authMethod is oAuth2ServerAuth
    API->>OAuth: oAuth2ServerAuth({ headers, query })
    OAuth->>DB: validate token / lookup access token & user
    DB-->>OAuth: access token / user or invalid
    OAuth-->>API: return IUser or undefined
  end
  alt user found
    API-->>API: set routeContext.request.user and continue to handler
    API-->>Client: handler response (authenticated)
  else no user found
    API-->>Client: unauthorized / no user
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing careful review:
    • APIClass public signature changes (authMethods, addAuthMethod) and all call sites.
    • oAuth2ServerAuth return-type and input-shape changes and its callers (middleware, API auth wiring).
    • parseJsonQuery runtime-guard changes and their impact on query parsing.
    • Conversions from req.headers to routeContext.request.headers across integrations and handlers.
    • Type-guard change in isPlainObject affecting consumer typings.

Suggested labels

stat: ready to merge, stat: QA assured

Suggested reviewers

  • scuciatto

Poem

🐇 I hopped through headers, tokens, and types,
Switched contexts and bounded the auth pipes.
Methods line up, checking each in turn,
Tokens found — the server's wheels now churn.
🥕 A rabbit's cheer for login paths that learn!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title clearly summarizes the main change: fixing third-party login functionality that was broken.
Linked Issues check ✅ Passed The changes properly refactor authentication flow and OAuth2 integration to restore third-party login functionality, addressing the root cause of authentication failures in SUP-943.
Out of Scope Changes check ✅ Passed All changes are focused on refactoring the authentication context to fix third-party login; no unrelated modifications detected.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ 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 fix/third-party-login

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.

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Dec 5, 2025

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

@d-gubert d-gubert force-pushed the fix/third-party-login branch from b6b2a1a to 1ee1adb Compare December 5, 2025 14:39
@d-gubert
Copy link
Member Author

d-gubert commented Dec 5, 2025

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 5, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

1 similar comment
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 5, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

📜 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 75bd3e4 and 1ee1adb.

📒 Files selected for processing (3)
  • .changeset/rich-dogs-wonder.md (1 hunks)
  • apps/meteor/app/api/server/ApiClass.ts (5 hunks)
  • apps/meteor/app/oauth2-server-config/server/oauth/oauth2-server.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:

  • apps/meteor/app/api/server/ApiClass.ts
  • apps/meteor/app/oauth2-server-config/server/oauth/oauth2-server.ts
🧬 Code graph analysis (1)
apps/meteor/app/api/server/ApiClass.ts (1)
packages/core-typings/src/IUser.ts (1)
  • IUser (186-256)
⏰ 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). (7)
  • GitHub Check: 🔨 Test Storybook / Test Storybook
  • GitHub Check: 🔎 Code Check / TypeScript
  • GitHub Check: 🔎 Code Check / Code Lint
  • GitHub Check: 🔨 Test Unit / Unit Tests
  • GitHub Check: 📦 Meteor Build (coverage)
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (9)
.changeset/rich-dogs-wonder.md (1)

1-5: LGTM!

The changeset entry is properly formatted and clearly describes the fix for third-party login functionality.

apps/meteor/app/api/server/ApiClass.ts (5)

173-173: LGTM! Improved type safety.

The authMethods type has been strengthened from loose any-typed functions to strongly-typed Request-based resolvers returning Promise<IUser | undefined>. This improves type safety and enforces a consistent authentication method signature.


826-826: LGTM! Correct context binding.

The call to authenticatedRoute is properly bound to the API instance and passes the Request object as expected by the refactored authentication flow.


976-977: LGTM! Consistent header access pattern.

The header retrieval uses the standard req.headers.get method, which is consistent with the Web API Request interface and properly handles the nullable return type.


991-998: LGTM! Sequential authentication method evaluation.

The implementation correctly iterates through authentication methods sequentially, returning the first successful result. The intentional serial execution (with justified eslint-disable) ensures authentication methods are evaluated in priority order, which is the appropriate behavior for a pluggable auth system.


255-257: No breaking change detected; signature is consistent with usage.

The addAuthMethod signature at line 255 matches the authMethods array type definition at line 173 and is used correctly in the codebase. The only usage found (oauth2-server.ts:77) implements the expected (req: Request) => Promise<IUser | undefined> pattern without issues. No evidence of a prior signature or migration concerns exists.

Likely an incorrect or invalid review comment.

apps/meteor/app/oauth2-server-config/server/oauth/oauth2-server.ts (3)

27-33: LGTM! Improved token handling clarity.

The extraction of incomingToken and early return improves code readability while maintaining the same logic.


46-46: LGTM! Return type aligned with new signature.

The direct return of the user object is consistent with the updated function signature.


77-83: LGTM! Correct OAuth2 authentication integration.

The auth method registration properly reconstructs headers and query parameters from the Request object and delegates to oAuth2ServerAuth. The type conversions are safe, and the implementation aligns with the new Request-based authentication pattern.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 5, 2025

📦 Docker Image Size Report

📈 Changes

Service Current Baseline Change Percent
sum of all images 1.2GiB 1.2GiB +12MiB
rocketchat 358MiB 347MiB +12MiB
omnichannel-transcript-service 132MiB 132MiB -243B
queue-worker-service 132MiB 132MiB +539B
ddp-streamer-service 126MiB 126MiB +559B
account-service 113MiB 113MiB -51B
stream-hub-service 110MiB 110MiB +92B
authorization-service 110MiB 110MiB +212B
presence-service 110MiB 110MiB -621B

📊 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/15 22:28", "11/16 01:28", "11/17 23:50", "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 19:43", "12/16 19:59 (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]
  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]
  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]
  line "omnichannel-transcript-service" [0.14, 0.14, 0.14, 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]
  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]
  line "queue-worker-service" [0.14, 0.14, 0.14, 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]
  line "rocketchat" [0.36, 0.36, 0.35, 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.35]
  line "stream-hub-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]
Loading

Statistics (last 22 days):

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

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

  • Tag: pr-37707
  • Baseline: develop
  • Timestamp: 2025-12-16 19:59:40 UTC
  • Historical data points: 22

Updated: Tue, 16 Dec 2025 19:59:41 GMT

@d-gubert d-gubert linked an issue Dec 5, 2025 that may be closed by this pull request
@d-gubert d-gubert force-pushed the fix/third-party-login branch 5 times, most recently from 86bc3ad to 06b4036 Compare December 8, 2025 19:48
@d-gubert
Copy link
Member Author

d-gubert commented Dec 8, 2025

@coderabbitai generate docstrings

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 8, 2025

✅ Actions performed

Initiated docstring generation; will generate only if new commits exist.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 8, 2025

Note

Docstrings generation - SUCCESS
Generated docstrings for this pull request at #37741

coderabbitai bot added a commit that referenced this pull request Dec 8, 2025
Docstrings generation was requested by @d-gubert.

* #37707 (comment)

The following files were modified:

* `apps/meteor/app/api/server/middlewares/authentication.ts`
* `apps/meteor/app/oauth2-server-config/server/oauth/oauth2-server.ts`
@d-gubert d-gubert force-pushed the fix/third-party-login branch from 06b4036 to 5001673 Compare December 11, 2025 17:20
@d-gubert
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 11, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

🧹 Nitpick comments (4)
apps/meteor/app/integrations/server/api/api.ts (1)

195-199: Type safety concern: result.content may not be a plain object.

After script execution, bodyParams is reassigned from result.content without validation. If the script returns non-object content, subsequent property access (e.g., bodyParams.separateResponse) may fail.

Consider validating the content:

-			bodyParams = result?.content;
+			bodyParams = isPlainObject(result?.content) ? result.content : {};
apps/meteor/lib/utils/isPlainObject.ts (1)

1-3: Consider narrower plain object check if stricter validation needed.

The current implementation returns true for Date, Map, Set, RegExp, and other built-in objects. For the PR's use cases (validating bodyParams/queryParams), this is acceptable since those are typically parsed JSON. If stricter validation is needed later, consider checking Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null.

apps/meteor/app/api/server/helpers/parseJsonQuery.ts (1)

137-139: Redundant fallback in queryFields check.

The condition if (queryFields && !isValidQuery(query, queryFields || ['*'], ...)) has a logical redundancy: if queryFields is truthy (non-empty array), then queryFields || ['*'] will never use the ['*'] fallback.

If the intent is to use ['*'] when queryFields is empty, consider:

-		if (queryFields && !isValidQuery(query, queryFields || ['*'], queryOperations ?? pathAllowConf.def)) {
+		if (!isValidQuery(query, queryFields.length > 0 ? queryFields : ['*'], queryOperations.length > 0 ? queryOperations : pathAllowConf.def)) {

Otherwise, if the current behavior is intentional (skip validation when no queryFields), the || ['*'] can be removed.

apps/meteor/app/api/server/ApiClass.ts (1)

820-830: Context initialization and user assignment.

Lines 820-822 properly initialize queryOperations, queryFields, and logger on the route context before authentication. However, line 826 uses a non-null assertion (user!) on a value that could be null from authenticatedRoute.

The non-null assertion is safe here because lines 832-846 handle the !this.user case and return early. However, for clarity, consider:

-						const user = await api.authenticatedRoute(this);
-						this.user = user!;
+						const user = await api.authenticatedRoute(this);
+						if (user) {
+							this.user = user;
+						}

This makes the null-handling explicit rather than relying on downstream checks.

📜 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 1ee1adb and 5001673.

📒 Files selected for processing (9)
  • .changeset/rich-dogs-wonder.md (1 hunks)
  • apps/meteor/app/api/server/ApiClass.ts (8 hunks)
  • apps/meteor/app/api/server/definition.ts (2 hunks)
  • apps/meteor/app/api/server/helpers/parseJsonQuery.ts (5 hunks)
  • apps/meteor/app/api/server/middlewares/authentication.ts (1 hunks)
  • apps/meteor/app/integrations/server/api/api.ts (7 hunks)
  • apps/meteor/app/oauth2-server-config/server/oauth/oauth2-server.ts (4 hunks)
  • apps/meteor/ee/server/apps/communication/endpoints/appLogsExportHandler.ts (2 hunks)
  • apps/meteor/lib/utils/isPlainObject.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/rich-dogs-wonder.md
🧰 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/lib/utils/isPlainObject.ts
  • apps/meteor/ee/server/apps/communication/endpoints/appLogsExportHandler.ts
  • apps/meteor/app/api/server/middlewares/authentication.ts
  • apps/meteor/app/oauth2-server-config/server/oauth/oauth2-server.ts
  • apps/meteor/app/api/server/helpers/parseJsonQuery.ts
  • apps/meteor/app/integrations/server/api/api.ts
  • apps/meteor/app/api/server/definition.ts
  • apps/meteor/app/api/server/ApiClass.ts
🧠 Learnings (2)
📚 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/middlewares/authentication.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/oauth2-server-config/server/oauth/oauth2-server.ts
🧬 Code graph analysis (7)
apps/meteor/ee/server/apps/communication/endpoints/appLogsExportHandler.ts (1)
apps/meteor/app/api/server/definition.ts (1)
  • GenericRouteExecutionContext (145-145)
apps/meteor/app/api/server/middlewares/authentication.ts (1)
apps/meteor/app/oauth2-server-config/server/oauth/oauth2-server.ts (1)
  • oAuth2ServerAuth (22-48)
apps/meteor/app/oauth2-server-config/server/oauth/oauth2-server.ts (3)
packages/core-typings/src/IUser.ts (1)
  • IUser (186-256)
apps/meteor/app/api/server/index.ts (1)
  • API (55-55)
apps/meteor/lib/utils/isPlainObject.ts (1)
  • isPlainObject (1-3)
apps/meteor/app/api/server/helpers/parseJsonQuery.ts (3)
apps/meteor/app/api/server/ApiClass.ts (1)
  • parseJsonQuery (246-248)
apps/meteor/app/api/server/definition.ts (1)
  • GenericRouteExecutionContext (145-145)
apps/meteor/lib/utils/isPlainObject.ts (1)
  • isPlainObject (1-3)
apps/meteor/app/integrations/server/api/api.ts (2)
apps/meteor/app/api/server/definition.ts (1)
  • GenericRouteExecutionContext (145-145)
apps/meteor/lib/utils/isPlainObject.ts (1)
  • isPlainObject (1-3)
apps/meteor/app/api/server/definition.ts (1)
packages/rest-typings/src/index.ts (2)
  • Method (122-122)
  • PathPattern (120-120)
apps/meteor/app/api/server/ApiClass.ts (2)
apps/meteor/app/api/server/definition.ts (1)
  • GenericRouteExecutionContext (145-145)
apps/meteor/app/api/server/helpers/parseJsonQuery.ts (1)
  • parseJsonQuery (17-153)
🔇 Additional comments (14)
apps/meteor/app/api/server/definition.ts (3)

145-151: LGTM - Well-structured route execution context types.

The dual type approach is sensible: GenericRouteExecutionContext with any for flexible internal use, and RouteExecutionContext for strongly-typed scenarios. This aligns with the route-context-based refactor throughout the PR.


153-154: LGTM - Logger added to ActionThis.

Adding readonly logger: Logger to the execution context enables consistent logging across route handlers.


180-182: LGTM - queryFields now accessible in context.

The conditional type correctly exposes queryFields when specified in options, consistent with the existing queryOperations pattern.

apps/meteor/app/integrations/server/api/api.ts (3)

43-48: LGTM - IntegrationThis properly extends GenericRouteExecutionContext.

The type correctly extends GenericRouteExecutionContext and adds the integration-specific request.integration property along with the required user type constraint.


141-142: Good defensive check with isPlainObject.

Using isPlainObject to guard against non-object bodyParams prevents runtime errors when accessing properties. The fallback to {} is appropriate.


316-328: Base class already uses the parameter-based signature.

The APIClass.authenticatedRoute method in apps/meteor/app/api/server/ApiClass.ts is already defined as protected async authenticatedRoute(routeContext: GenericRouteExecutionContext): Promise<IUser | null>. The override signature using IntegrationThis (a subtype of GenericRouteExecutionContext) is compatible with the base class and requires no changes.

Likely an incorrect or invalid review comment.

apps/meteor/app/api/server/helpers/parseJsonQuery.ts (2)

17-36: Signature refactor and defensive checks look solid.

The migration to GenericRouteExecutionContext with runtime defensive checks for params, queryFields, and queryOperations improves type safety. The mandatory userId validation (lines 34-36) ensures authenticated context before proceeding with query parsing.


30-32: The type assertions are necessary and appropriate. In GenericRouteExecutionContext = ActionThis<any, any, any>, the conditional types on queryOperations and queryFields resolve to any. TypeScript does not automatically narrow any to a specific array type via Array.isArray() checks alone, so the explicit as string[] casts are required to establish the correct type for downstream usage. The assertions are safe and justified by the guard condition.

Likely an incorrect or invalid review comment.

apps/meteor/app/oauth2-server-config/server/oauth/oauth2-server.ts (2)

22-48: Return type simplification and early exit pattern look good.

The function now correctly returns IUser | undefined directly, with proper early returns for missing token (lines 30-32) and expired/invalid token scenarios. This aligns with the updated caller expectations.


78-83: The code is correct. The request property in GenericRouteExecutionContext is typed as Request (Fetch API), which has a headers property that is a Headers object with the .entries() method available. The implementation safely uses this API.

apps/meteor/app/api/server/ApiClass.ts (4)

168-168: Auth methods signature update aligns with route-context refactor.

The type change for authMethods to accept GenericRouteExecutionContext is consistent with the broader refactoring effort.


246-252: Method signatures updated correctly.

Both parseJsonQuery and addAuthMethod now properly accept route-context-based parameters, maintaining consistency with the new authentication flow.


972-998: Core fix for third-party login authentication.

The refactored authenticatedRoute correctly:

  1. Attempts standard header-based auth first (x-user-id + x-auth-token)
  2. Falls back to iterating registered authMethods with the routeContext
  3. Returns the first successful user match

The serial execution pattern (lines 988-995) is appropriate here as auth methods should be tried in order until one succeeds. This addresses the third-party login issue by ensuring OAuth2 and other auth methods receive the properly typed route context.


920-920: parseJsonQuery binding updated correctly.

The closure now properly passes this (the route context) to api.parseJsonQuery, maintaining consistency with the new signature.

@d-gubert d-gubert force-pushed the fix/third-party-login branch from 66a0917 to a79d389 Compare December 11, 2025 21:10
@codecov
Copy link

codecov bot commented Dec 11, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.63%. Comparing base (f3dc2c1) to head (e61f209).
⚠️ Report is 25 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #37707      +/-   ##
===========================================
- Coverage    67.63%   67.63%   -0.01%     
===========================================
  Files         3457     3457              
  Lines       113662   113661       -1     
  Branches     20903    20903              
===========================================
- Hits         76874    76872       -2     
- Misses       34657    34659       +2     
+ Partials      2131     2130       -1     
Flag Coverage Δ
e2e 57.29% <ø> (+<0.01%) ⬆️
e2e-api 42.28% <ø> (+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.

@d-gubert
Copy link
Member Author

@copilot evaluate the code changes in this PR and write end-to-end tests that guarantee oauth2 apps authentication works in the v1/ endpoints

Copy link

Copilot AI commented Dec 11, 2025

@d-gubert I've opened a new pull request, #37784, to work on those changes. Once the pull request is ready, I'll request review from you.

@d-gubert d-gubert force-pushed the fix/third-party-login branch from a79d389 to 15e4f11 Compare December 12, 2025 23:06
@d-gubert d-gubert force-pushed the fix/third-party-login branch from 15e4f11 to 2f82a50 Compare December 16, 2025 17:16
@d-gubert d-gubert force-pushed the fix/third-party-login branch from 2f82a50 to e61f209 Compare December 16, 2025 19:39
@d-gubert d-gubert added this to the 7.14.0 milestone Dec 16, 2025
@d-gubert d-gubert marked this pull request as ready for review December 16, 2025 20:49
@d-gubert d-gubert requested a review from a team as a code owner December 16, 2025 20:49
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 (1)
apps/meteor/app/api/server/ApiClass.ts (1)

972-997: Core fix for third-party login - proper route context propagation.

This refactor correctly passes the route context to each auth method, enabling OAuth providers to access request headers (like the Bearer token). The serial execution with early return on first successful auth is appropriate.

Minor type inconsistency: authenticatedRoute returns IUser | null but authMethods return IUser | undefined. This works due to JavaScript's truthiness check at line 992, but consider aligning the types for clarity:

-	protected async authenticatedRoute(routeContext: GenericRouteExecutionContext): Promise<IUser | null> {
+	protected async authenticatedRoute(routeContext: GenericRouteExecutionContext): Promise<IUser | null | undefined> {

Or update authMethods to return IUser | null.

📜 Review details

Configuration used: Organization 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 5001673 and e61f209.

📒 Files selected for processing (10)
  • .changeset/rich-dogs-wonder.md (1 hunks)
  • apps/meteor/app/api/server/ApiClass.ts (8 hunks)
  • apps/meteor/app/api/server/definition.ts (2 hunks)
  • apps/meteor/app/api/server/helpers/parseJsonQuery.ts (5 hunks)
  • apps/meteor/app/api/server/middlewares/authentication.ts (1 hunks)
  • apps/meteor/app/integrations/server/api/api.ts (7 hunks)
  • apps/meteor/app/oauth2-server-config/server/oauth/oauth2-server.ts (4 hunks)
  • apps/meteor/ee/server/apps/communication/endpoints/appLogsExportHandler.ts (2 hunks)
  • apps/meteor/lib/utils/isPlainObject.ts (1 hunks)
  • apps/meteor/tests/end-to-end/api/oauth-server.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/meteor/app/oauth2-server-config/server/oauth/oauth2-server.ts
  • apps/meteor/lib/utils/isPlainObject.ts
  • apps/meteor/app/api/server/middlewares/authentication.ts
  • apps/meteor/ee/server/apps/communication/endpoints/appLogsExportHandler.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:

  • apps/meteor/tests/end-to-end/api/oauth-server.ts
  • apps/meteor/app/api/server/helpers/parseJsonQuery.ts
  • apps/meteor/app/integrations/server/api/api.ts
  • apps/meteor/app/api/server/definition.ts
  • apps/meteor/app/api/server/ApiClass.ts
🧠 Learnings (6)
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • apps/meteor/tests/end-to-end/api/oauth-server.ts
🧬 Code graph analysis (4)
apps/meteor/tests/end-to-end/api/oauth-server.ts (1)
apps/meteor/tests/data/api-data.ts (1)
  • request (10-10)
apps/meteor/app/integrations/server/api/api.ts (2)
apps/meteor/app/api/server/definition.ts (1)
  • GenericRouteExecutionContext (145-145)
apps/meteor/lib/utils/isPlainObject.ts (1)
  • isPlainObject (1-3)
apps/meteor/app/api/server/definition.ts (1)
packages/rest-typings/src/index.ts (2)
  • Method (122-122)
  • PathPattern (120-120)
apps/meteor/app/api/server/ApiClass.ts (4)
apps/meteor/app/api/server/definition.ts (1)
  • GenericRouteExecutionContext (145-145)
packages/core-typings/src/IUser.ts (1)
  • IUser (186-256)
apps/meteor/app/api/server/helpers/parseJsonQuery.ts (1)
  • parseJsonQuery (17-149)
ee/packages/media-calls/src/logger.ts (1)
  • logger (3-3)
🔇 Additional comments (12)
apps/meteor/tests/end-to-end/api/oauth-server.ts (1)

146-177: LGTM! These tests verify the core OAuth fix.

The new test suite correctly validates that OAuth bearer tokens work with v1 API endpoints, which directly addresses the third-party login issue. The test structure follows existing patterns in this file.

One minor observation: The local accessToken variable at line 147 shadows the outer scope variable at line 13, but this appears intentional for test isolation and clarity.

.changeset/rich-dogs-wonder.md (1)

1-5: LGTM!

Appropriate patch-level version bump for a bug fix with a clear, user-facing description.

apps/meteor/app/api/server/definition.ts (2)

145-151: LGTM!

The new GenericRouteExecutionContext and RouteExecutionContext types provide clean abstractions for route-context-based authentication. Using ActionThis<any, any, any> for the generic version appropriately allows flexibility while maintaining the underlying type structure.


153-154: LGTM!

Adding logger and queryFields as readonly properties to ActionThis correctly exposes these to the route context, enabling parseJsonQuery to access them without relying on implicit this bindings.

Also applies to: 181-181

apps/meteor/app/api/server/helpers/parseJsonQuery.ts (2)

17-32: LGTM! Improved type safety for route context.

The refactored function signature with GenericRouteExecutionContext and the runtime guards using isPlainObject and Array.isArray provide better safety. The fallback defaults ({} for params, [] for queryFields/queryOperations) ensure the function handles edge cases gracefully.


35-35: Good defensive checks using typeof.

Using typeof params?.sort === 'string' is more explicit than truthy checks and correctly handles edge cases like params.sort = 0 or empty strings.

Also applies to: 58-58, 108-108

apps/meteor/app/integrations/server/api/api.ts (3)

141-142: LGTM! Proper defensive handling of bodyParams.

Using isPlainObject to guard this.bodyParams and extracting separateResponse locally is a clean pattern that prevents runtime errors if bodyParams is unexpectedly not an object.


195-199: Verify handling of undefined result.content.

If result?.content is undefined or not a plain object, subsequent code at lines 197-199 accesses bodyParams.separateResponse and may fail. Consider adding a guard:

-			bodyParams = result?.content;
+			bodyParams = isPlainObject(result?.content) ? result.content : {};

316-328: LGTM! Clean refactor to explicit route context parameter.

The authenticatedRoute method now accepts routeContext explicitly instead of relying on this, which aligns with the broader route-context pattern. The logic for finding the integration and returning the user remains correct.

apps/meteor/app/api/server/ApiClass.ts (3)

168-168: LGTM! Core authentication method refactored to route-context pattern.

The authMethods array and addAuthMethod now properly use GenericRouteExecutionContext, enabling OAuth and other third-party auth providers to access request headers and query parameters through the route context. This is the key change that fixes the third-party login issue.

Also applies to: 250-252


820-830: LGTM! Route context properly populated before authentication.

Setting queryOperations, queryFields, and logger on the context before calling authenticatedRoute ensures all necessary properties are available for auth methods (including OAuth) to function correctly.


246-248: LGTM!

The parseJsonQuery method correctly delegates to the imported function with the route context.

@ggazzo ggazzo added the stat: QA assured Means it has been tested and approved by a company insider label Dec 19, 2025
@dionisio-bot dionisio-bot bot added the stat: ready to merge PR tested and approved waiting for merge label Dec 19, 2025
@ggazzo ggazzo merged commit ec56600 into develop Dec 19, 2025
92 of 94 checks passed
@ggazzo ggazzo deleted the fix/third-party-login branch December 19, 2025 12:29
gaolin1 pushed a commit to gaolin1/medsense.webchat that referenced this pull request Jan 6, 2026
@dougfabris dougfabris modified the milestones: 7.14.0, 8.0.0 Jan 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Third-party login breaks in 7.4.0

4 participants