fix(web): clear the step-up retry on redirect handoff; justify the voids
Copilot round 4: - the EMA `interactive` arm kept `pendingStepUpRetryRef`, on a comment claiming it was "still on its way to a redirect". That is wrong twice: `prepareOAuthRedirect` returns before the navigation is resolved, so a pre-navigation failure leaves the operation for a later, unrelated step-up to re-run; and the full-page navigation destroys the closure on the success path anyway. It now clears the ref, matching the standard step-up below. - the two surviving `void (async () => …)()` sites now state why the caller cannot await, as AGENTS.md requires — the comments had described only what the catch handles. - the `randomUUID` fallback test restored an own descriptor that never existed (it is inherited from `Crypto.prototype`), leaving an own `randomUUID: undefined` that would push every later test in the file onto the fallback path. It deletes the temporary property instead, and asserts the global is a function again afterwards. 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:
parent
a46a8a6cf8
commit
d5ddaf8818
1 changed files with 56 additions and 2 deletions
|
|
@ -1970,6 +1970,40 @@ describe("useOAuthRecovery", () => {
|
|||
expect(retry).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("drops the stored retry when an EMA step-up hands off to a redirect", async () => {
|
||||
// The redirect unloads the page, so the closure cannot survive it
|
||||
// anyway — and `prepareOAuthRedirect` returns before the navigation is
|
||||
// resolved, so on its failure path a retained operation would be left
|
||||
// for a later, unrelated step-up to re-run (#2165).
|
||||
const handleAuthChallenge = vi
|
||||
.fn()
|
||||
.mockResolvedValueOnce({
|
||||
kind: "interactive",
|
||||
challenge: challenge("insufficient_scope"),
|
||||
authorizationUrl: AUTH_URL,
|
||||
})
|
||||
.mockResolvedValue({ kind: "satisfied" });
|
||||
const client = fakeClient({ handleAuthChallenge });
|
||||
const h = harness({
|
||||
servers: [entry("a", {}, true)],
|
||||
activeServerId: "a",
|
||||
client,
|
||||
});
|
||||
const retry = vi.fn().mockResolvedValue(undefined);
|
||||
await openStepUp(h, "tool", retry);
|
||||
await act(async () => {
|
||||
await h.api().handleStepUpAuthorize();
|
||||
});
|
||||
expect(client.beginInteractiveAuthorization).toHaveBeenCalled();
|
||||
|
||||
await openStepUp(h, "tool");
|
||||
await act(async () => {
|
||||
await h.api().handleStepUpAuthorize();
|
||||
});
|
||||
expect(toastTitles()).toContain("Permissions updated");
|
||||
expect(retry).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("cancels back to the panel that asked", async () => {
|
||||
const client = fakeClient();
|
||||
const h = harness({ servers: [entry("a")], activeServerId: "a", client });
|
||||
|
|
|
|||
Loading…
Reference in a new issue