Skip to content

[muse] fix(server): bound OAuth token HTTP calls with a 10s timeout - #10

Open
kvnloo wants to merge 4 commits into
mainfrom
muse/cli-token-oauth-http-timeout
Open

kvnloo wants to merge 4 commits into
mainfrom
muse/cli-token-oauth-http-timeout

Conversation

@kvnloo

@kvnloo kvnloo commented Sep 28, 2026

Copy link
Copy Markdown
Owner

What Changed

OAuth token HTTP calls in apps/server/src/cloud/CliTokenManager.ts now have a 10s deadline (CLOUD_CLI_OAUTH_HTTP_TIMEOUT, matching the cloud HTTP family convention in this repo):

  • exchangeToken (token-endpoint POST, used by the refresh flow and the login authorization_code exchange)
  • the initial deviceAuthorizationEndpoint POST in deviceAuthorizationLogin (the poll loop was already bounded by the device-code lifetime)

The device-authorization POST maps a timeout to CloudCliAuthorizationError. Refresh timeouts fall back to a fresh login via the existing orElseSucceed path in get.

Why

Both calls ran with no deadline. A wedged cloud endpoint hung the credential refresh under the manager's global semaphore (starving every other get caller) or dead-ended login after the browser callback had already returned. Same defect family as the unbounded protocol.ts request fixed in #4.

Validation

  • New tests in CliTokenManager.test.ts with a never-responding HttpClient mock under TestClock: stall during refresh fails with CloudCliCredentialRefreshError; stall at the device-authorization endpoint fails with CloudCliAuthorizationError. 10/10 tests green.
  • Red on base: both new tests hang until the 60s vitest timeout on the unfixed code (the defect is literally a hang), green with the fix.
  • vp fmt --check clean; tsc --noEmit shows no new errors in the touched files (only a pre-existing style suggestion matching existing file idiom).

Checklist

  • This PR is small and focused
  • I have tested the change

AI-assisted: authored with AI assistance (Muse, Meta's Muse Spark) under the contributor's direction.

Token-endpoint POSTs (refresh + authorization_code exchange) and the device
authorization POST ran with no deadline. A wedged cloud endpoint hung the
credential refresh under the manager's global semaphore, starving every other
caller, or dead-ended login after the browser callback returned.

Exchange calls now fail after 10s (the cloud HTTP family convention in this
repo); refresh timeouts fall back to a fresh login via the existing
orElseSucceed path, and the device-authorization POST maps to
CloudCliAuthorizationError.

AI-assisted: authored with AI assistance (Muse, Meta's Muse Spark) under the
contributor's direction.
@github-actions github-actions Bot added size:S vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Sep 28, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

keep pr-janitor: never auto-close size:S vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant