fix(auth): tolerate full hostnames in --account input#15
Conversation
Telemetry showed 9 distinct users got a TLS x509 error during "dhq auth login" because they typed their full account hostname (e.g. "uniportal.deployhq.com") at the "Account subdomain:" prompt. The CLI naively appended ".deployhq.com" and built a request to https://uniportal.deployhq.com.deployhq.com/projects, which is covered by the *.deployhq.com cert only at depth 1, hence the verification failure. - Add a normalizeAccount helper that strips scheme, paths, and a trailing ".<host>" suffix, then apply it in runAuthLogin after collecting --account (from either flag or prompt) so the stored value is canonical. - Defensively strip ".deployhq.com" in sdk.New so existing users who already stored a polluted account get healed on next run without needing to re-login. - Mirror the strip in config.BaseURL for staging/self-hosted hosts. - Clarify the interactive prompt with the example from the flag help so users know to enter the bare subdomain. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
WalkthroughThe PR adds account input normalization across the CLI, config, and SDK layers. A new ChangesAccount input normalization across CLI and SDK
🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
…#18) Telemetry for "dhq hello" (interactive setup) showed 15 internal errors over 30d that were really auth/user failures dressed up as CLI bugs: - 8 were ".deployhq.com.deployhq.com" TLS errors (users typed their full hostname at the "Account subdomain:" prompt). - 4 were 403 (AccessDenied x2 + api_access_restricted x2). - 3 were 404 Not found on the validate-credentials API call. The URL-doubling case is already covered defensively in sdk.New (PR #15). What's left is helloLogin wrapping the validation error in *output.InternalError unconditionally, which bypasses ClassifyError's status-code fallback (PR #16) and gives users a generic "internal error" message instead of an actionable hint. Changes: - Clarify the interactive prompt to "Account subdomain (e.g. 'mycompany' for mycompany.deployhq.com):" — same example shown in the --account flag help. Lifts the hint into the moment it's needed. - Extract classifyHelloValidateErr that maps the validation API error to AuthError (401, 403) or UserError (404) or NetworkError, and returns nil for everything else so the raw error passes through. ClassifyError can then handle 5xx via its status-code fallback once PR #16 lands; if it doesn't, behavior matches main today. - Uses errors.As so the change is self-contained and doesn't depend on sdk.IsForbidden (added in PR #16). Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Telemetry showed 9 distinct users got a TLS
x509: certificate is valid for *.deployhq.comerror duringdhq auth loginbecause they typed their full account hostname (e.g.uniportal.deployhq.com) at theAccount subdomain:prompt. The CLI naively appended.deployhq.comand built a request tohttps://uniportal.deployhq.com.deployhq.com/projects, which the wildcard cert doesn't cover.Examples from telemetry (Mixpanel, last 30d):
uniportal.deployhq.com.deployhq.comfatchip-gmbh.deployhq.com.deployhq.comrecovery-guide.deployhq.com.deployhq.comabdelkarim.deployhq.com.deployhq.com(×2)florianmatthias.deployhq.com.deployhq.comundigital.deployhq.com.deployhq.comjmdentand.deployhq.com.deployhq.comwooltown.deployhq.com.deployhq.comChanges
normalizeAccount(input, host)helper that strips scheme, paths, and a trailing.<host>suffix.runAuthLoginafter collecting--account(from either flag or prompt) so the stored value is canonical..deployhq.cominsdk.Newso existing users with already-polluted stored accounts get healed on next run without needing to re-login.config.BaseURLfor staging/self-hosted hosts.Test plan
go build ./...,go vet ./...,go test ./...,golangci-lint runTestNormalizeAccountcovers: bare subdomain, full hostname, https/http schemes, trailing slash, path, query string, surrounding whitespace, hyphenated subdomains, custom staging host (host-suffix only stripped when it matches the configured host).dhq auth login --account uniportal.deployhq.com --email ... --api-key ...succeeds.dhq auth login --account https://uniportal.deployhq.com/ --email ... --api-key ...succeeds.🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Updates
Tests