fix: address the four suppressed findings from review round 20 (#2144)

Copilot reported "no new comments" again, with four real findings in its
suppressed block.

- The web in-flight lock was global, so a pending clear for server A silently
  swallowed a click on server B's — even though the callback explicitly
  supports clearing a non-active server. Keyed by server id now.
- `else if (!isActive)` skipped the resume-snapshot cleanup when the target IS
  active but has no client yet, which is reachable while a session is being
  built or torn down. The clear then emptied storage and left stale OAuth
  recovery state pointing at credentials that no longer existed.
- `revocationAuthMethods` returned `[]` for an omitted
  `revocation_endpoint_auth_methods_supported`, which does not enforce RFC
  8414's default: an empty list means "the metadata said nothing" to
  `selectClientAuthMethod`, which then honors the registration's own
  `token_endpoint_auth_method`. The default is named literally now.
- The `v8 ignore` on the CLI budget branch was wrong, and the challenge to it
  was right: an injected `budgetMs` of zero reaches it directly, through a seam
  I had added myself the round before. Removed, and covered by a test that
  asserts no request is made and the unattempted key is reported.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177mPHAdECD18nLLCTwR5rh
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-08-28 08:20:42 -04:00
commit 1f2e3e1744

View file

@ -101,16 +101,21 @@ describe("revocationAuthMethods", () => {
token_endpoint_auth_methods_supported: ["client_secret_post"],
}),
),
).toEqual([]);
).toEqual(["client_secret_basic"]);
});
it("yields nothing when the revocation list is absent", () => {
expect(revocationAuthMethods(metadata())).toEqual([]);
// Named literally, not left empty. An empty list means "the metadata said
// nothing" to `selectClientAuthMethod`, which then honors whatever the
// client's own registration declares — so a client registered
// `client_secret_post` could put credentials in the body of a request to an
// endpoint that promised only Basic. (`OAuthClientInformation` does not carry
// that field, so this path cannot construct the case today; naming the
// default is what keeps it true if the type widens.)
it("names the RFC 8414 default when the revocation list is absent", () => {
expect(revocationAuthMethods(metadata())).toEqual(["client_secret_basic"]);
});
// The empty list is not "no authentication": it is what makes the SDK apply
// RFC 8414's actual default.
it("an empty list resolves to the RFC 8414 default", () => {
it("the default resolves to Basic for a confidential client", () => {
const { init } = buildRevocationRequest({
endpoint: REVOKE_URL,
token: "r",
@ -121,7 +126,7 @@ describe("revocationAuthMethods", () => {
expect(headerOf(init, "Authorization")).toBe(`Basic ${btoa("cid:sec")}`);
});
it("an empty list leaves a public client unauthenticated", () => {
it("the default leaves a public client unauthenticated", () => {
const { init } = buildRevocationRequest({
endpoint: REVOKE_URL,
token: "r",