fix(web): terminate the five void-discarded OAuth recovery promises

Each of the five sites in `useOAuthRecovery` discarded a promise with
`void`, satisfying `@typescript-eslint/no-floating-promises` but not the
narrower rule AGENTS.md states — `void` only where the callee owns its
failures or the caller cannot await, with a comment saying which.

Each now picks a user-visible outcome:

- `prepareOAuthRedirect` clears the resume snapshot (so the next load
  cannot read a redirect that never started as an *abandoned* one),
  flags the server and raises the re-auth banner.
- the `authChallengeInteractive` handler flags and banners, where before
  a rejection drew no UI response at all.
- `resumePendingReauth` restores the pending slot and toasts, so the
  next trigger retries the deferred recovery instead of losing it.
- the `/oauth/callback` effect flags and banners what falls between its
  existing arms — the client rebuild and the post-resume scope check.
- `handleStepUpAuthorize`'s EMA branch reports exactly as its `failed`
  outcome arm does; the stored retry gets its own catch, since by then
  the permissions leg succeeded and the failure is the command's.

The two surviving `void`s carry the justification AGENTS.md asks for.

Closes #2165

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Quk1hBUtyhkXowwMXzAnAY
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-08-29 01:34:40 -04:00
commit f74aa757d2

View file

@ -46,6 +46,20 @@ export function authRecoveryRestoredMessage(options?: {
: "Session credentials were updated.";
}
/**
* Toast when a *deferred* authorization recovery (#2165) fails partway
* through — the tab-visible / reconnect resume, not a user-initiated one.
*
* Phrased as "will try again" rather than as a final failure because the
* pending recovery is restored when this fires: the slot was cleared only to
* keep two triggers from racing, and it is still owed.
*/
export function authRecoveryRetryFailedMessage(detail?: string): string {
const base =
"Could not continue the pending authorization. The Inspector will try again the next time this tab becomes active or the session reconnects.";
return detail?.trim() ? `${base} (${detail.trim()})` : base;
}
export function oauthResumeAbandonedMessage(
authKind: OAuthInteractiveAuthKind,
options?: { recoverySource?: OAuthRecoverySource },