inspector/core/auth/node
Repository files (latest commit first)
Filename Latest commit message Latest commit date
cliffhall 16613b115d fix(auth): address Copilot review round 1 on the secrets-file lock (#2082)
- Create the storage directory before locking. `writeStoreFile` creates it,
  but from inside the locked section — so on a fresh install, where
  `~/.mcp-inspector` does not exist, proper-lockfile failed ENOENT and every
  *first* save degraded to an unlocked write with a warning. That is the save
  most likely to be racing another (two Inspectors started together both
  reach it), so the lock was absent from precisely the interleaving it exists
  to close.
- `anythingToMigrate` no longer reads every `readdir` failure as "nothing to
  migrate". Only ENOENT/ENOTDIR proves the fresh-install case; a directory
  that denies listing can still permit access to the known `secrets.json`,
  and returning false there selected the keychain and left those secrets
  invisible with nothing said. Other errors fall through to the under-lock
  checks, which is what happened before the fast path existed.
- Pin `proper-lockfile` to the repo-root install in `vitest.shared.mts`,
  beside express and yaml: it is reached only through root-owned `core/`.
  Resolution already finds the root copy since no client declares it; the pin
  is what stops that depending on it never arriving as some client's
  transitive dependency, which would give a test two copies of a module whose
  whole job is one registry of held locks.
- Make the cross-process test prove `mutate` takes the lock. The previous one
  asserted only that both secrets survived, which the optimistic verify
  delivers with the lock removed entirely. It now asserts the parent's `set`
  has *not* settled while a child holds the lock — an observation only a real
  lock produces. Verified by removing `withSecretFileLock` from `mutate`:
  three tests fail, where none did before.

The degrade test's "lock cannot be created" case is now a path whose parent
is a *file* rather than a missing directory, since a missing directory is no
longer that case. It also fails identically for root, so it cannot pass
locally and flake in a container.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JTHVxSu8AUgHRLvo1ntZ8H
Signed-off-by: cliffhall <cliff@futurescale.com>
2026-08-23 09:49:01 -04:00
..
file-lock.ts fix(auth): address Copilot review round 1 on the secrets-file lock (#2082) 2026-08-23 09:49:01 -04:00
file-secret-store.ts feat(auth): give the secrets file a real cross-process lock (#2082) 2026-08-23 09:32:41 -04:00
index.ts chore: close quality-gate coverage gaps (#1689) (#1766) 2026-07-24 17:20:12 -04:00
oauth-callback-server.ts feat(web): enforce localhost-only binding; expand loopback origin allow-list (#1796) 2026-07-26 22:15:10 -04:00
oauth-persist-file.ts fix(auth): keep oauth-persist browser-safe (move Node file backend out) 2026-07-08 16:20:31 -04:00
runner-interactive-oauth.ts fix(auth): explicit re-authorize when the OAuth callback state was lost (#1808) (#1810) 2026-07-27 18:08:31 -04:00
runner-oauth-callback.ts chore(deps): migrate to eslint 10 to clear the brace-expansion DoS advisory (#1900) 2026-08-01 20:13:30 -04:00
secret-store-selection.ts fix(auth): address Copilot review round 1 on the secrets-file lock (#2082) 2026-08-23 09:49:01 -04:00
secret-store.ts fix(auth): stop losing preserved plaintext, and claim the hand-off file atomically 2026-08-22 21:34:34 -04:00
storage-node.ts CLI: catalog listing, auth flags, and OAuth browser UX (#1782) 2026-07-26 16:55:25 -04:00