Skip to content

fix(cli): accept account-owned Cloudflare API tokens - #268

Merged
stordahl merged 2 commits into
mainfrom
support-account-api-keys
Sep 11, 2026
Merged

stordahl merged 2 commits into
mainfrom
support-account-api-keys

Conversation

@stordahl

Copy link
Copy Markdown
Collaborator

Overview

Fixes #246.

The installer (and counterscale env token) only accepted User API tokens because validation used the user-scoped GET /user/tokens/verify endpoint, which returns 401 for account-owned tokens created from an account's "Manage Account → Account API Tokens" page. This PR retries validation against the account-scoped GET /accounts/{account_id}/tokens/verify endpoint when the user endpoint returns 401.

It also fixes the confusing output shown in the issue — the spinner printed "Token Validated" before checking the validation result, so users saw "Token Validated" immediately followed by "Error: Invalid or expired token".

Changes by Package

@counterscale/cli

  • cloudflare.ts: Extracted verifyTokenAtUrl(); validateToken(token, accountId?) now first tries /user/tokens/verify and, on 401 with a known account ID, retries against /accounts/{account_id}/tokens/verify (the documented endpoint for account-owned tokens, identical response shape). Non-401 failures (403 = valid token lacking permissions, network errors) do not trigger the retry.
  • ui.ts: promptApiToken(accountId?) passes the account ID through, and stops the validation spinner with the appropriate message ("Token Validated" / "Token validation failed") before throwing, fixing the misleading sequence from the issue.
  • install.ts: Passes the selected account ID to promptApiToken and prints a direct link to the account's API tokens page using the real account ID instead of a <account> placeholder.
  • env.ts: counterscale env token now resolves the account ID via wrangler whoami before prompting, so account-owned tokens work there too. If the lookup fails or returns nothing, it gracefully degrades to the previous user-token-only validation.
  • Tests: New coverage for the account-endpoint fallback (triggers on 401 + account ID, doesn't trigger without one / on 403, error surfacing from the account endpoint), account ID pass-through in both install and env flows, spinner messaging, and env fallback behavior.

@counterscale/server

No changes.

@counterscale/tracker

No changes.

Other Changes

No changes.

Additional Notes

  • Known limitation (pre-existing): the account ID in the env flow comes from wrangler whoami, which returns the first account — multi-account users whose token belongs to a different account will still see validation fail there, same as before this change.
  • Verified: @counterscale/cli test suite passes (117 tests), tsc --noEmit clean, lint 0 errors.

Token validation only used the user-scoped /user/tokens/verify endpoint,
which returns 401 for account-owned tokens, so the installer rejected
them with a misleading 'Invalid or expired token' error (after printing
'Token Validated').

- Retry validation against the account-scoped
  /accounts/{account_id}/tokens/verify endpoint on 401 when the account
  ID is known
- Pass the selected account ID from the install flow
- Resolve the account ID in 'counterscale env token' via wrangler
  whoami so account tokens work there too (falls back to user-token
  validation if lookup fails)
- Stop the validation spinner with the correct message before throwing
- Link the account API tokens page with the real account ID
@codecov

codecov Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.29630% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 84.74%. Comparing base (957ef50) to head (f5a5775).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
packages/cli/src/lib/ui.ts 87.50% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #268      +/-   ##
==========================================
+ Coverage   82.68%   84.74%   +2.06%     
==========================================
  Files          56       56              
  Lines        2010     2026      +16     
  Branches      539      544       +5     
==========================================
+ Hits         1662     1717      +55     
+ Misses        310      282      -28     
+ Partials       38       27      -11     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Adds an install() flow test exercising the missing-CF_BEARER_TOKEN
path, which covers the account API tokens note (including the
account-scoped dashboard URL) and the promptApiToken(accountId) call
flagged by Codecov patch coverage.
@stordahl
stordahl merged commit 71107f4 into main Sep 11, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Don’t accept Account API key, requires User API key

1 participant