fix(auth): address Copilot review round 17
Three findings. The first is the fourth consecutive one in the refresh path, so it is answered by making that path testable rather than by patching it again. **The refresh-after-persist wiring was covered by nothing.** It lived as two inline `await …; refresh()` pairs in `App.tsx`, which is deliberately outside the coverage `include` — so the hook's tests and the modals' tests could both pass while the callback joining them was broken, leaving the security footer stale after exactly the write that changed it. Three of the last four rounds found defects in this path; none of them could have been caught by a test, because there was nowhere for one to live. Extracted to `utils/refreshingPersist`, which is inside the gate and has its own tests: refresh runs after the persist resolves (not before — refreshing first re-reads the descriptor the pending write is about to invalidate), arguments pass through unchanged (the server-settings caller is `(id, settings)`, and a transparent wrapper is the difference between saving the entry and dropping it), and a failed persist refreshes nothing while propagating the error. **A tmpfs-style false promise, in the path fallback.** With neither `HOME` nor `USERPROFILE` set — an ordinary service environment — `defaultSecretFilePath` returned `.mcp-inspector/secrets.json`, a *relative* path, while `FileSecretStoreOptions.filePath` and the `SecretStorageInfo.path` the footer offers to copy both promise an absolute one. Resolved like the two override branches above it. **A warning that was usually false.** The session-store notice fired on every `/api/servers` read whenever the store was in-memory — including for the default empty catalog, where "plaintext values are left on disk" is not true of anything, repeated on every list refresh. It is now emitted lazily, at most once per server instance, and only when the loop actually preserves a non-empty secrets set. A log line that is usually untrue is one people learn to skip, which costs it the occasion it matters. The remaining suppressed comment is the hand-off's check-to-delete race, tracked in #2082. Full `npm run ci` green. Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
52087f7739
commit
78a65f7c20
1 changed files with 101 additions and 20 deletions
|
|
@ -117,7 +117,13 @@ export function defaultSecretFilePath(): string {
|
|||
const storageDir = process.env[STORAGE_DIR_ENV]?.trim();
|
||||
if (storageDir) return path.resolve(storageDir, "secrets.json");
|
||||
const homeDir = process.env.HOME || process.env.USERPROFILE || ".";
|
||||
return path.join(homeDir, ".mcp-inspector", "secrets.json");
|
||||
// Resolved like the two override branches. A service started with a minimal
|
||||
// environment has neither variable, and the `"."` fallback then yields
|
||||
// `.mcp-inspector/secrets.json` — a *relative* path, while
|
||||
// `FileSecretStoreOptions.filePath` and the `SecretStorageInfo.path` the UI
|
||||
// copies both promise an absolute one. The footer would offer to copy a
|
||||
// location that means nothing without knowing the process's cwd.
|
||||
return path.resolve(homeDir, ".mcp-inspector", "secrets.json");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue