Skip to content

feat(auth): add headless OAuth login mode#13

Merged
stefanosala merged 3 commits into
mainfrom
feat/headless-auth-login
May 22, 2026
Merged

feat(auth): add headless OAuth login mode#13
stefanosala merged 3 commits into
mainfrom
feat/headless-auth-login

Conversation

@stefanosala

Copy link
Copy Markdown
Owner

Summary

  • add auth login --headless so login can complete without a local callback listener
  • print the OAuth authorization URL and accept a pasted callback URL containing code and state
  • keep PKCE/state validation and token persistence aligned with the existing browser-based flow

Test plan

  • cargo fmt
  • cargo test
  • cargo run -- auth login --headless (manual verification of headless prompt and callback handling)

Made with Cursor

Add a headless login path that prints the authorization URL and accepts a pasted callback URL, so OAuth can complete without a local listener. This keeps PKCE/state validation and token persistence aligned with the existing login flow.

Co-authored-by: Cursor <cursoragent@cursor.com>
@stefanosala stefanosala self-assigned this May 22, 2026
Document where to find the vc-cli skill reference and add explicit guidance for using `auth login --headless` in agent/server contexts so users can complete OAuth pasteback reliably.

Co-authored-by: Cursor <cursoragent@cursor.com>
@stefanosala stefanosala marked this pull request as ready for review May 22, 2026 15:57
Copilot AI review requested due to automatic review settings May 22, 2026 15:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds a headless OAuth login mode to vc-cli auth login so authentication can complete on hosts that can’t open a browser or run a local callback listener, while keeping PKCE/state validation and token persistence aligned with the existing flow.

Changes:

  • Introduces --headless flag to print the authorization URL and prompt for a pasted redirect callback URL.
  • Adds parsing/validation helpers for pasted callbacks and redirect URI path validation.
  • Updates CLI docs/tests (README + skill docs) to describe and cover the new mode.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
src/commands/auth_login.rs Implements headless pasteback flow, callback parsing, and redirect URI path validation; adds unit tests.
src/cli/mod.rs Adds --headless flag wiring from clap CLI args into command execution; adds parsing test.
skills/vc-cli/SKILL.md Documents auth login --headless behavior for agent usage.
README.md Adds quick-start guidance and notes for headless login and skill docs location.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/commands/auth_login.rs
Comment thread src/commands/auth_login.rs Outdated
Comment thread src/commands/auth_login.rs Outdated
Skip listener-timeout validation in headless mode and reuse a single redirect URI parser for both headless and listener flows. Also reject redirect URIs that use port 0 to prevent impossible callback targets.

Co-authored-by: Cursor <cursoragent@cursor.com>
@stefanosala

Copy link
Copy Markdown
Owner Author

Addressed all unresolved review threads.

Fixed

  • Skip listener timeout validation when --headless is used, so headless login no longer depends on --auth-listen-timeout-seconds.
  • Refactor redirect URI validation into a shared parser used by both headless and listener flows to prevent drift.
  • Reject redirect URIs with port 0 for both flows.

Not fixed

  • None.

Validation

  • cargo fmt
  • cargo test (33 passed)

@stefanosala

Copy link
Copy Markdown
Owner Author

@copilot review

Copilot AI commented May 22, 2026

Copy link
Copy Markdown

@copilot review

All three review items are correctly addressed in commit f170417:

  1. Timeout validation skipped for headlessresolve_listen_timeout(value, headless) returns Ok(None) immediately when headless is true, bypassing normalize_timeout entirely. The browser path then ok_or_else-unwraps the Option<u64> at the point it's actually needed, so neither path can misuse the other's value.

  2. Shared redirect URI validatorparse_redirect_callback_target is the single source of truth for scheme, host, port, and path normalization. Both prompt_headless_callback (via redirect_target.expected_path) and bind_redirect_listener (which now accepts &RedirectCallbackTarget) consume the same pre-validated struct, so drift between the two paths is no longer possible.

  3. Port 0 rejected – the explicit if port == 0 { return Err(...) } guard in parse_redirect_callback_target covers both flows simultaneously, and the new test asserts http://127.0.0.1:0/callback is rejected.

No issues found. The implementation is clean and cargo test confirms all 33 tests pass.

@stefanosala stefanosala merged commit 093abea into main May 22, 2026
3 checks passed
@stefanosala stefanosala deleted the feat/headless-auth-login branch May 22, 2026 16:10
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.

3 participants