LibreChat/api/server/routes
Danny Avila a7f16911b2
fix: Extend and Decouple MCP OAuth Flow Timeouts (#13622)
*  fix: Extend and decouple MCP OAuth flow timeouts

The OAuth auth button disappeared after 2 minutes (the internal OAuth
handling timeout) while the flow state lived for 3 minutes, leaving users
who didn't click immediately stuck in an unrecoverable re-auth loop. The
handling timeouts also reused the connection/init timeout, so a short
initTimeout would shrink the OAuth window further.

- Add MCP_OAUTH_HANDLING_TIMEOUT (10m) and MCP_OAUTH_FLOW_TTL (15m) to mcpConfig
- Decouple the reactive/proactive OAuth waits from initTimeout/connectionTimeout
- Use OAUTH_FLOW_TTL for the FlowStateManager TTL and the UI status window
- Ensure the flow TTL outlives the handling timeout, fixing the
  "Flow state not found" race
- Remove dead FLOW_TTL constant and document new env vars

Fixes #13615

*  fix: Coordinate OAuth pending window with handling timeout

Address Codex review: the extended OAuth wait was still capped by other
timeouts that were not updated.

- Align PENDING_STALE_MS (button validity + pending-flow reuse window)
  with MCP_OAUTH_HANDLING_TIMEOUT so a flow stays reusable for the full
  wait instead of 2 minutes (Finding 3)
- Clamp MCP_OAUTH_FLOW_TTL to never fall below the handling timeout so a
  callback near the deadline still finds its flow state (Finding 2)
- Floor attemptToConnect's timeout to the handling window for OAuth
  servers so the reactive in-connect OAuth wait is not killed by the
  30s connection timeout (Finding 1)
- Update flow staleness tests to reference the threshold symbolically

*  fix: Align OAuth window across status, action flows, and client polling

Address Codex round 2: extending the server wait exposed three more
windows that were still capped or now over-extended.

- checkOAuthFlowStatus reports a PENDING flow as active only within the
  usable PENDING_STALE_MS window, not the longer Keyv retention TTL, so
  the connect button reappears instead of a stuck 'connecting' state
- Give Action (custom tool) OAuth its own FlowStateManager on the prior
  3-minute TTL so the longer MCP OAuth TTL can't leave an action tool
  call waiting up to 15 minutes
- Extend the MCP server-card client polling to the 10-minute handling
  window so a user who completes OAuth after 3 minutes is still picked up

* 🧪 test: Make stale-flow CSRF test track PENDING_STALE_MS

The CSRF-fallback stale-flow test hardcoded a 3-minute age, which is now
within the 10-minute PENDING_STALE_MS window and was wrongly treated as
active. Derive the age from PENDING_STALE_MS so it tracks the constant.

*  fix: Add grace buffers and surface OAuth timeout to the client

Address Codex round 3 (near-deadline edges):

- Clamp MCP_OAUTH_FLOW_TTL to handling timeout + 60s grace (not equality),
  so flow state outlives the wait instead of expiring at the same instant
- Extend attemptToConnect's OAuth floor by a 60s grace so a user who
  authorizes near the deadline still gets the post-OAuth reconnect
- Surface OAUTH_HANDLING_TIMEOUT on the connection-status response and
  have the client poll for the configured window instead of a hardcoded
  10 minutes, so a tuned server deadline isn't capped on the client

*  fix: Refresh client OAuth timeout from the first status refetch

If the connection-status cache is empty when polling starts, the client
captured the 10-minute fallback and never picked up a tuned oauthTimeout.
Re-read it after each refetch so a longer configured deadline is honored
even on a cold cache.

* 📝 refactor: Type oauthTimeout on MCPConnectionStatusResponse

Declare the oauthTimeout field on the shared response type in
data-provider instead of an ad-hoc inline cast in the client hook, and
replace the pre-existing 'as any' on the status query read with the
typed getQueryData. Type-level only; no runtime change.
2026-06-09 17:50:02 -04:00
..
__test-utils__ 🔗 feat: Add Granular Access Control to Shared Links via ACL System (#13051) 2026-06-03 14:17:17 -04:00
__tests__ fix: Extend and Decouple MCP OAuth Flow Timeouts (#13622) 2026-06-09 17:50:02 -04:00
admin 🪦 fix: Add Durable MCP Config Tombstones (#13534) 2026-06-05 15:05:40 -04:00
agents 🪞 fix: Preserve Model Spec Icons Across Stream Resume and Abort (#13603) 2026-06-08 17:14:21 -04:00
assistants 🧭 fix: Tighten Action OAuth Endpoint Validation (#13142) 2026-05-15 14:53:41 -04:00
files 🧯 fix: Harden Data Retention Semantics (#13049) 2026-05-19 21:58:42 -04:00
types
accessPermissions.js 🔗 feat: Add Granular Access Control to Shared Links via ACL System (#13051) 2026-06-03 14:17:17 -04:00
accessPermissions.sharePolicy.test.js 🔗 feat: Add Granular Access Control to Shared Links via ACL System (#13051) 2026-06-03 14:17:17 -04:00
accessPermissions.test.js 📦 refactor: Consolidate DB models, encapsulating Mongoose usage in data-schemas (#11830) 2026-03-21 14:28:53 -04:00
actions.js fix: Extend and Decouple MCP OAuth Flow Timeouts (#13622) 2026-06-09 17:50:02 -04:00
apiKeys.js 📦 refactor: Consolidate DB models, encapsulating Mongoose usage in data-schemas (#11830) 2026-03-21 14:28:53 -04:00
auth.2fa-ratelimit.test.js 🚦 fix: Guard Auth Continuation with Dedicated Limiter (#13555) 2026-06-06 14:21:28 -04:00
auth.cloudfront.test.js 🚦 fix: Guard Auth Continuation with Dedicated Limiter (#13555) 2026-06-06 14:21:28 -04:00
auth.js 🚦 fix: Guard Auth Continuation with Dedicated Limiter (#13555) 2026-06-06 14:21:28 -04:00
balance.js 🤫 chore: Quiet Repetitive Log Noise from Balance, CloudFront, and Capability Paths (#13461) 2026-06-01 20:40:16 -04:00
banner.js 📦 refactor: Consolidate DB models, encapsulating Mongoose usage in data-schemas (#11830) 2026-03-21 14:28:53 -04:00
categories.js 📦 refactor: Consolidate DB models, encapsulating Mongoose usage in data-schemas (#11830) 2026-03-21 14:28:53 -04:00
config.js feat: Immediate Conversation Title Generation (#13395) 2026-06-02 16:40:57 -04:00
convos.js 🗂️ feat: Add Private Chat Projects (#13467) 2026-06-03 15:29:18 -04:00
endpoints.js 🏗️ refactor: Remove Redundant Caching, Migrate Config Services to TypeScript (#12466) 2026-03-30 16:49:48 -04:00
index.js 🗂️ feat: Add Private Chat Projects (#13467) 2026-06-03 15:29:18 -04:00
keys.js 🔱 chore: Harden API Routes Against IDOR and DoS Attacks (#11760) 2026-02-12 18:08:24 -05:00
mcp.js fix: Extend and Decouple MCP OAuth Flow Timeouts (#13622) 2026-06-09 17:50:02 -04:00
memories.js 📦 refactor: Consolidate DB models, encapsulating Mongoose usage in data-schemas (#11830) 2026-03-21 14:28:53 -04:00
messages.js 📋 refactor: Attach Message Context to Langfuse Feedback Scores (#13604) 2026-06-08 15:54:01 -04:00
models.js
oauth.js 🩻 refactor: Replace Opaque OAuth Errors with Structured Failure Diagnostics (#13471) 2026-06-02 15:06:42 -04:00
oauth.test.js feat: Immediate Conversation Title Generation (#13395) 2026-06-02 16:40:57 -04:00
presets.js
projects.js 🗂️ feat: Add Private Chat Projects (#13467) 2026-06-03 15:29:18 -04:00
prompts.js 📁 refactor: Prompts UI (#11570) 2026-03-22 16:56:22 -04:00
prompts.test.js 📁 refactor: Prompts UI (#11570) 2026-03-22 16:56:22 -04:00
roles.js 📜 feat: Skills UI + Initial E2E CRUD / Sharing (#12580) 2026-04-25 04:02:00 -04:00
rum.js 📡 feat: Add Authenticated Proxy Mode for Browser RUM Telemetry (#13464) 2026-06-01 21:11:35 -04:00
search.js
settings.js 🎚️ feat: Per-User Skill Active/Inactive Toggle with Ownership-Aware Defaults (#12692) 2026-04-25 04:02:00 -04:00
share.js 🧼 fix: Prevent Shared Link Caching and Strengthen Log Redaction (#13561) 2026-06-06 18:40:57 -04:00
skills.js 🗂️ feat: Add Deployment Skill Directory (#13523) 2026-06-05 10:24:28 -04:00
skills.tenant.test.js 🧵 fix: Preserve Upload Context Across Multipart Routes (#13072) 2026-05-11 15:46:48 -04:00
skills.test.js 📦 feat: Configure Skill Import Size Limit (#13073) 2026-05-11 16:24:04 -04:00
static.js
tags.js 📦 refactor: Consolidate DB models, encapsulating Mongoose usage in data-schemas (#11830) 2026-03-21 14:28:53 -04:00
user.js