Skip to content

fix(connection): auto-fetch hidden stored headers when saving auth changes#2562

Merged
chelojimenez merged 2 commits into
mainfrom
claude/cool-bell-iqck7h
Jun 11, 2026
Merged

fix(connection): auto-fetch hidden stored headers when saving auth changes#2562
chelojimenez merged 2 commits into
mainfrom
claude/cool-bell-iqck7h

Conversation

@chelojimenez

@chelojimenez chelojimenez commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Problem

Changing the bearer token (or auth type, or adding a header row) on an existing hosted server hard-blocked the save with:

Reveal saved headers before changing authentication so existing hidden headers aren't lost.

Saving a header-affecting change replaces the entire stored header set, and in hosted mode the saved headers (including Authorization) are redacted from the client, so the form refused to build a replacement patch it couldn't make safely. The only way out was finding the "Reveal" button buried in Advanced settings — a dead end when you just want to rotate a token.

Fix

Instead of blocking, ServerDetailModal.handleSave now fetches the stored headers through the existing /api/web/server/reveal-secrets API when needed and passes them to buildFormData, which merges the edit into them:

  • The saved Authorization header is replaced/dropped only when the user actually edited auth (new authDirty flag, tracked separately from header-row edits) — adding an unrelated header row no longer risks losing a hidden bearer token.
  • All other hidden headers are preserved in the replacement patch.
  • The old blocking toast remains only as a fallback when the secrets can't be fetched (no project/server id yet, or the reveal request fails — e.g. non-creator).

Also fixes a latent bug: a bearer-token edit made before manually revealing headers was silently dropped from the secret patch, because reveal reset the dirty flag the patch depended on. authDirty survives the reveal, so the edit is kept.

Testing

  • Updated use-server-form tests: the auth-change-with-hidden-headers case now expects a merged patch instead of a validation error; added coverage for preserving the hidden Authorization on row-only edits and dropping it when switching to OAuth.
  • vitest run client/src/components/connection — 11 files, 113 tests pass.
  • npm run typecheck:client — clean.

Fixes the error Eric reported when changing bearer tokens for an existing server.

https://claude.ai/code/session_01DENLb6ErstWpuZThrLDWR9


Generated by Claude Code


Note

Medium Risk
Changes how stored server secrets are assembled on save and could mis-merge headers if reveal fails or IDs are missing, though the code fails closed on API errors.

Overview
Hosted server saves no longer hard-block when you change bearer auth, auth type, or custom headers while stored HTTP headers are still hidden. Instead of requiring a manual “Reveal” in Advanced settings, ServerDetailModal loads saved headers via fetchServerSecrets when needsStoredHeaderReveal is set, then passes them into buildFormData so the replacement secretPatch keeps non-auth headers and applies your edit.

useServerForm now tracks auth edits separately (authDirty vs header-row headersDirty). Merged patches only drop or replace the stored Authorization header when auth was actually changed; header-only edits can preserve a hidden bearer token. Validation no longer blocks save for hidden headers; fetch failures still show toasts and abort save.

Tests cover merge behavior for auth changes, header-only edits, and switching away from bearer/OAuth.

Reviewed by Cursor Bugbot for commit 6cce650. Bugbot is set up for automated code reviews on this repo. Configure here.

…anges

Changing the bearer token (or any auth/header field) on an existing
hosted server hard-blocked the save with 'Reveal saved headers before
changing authentication...' because saving replaces the whole stored
header set and the form couldn't see the hidden ones.

Instead of blocking, the save flow now fetches the stored headers via
the existing reveal-secrets API and merges the edit into them: the
saved Authorization header is swapped only when auth was actually
edited, and all other hidden headers are preserved. The old error
remains only as a fallback when the secrets can't be fetched.

Also fixes a latent bug where a bearer-token edit made before manually
revealing headers was silently dropped from the secret patch.

https://claude.ai/code/session_01DENLb6ErstWpuZThrLDWR9
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@chelojimenez

chelojimenez commented Jun 11, 2026

Copy link
Copy Markdown
Contributor Author

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. bug Something isn't working labels Jun 11, 2026
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7bd1f965-b4d3-4860-9909-fe4bf7e02342

📥 Commits

Reviewing files that changed from the base of the PR and between f3c4fc7 and 6cce650.

📒 Files selected for processing (1)
  • mcpjam-inspector/client/src/components/connection/ServerDetailModal.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • mcpjam-inspector/client/src/components/connection/ServerDetailModal.tsx

Walkthrough

This PR adds selective preservation of stored HTTP headers when users edit server authentication. The useServerForm hook now tracks auth changes via authDirty and exposes needsStoredHeaderReveal to signal when stored headers must be fetched. The buildFormData method accepts optional revealedHeaders to seed outgoing headers while conditionally excluding the Authorization header if auth was modified. The modal's save handler checks this flag, conditionally fetches stored headers via fetchServerSecrets, and passes them through buildFormData to prevent accidental overwrites of hidden stored headers during authentication edits.


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.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit f3c4fc7. Configure here.


const finalFormData = formState.buildFormData(
revealedHeaders ? { revealedHeaders } : undefined
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Deferred build races form reset

Medium Severity

handleSave now awaits fetchServerSecrets before calling buildFormData, but dirty flags and edited auth/header values live in hook state that useServerForm reinitializes whenever the server prop changes. If the live server snapshot updates during that await, authDirty/headersDirty can clear and the post-fetch patch may omit the user’s auth or header change or keep the old Authorization value while still showing success.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit f3c4fc7. Configure here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This race can't occur: handleSave captures formState from the render in which Save was clicked, and buildFormData reads only closure-bound useState values from that same render (no refs). If the server prop updates during the await and the init effect resets authDirty/headersDirty, that affects the next render's formState — the in-flight handler keeps building from the values as of the click. The second finding (null headers coerced to an empty merge base) was real and is fixed in 6cce650.


Generated by Claude Code

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Internal preview

Preview URL: https://mcp-inspector-pr-2562.up.railway.app
Deployed commit: a6e9915
PR head commit: 6cce650
Backend target: staging fallback.
Health: ❌ Convex unreachable — see upsert-preview job logs (staging may need convex deploy)
Access is employee-only in non-production environments.

…he response

A successful reveal-secrets response with a null headers payload was
coerced to an empty merge base, so the replacement patch could wipe
stored headers that never came back. Treat it as a failed reveal and
surface the retry toast instead.

https://claude.ai/code/session_01DENLb6ErstWpuZThrLDWR9
@chelojimenez chelojimenez merged commit ce85117 into main Jun 11, 2026
12 checks passed
@chelojimenez chelojimenez deleted the claude/cool-bell-iqck7h branch June 11, 2026 02:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants