Skip to content

feat(login): add token login#1082

Open
runeb wants to merge 1 commit into
mainfrom
login-token-auth
Open

feat(login): add token login#1082
runeb wants to merge 1 commit into
mainfrom
login-token-auth

Conversation

@runeb
Copy link
Copy Markdown
Member

@runeb runeb commented May 14, 2026

Description

Adds sanity login --with-token for token-based CLI login from standard input. The token is validated through users/me; any token accepted by that endpoint is stored in the normal CLI auth config, while invalid or expired tokens fail before storage.

All login flows now use the same auth-token storage path, which clears cached telemetry consent and handles previous-token cleanup. When replacing an existing token, the CLI checks whether the previous token is a Sanity API token and skips /auth/logout for API tokens because the backend does not treat them as sessions. Expired previous tokens are also ignored.

Fixes AIGRO-4983

What to review

Review the sanity login --with-token < token.txt flow, token validation, previous-token invalidation behavior, TTY/stdin handling, and telemetry handling in packages/@sanity/cli/src/actions/auth/login/ and packages/@sanity/cli/src/commands/login.ts.

Testing

  • CI=true mise exec -- pnpm test packages/@sanity/cli/src/commands/__tests__/login.test.ts packages/@sanity/cli/src/actions/auth/login/__tests__/login.vercel.test.ts
  • mise exec -- pnpm check:types
  • mise exec -- pnpm check:lint
  • mise exec -- pnpm check:deps
  • mise exec -- pnpm --filter @sanity/cli readme

Latest affected login tests passed with 50 passed and 0 failed.

@runeb runeb requested a review from a team as a code owner May 14, 2026 17:22
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 14, 2026

📦 Bundle Stats — @sanity/cli

Compared against main (f0906a04)

@sanity/cli

Metric Value vs main (f0906a0)
Internal (raw) 2.1 KB -
Internal (gzip) 799 B -
Bundled (raw) 10.97 MB -
Bundled (gzip) 2.06 MB -
Import time 836ms +1ms, +0.1%

bin:sanity

Metric Value vs main (f0906a0)
Internal (raw) 975 B -
Internal (gzip) 460 B -
Bundled (raw) 9.84 MB -
Bundled (gzip) 1.77 MB -
Import time 1.98s +12ms, +0.6%

🗺️ View treemap · Artifacts

Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

📦 Bundle Stats — @sanity/cli-core

Compared against main (f0906a04)

Metric Value vs main (f0906a0)
Internal (raw) 96.2 KB -
Internal (gzip) 22.5 KB -
Bundled (raw) 21.61 MB -
Bundled (gzip) 3.42 MB -
Import time 782ms -7ms, -0.8%

🗺️ View treemap · Artifacts

Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

📦 Bundle Stats — create-sanity

Compared against main (f0906a04)

Metric Value vs main (f0906a0)
Internal (raw) 976 B -
Internal (gzip) 507 B -
Bundled (raw) 50.7 KB -
Bundled (gzip) 12.6 KB -
Import time ❌ ChildProcess denied: node -
Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

@runeb runeb force-pushed the login-token-auth branch from 730a467 to 8560211 Compare May 14, 2026 17:27
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8560211. Configure here.

Comment thread packages/@sanity/cli/src/actions/auth/login/login.ts
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 14, 2026

Coverage Delta

File Statements
packages/@sanity/cli/src/actions/auth/login/login.ts 100.0% (±0%)
packages/@sanity/cli/src/actions/auth/login/validateToken.ts 100.0% (new)
packages/@sanity/cli/src/commands/login.ts 100.0% (±0%)

Comparing 3 changed files against main @ f0906a0412d9393185bff3be1ec2c2dd9c59ec9d

Overall Coverage

Metric Coverage
Statements 84.3% (+ 0.0%)
Branches 74.3% (+ 0.1%)
Functions 84.2% (+ 0.0%)
Lines 84.8% (+ 0.0%)

@runeb runeb force-pushed the login-token-auth branch 3 times, most recently from 1ba4f10 to 8d40a04 Compare May 14, 2026 19:14
@sanity-io sanity-io deleted a comment from squiggler-app Bot May 14, 2026
@sanity-io sanity-io deleted a comment from cursor Bot May 14, 2026
@sanity-io sanity-io deleted a comment from claude Bot May 14, 2026
@claude
Copy link
Copy Markdown

claude Bot commented May 14, 2026

Claude finished @runeb's task in 3m 32s —— View job


Review

No blocking issues. The implementation is clean, well-tested (100% coverage on new code), and the design choices (stdin-only token input, validation before storage, identical post-storage path as OAuth) are sound.

Notes on the Cursor Bugbot finding

Token login failures don't record telemetry trace errors

This is already fixed in the current head (5855ab7). The token branch in login.ts:54-61 wraps validateToken in a try/catch that calls trace.error(err as Error), and there's a regression test for it in login.vercel.test.ts:120-132. The Bugbot review targeted an older commit (85602116).

Minor (non-blocking) observations

  • Duplicated error string. The message 'Token is required on standard input. Run \sanity login --with-token < token.txt`.' appears in both [commands/login.ts:89-91](packages/@sanity/cli/src/commands/login.ts#L89-L91) (TTY guard) and [validateToken.ts:11-13`](packages/@sanity/cli/src/actions/auth/login/validateToken.ts#L11-L13) (empty-token guard). Extracting to a shared constant would keep the two copies from drifting.

  • requireUser: true in validateToken. validateToken.ts:34-38 passes requireUser: true together with an explicit token. The flag is redundant when a token is provided (the check in getGlobalCliClient only triggers when token is absent), but harmless. Worth dropping for clarity.

  • 401 vs 403 in validateToken. Treating 403 as "invalid or expired" alongside 401 is reasonable, but a 403 from /users/me more typically means the token is valid but lacks the required scope — the message could mislead a user whose token is genuinely scoped wrong. Low priority, leave as-is unless support reports confusion.

  • Test style consistency (CLAUDE.md). The new token tests correctly use if (error) throw error per repo guidelines. Pre-existing OAuth tests in this file still use expect(error).toBeUndefined() — not introduced by this PR, just noting in case a follow-up wants to align them.

Changeset

.changeset/login-token.md is appropriate: minor bump matches the new public flag, the summary is one concise developer-facing sentence with no marketing voice or implementation detail.


  • Read changed files
  • Analyze login.ts changes
  • Analyze validateToken.ts
  • Analyze login command (CLI flag, stdin handling)
  • Review tests and coverage
  • Verify changeset
  • Post final review
    · Branch

@runeb runeb force-pushed the login-token-auth branch 3 times, most recently from ca76513 to d8d9590 Compare May 14, 2026 20:01
@runeb runeb force-pushed the login-token-auth branch from d8d9590 to 5855ab7 Compare May 14, 2026 20:19
@runeb runeb requested review from binoy14 and rexxars May 14, 2026 20:29
Copy link
Copy Markdown
Member

@rexxars rexxars left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

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.

2 participants