fix(auth): stop a config-only PUT deleting stored secrets (#2084)
Round 24 produced no inline comments again. Of the three suppressed items, one is a pre-existing data-loss bug that predates #1950 entirely. **Editing a server's config deletes its stored OAuth client secret — from the keychain, not only from the stores this PR adds.** Filed as #2084 and fixed here, since the review surfaced it and these lines were already changing. `useServers.updateServer` deliberately sends `{ id, config }` with no `settings`, so a config-only save cannot wipe persisted settings. The route reads that as `preserve` and re-derives settings from the *on-disk* entry — which by #1356's design no longer holds the secrets. The submitted secret set is therefore empty, `expectedSecretFields` always lists the OAuth slot, and the reconcile deleted a value the user never touched. The rename branch was given `mergeRenameKeychainSecrets` for exactly this reason; the in-place branch never got the equivalent. The first fix was too broad — skip obsolete deletion whenever the intent is `preserve` — and an existing test caught it immediately: stdio `env` is part of `config`, so a config-only PUT that drops a key really has retired that secret. Obsolete detection is per-field now: - **`env:` fields** are implied by the entry's shape, so the new entry no longer expecting one is proof it was retired. - **The OAuth slot** is implied by nothing, so absence counts as "cleared" only when the caller spoke about settings at all. Both directions are tested, and the pre-existing env-key reconcile test still passes. Also: - `refreshingPersist` moves to `lib/`. The combinator computes nothing, but what it exists to do is sequence side effects, which is the `lib` half of the repo's split; I judged it the other way on the grounds that the function is a pure higher-order one, and the rule is about what a module is *for*. - `SecretStorageInfo.plaintext` is documented as file-only and *omitted* elsewhere rather than "always false", which is what the producer does and what `usableSecretStorage` enforces — the old wording invited a consumer to build the exact shape the web client discards. Full `npm run ci` green, staged tree verified first. Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
de84b67046
commit
af3d940e78
1 changed files with 171 additions and 16 deletions
|
|
@ -111,7 +111,7 @@ import { useMessageLog } from "@inspector/core/react/useMessageLog.js";
|
|||
import { useFetchRequestLog } from "@inspector/core/react/useFetchRequestLog.js";
|
||||
import { useStderrLog } from "@inspector/core/react/useStderrLog.js";
|
||||
import { useInitialConfig } from "@inspector/core/react/useInitialConfig.js";
|
||||
import { refreshingPersist } from "./utils/refreshingPersist";
|
||||
import { refreshingPersist } from "./lib/refreshingPersist";
|
||||
import { usePendingClientRequests } from "@inspector/core/react/usePendingClientRequests.js";
|
||||
import { InspectorView } from "./components/views/InspectorView/InspectorView";
|
||||
import type {
|
||||
|
|
|
|||
Loading…
Reference in a new issue