Dashboard › cli › Distillation
e25b4444-faf6-4d81-9641-bc1f6efa22ed["lore_tm_v1_pxZcyunuD1bi-ydz7FIqlJ-uViBEjYqbEstn4FeOe34","lore_tm_v1_yYeSMPXC_w44JJD1Rkn0Id65UA198eMqZkCHW9T8Wos"]
Date: Sep 10, 2026
packages/cli/src/lib/db/auth.ts getAuthConfig() (lines 158-203) reads SENTRY_FORCE_ENV_TOKEN?.trim(); when truthy, it returns getEnvToken() first. Otherwise it reads getAuthRow() in withDbSpan("getAuthConfig", ...), rejects rows without token and rows whose expires_at is in the past without refresh_token, returns stored OAuth { token, refreshToken, expiresAt, issuedAt, source: "oauth" } when usable, and only then falls back to getEnvToken(). Its comments identify this DB-first behavior as the fix for #646, preventing wizard-generated build tokens from silently overriding interactive login.packages/cli/src/lib/db/auth.ts getStoredAuthHost() (lines 216-232) reads the auth row under withDbSpan("getStoredAuthHost", ...), returns undefined without a stored token, returns row.host when present, lazily migrates pre-schema-v16 NULL hosts via migrateNullHost(row), and catches DB failures to return undefined.packages/cli/src/lib/db/auth.ts hasUsableStoredToken() (lines 243-259) returns true only when getAuthRow() has a token and the row is either unexpired, has no expiry, or is expired with a refresh_token; it catches DB errors and returns false.packages/cli/src/lib/db/auth.ts introduces getUsableStoredTokenHost() beginning at line 272 to atomically check stored-token usability and retrieve/migrate its host in one DB read, avoiding an interleaving clearAuth() between separate hasUsableStoredToken() and getStoredAuthHost() calls that could yield an inconsistent usable-token/undefined-host fallback.packages/cli/src/lib/constants.ts:83-84 lets getConfiguredSentryUrl() use an environment sntrys_ claim even when getAuthConfig() selects stored OAuth (packages/cli/src/lib/db/auth.ts:158-201) and host scoping uses stored-token host (packages/cli/src/lib/token-host.ts:54-67). Example: stored OAuth scoped to sentry.io, unforced env sntrys_ token claiming self-hosted.example, and no explicit URL routes API traffic to the claim URL while using stored OAuth, causing host scoping to reject the request before it reaches the network. Recommended regression: store OAuth, set an unforced conflicting env claim, and assert routing follows the active stored credential.packages/cli/src/lib/constants.ts:79: normalizeUrl(env.SENTRY_HOST || env.SENTRY_URL) selects whitespace SENTRY_HOST before normalization; normalizeUrl() returns undefined for whitespace at lines 52-64, so a valid SENTRY_URL is skipped and token-claim fallback at lines 83-84 is used. Recommended test: SENTRY_HOST=" ", SENTRY_URL=https://configured.example, and a distinct claim URL; expected configured URL is https://configured.example.packages/cli/src/lib/token-claims.ts:82-90 accepts any non-empty string as a claim url, while packages/cli/src/lib/constants.ts:52-64 normalizeUrl() adds only a scheme and does not validate the URL. A structurally valid claim containing an invalid URL can therefore become the configured URL and propagate through API, OAuth, DSN scanning, web-link, telemetry, region, and custom-header routing callers using constants.ts:84. Recommended fix: validate claim URL as an origin before accepting it as fallback, with coverage; malformed token syntax already safely falls through.SENTRY_HOST takes precedence over SENTRY_URL and token claims in packages/cli/src/lib/constants.ts:79-84.constants.ts import introduces no cycle because token-claims.ts has no imports.getApiBaseUrl() and authenticated routing.32/32 across constants.test.ts and sntrys-claim-mismatch.test.ts.SENTRY_URL-versus-claim precedence including whitespace SENTRY_HOST; SENTRY_TOKEN fallback and token-variable precedence; stored OAuth shadowing an env sntrys_ token; and malformed claim syntax plus malformed claim-URL behavior through getConfiguredSentryUrl().