Skip to content

feat(auth): add hotdata auth register command#85

Merged
eddietejeda merged 5 commits into
mainfrom
feat/auth-register
May 19, 2026
Merged

feat(auth): add hotdata auth register command#85
eddietejeda merged 5 commits into
mainfrom
feat/auth-register

Conversation

@eddietejeda
Copy link
Copy Markdown
Contributor

@eddietejeda eddietejeda commented May 19, 2026

Summary

  • Adds hotdata auth register — opens the browser to create a new Hotdata account via a PKCE handoff flow, then exchanges the auth code for a JWT session saved to ~/.hotdata/config.yml
  • Defaults to GitHub OAuth signup; pass --email to use email/password instead
  • Reuses the same local callback server and PKCE machinery as hotdata auth login
  • Companion webapp changes: hotdata-dev/monopoly#904 (base flow) and hotdata-dev/monopoly#905 (GitHub default)

Usage

```
hotdata auth register # GitHub OAuth (default)
hotdata auth register --email # email/password signup
```

Test plan

  • `hotdata auth register` opens browser to GitHub OAuth, completes signup, saves session
  • `hotdata auth register --email` opens browser to email signup page
  • Already signed-in guard prints a message and exits without overwriting session
  • PKCE code exchange at `/v1/auth/token` validates `code_verifier` correctly

🤖 Generated with Claude Code

eddietejeda and others added 3 commits May 19, 2026 09:03
Add hotdata-search and hotdata-analytics bundled skills, slim the core hotdata
skill, and expand WORKFLOWS with a decision tree and datasets vs databases
guides. Tag-only release finish for branch-protected main; validate changelog on prepare.
Onboard, Chain, and Retrieval epics link into analytics and search sub-skill references.
Opens the browser to /auth/cli-register/ with PKCE params, waits for
the provisioning-complete callback from the webapp, then exchanges the
CLIAuthCode for a full JWT session (via mint_from_api_token) so the
on-disk state is identical to a normal hotdata auth login.

Changes:
- auth.rs: add register(), refactor receive_callback to accept
  success_title/success_body for the browser confirmation page
- jwt.rs: add exchange_cli_register_code — POSTs code+verifier to
  /v1/auth/token, gets opaque API token, mints JWT session from it
- command.rs: add Register variant to AuthCommands
- main.rs: dispatch AuthCommands::Register to auth::register()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sentry
Copy link
Copy Markdown

sentry Bot commented May 19, 2026

Codecov Report

❌ Patch coverage is 53.97727% with 81 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/auth.rs 10.98% 81 Missing ⚠️

📢 Thoughts on this report? Let us know!

Comment thread src/jwt.rs
Comment thread src/auth.rs
Comment thread src/auth.rs Outdated
claude[bot]
claude Bot previously approved these changes May 19, 2026
hotdata auth register now defaults to GitHub OAuth signup; pass
--email to use email/password instead. The method query param is
forwarded to the webapp cli_register endpoint.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread src/jwt.rs
Copy link
Copy Markdown
Contributor

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Review

Blocking Issues

  • src/jwt.rs:167exchange_cli_register_code builds the token-exchange URL against app_url (https://app.hotdata.dev/v1/auth/token), but every other /v1/... route in the CLI is reached via api_url (which already includes /v1). This will hit the webapp host instead of the API. End-to-end test boxes in the PR description are unchecked, so this hasn't been verified against a real deploy yet.

Action Required

Switch the URL construction to api_url-based (mirroring sandbox_session.rs::refresh), or — if the backend really does mount this on app_url — explain that in a comment so the divergence from the existing oauth_base doc is intentional.

(Other previously-raised nits about missing tests for exchange_cli_register_code, unescaped HTML in receive_callback, and register()/login() duplication still stand from earlier review threads but are non-blocking.)

@eddietejeda
Copy link
Copy Markdown
Contributor Author

eddietejeda commented May 19, 2026

Responding to the blocking issue raised in the latest review:

src/jwt.rs:167 — oauth_base vs api_url

api_url points to https://api.hotdata.dev/v1 — a separate service that doesn't host this endpoint. Using api_url here would be the bug. oauth_base is the right base for all webapp-side endpoints (/o/... and now /v1/auth/token), which is exactly what the existing comment in oauth_base documents.

…ge_cli_register_code

- Add doc comment to receive_callback noting success_title/success_body
  are interpolated into HTML without escaping — callers must pass
  static strings only
- Extract run_browser_auth() to collapse the ~80% duplication between
  login() and register(); the two functions now each reduce to the
  signed-in guard plus a run_browser_auth call with distinct URL and
  exchange closures
- Add four tests for exchange_cli_register_code: success (two-step
  mock: /v1/auth/token then /o/token/), http_error, malformed_response,
  connection_error — matching the pattern used by mint_from_pkce_code
  and mint_from_api_token

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
claude[bot]
claude Bot previously approved these changes May 19, 2026
Copy link
Copy Markdown
Contributor

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

All prior feedback addressed: helper extraction, doc-comment tightening, and added test coverage for exchange_cli_register_code. Accepting the author's correction on the /v1/auth/token host — the companion webapp PRs make their knowledge of the routing authoritative.

@eddietejeda eddietejeda dismissed claude[bot]’s stale review May 19, 2026 19:27

The merge-base changed after approval.

@eddietejeda eddietejeda merged commit 9725898 into main May 19, 2026
10 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.

1 participant