Skip to content

feat(cli): interactive register server picker + Bitwarden-cloud routing#44

Merged
UnbreakableMJ merged 1 commit into
mainfrom
register-server-picker
Jun 22, 2026
Merged

feat(cli): interactive register server picker + Bitwarden-cloud routing#44
UnbreakableMJ merged 1 commit into
mainfrom
register-server-picker

Conversation

@UnbreakableMJ

Copy link
Copy Markdown
Contributor

Summary

vault register with no --server on a terminal now presents a server picker instead of erroring:

Select a server:
  1) Bitwarden cloud — US (bitwarden.com)
  2) Bitwarden cloud — EU (bitwarden.eu)
  3) Vaultwarden / other self-hosted (enter URL)

Choosing a cloud option is only honest because this PR also wires split-domain routing into the agent. Previously the live unlock path (ensure_online, online_unlock) always built <server>/api + <server>/identity (the Vaultwarden single-origin shape), so bitwarden.com/.eu could never connect — the split constructor bitwarden_hosted() existed but had zero call sites.

Changes

vault-api

  • BaseUrls::bitwarden_eu()api.bitwarden.eu + identity.bitwarden.eu, mirroring bitwarden_hosted().
  • BaseUrls::infer_from(server) — routes *.bitwarden.com → US split, *.bitwarden.eu → EU split, else self_hosted. This is the method the orphaned error.rs doc comment already referenced. The suffix match is apex-anchored, so lookalike hosts (bitwarden.com.evil.example) fall through to self_hosted.
  • 6 new infer_from tests in tests/parsing.rs.

vault-agent

  • ensure_online (state.rs) and online_unlock (unlock.rs) call infer_from instead of self_hosted. The stored server string and account_dir_name cache-dir scheme are untouched, so existing caches don't orphan.

vault-cli

  • cmd_register resolves server/email via new resolve_register_server / resolve_register_email: flag → env → (TTY only) prompt. Off a TTY with neither flag nor env, it prints the same vault: missing --server (or $VAULT_SERVER) and exits 2 — the non-interactive contract is preserved (piped/scripted register never hangs).
  • single-use resolve_arg replaced by the non-erroring arg_or_env helper.

Advances the still-open PRD §11.1 end-to-end-against-bitwarden.com gate.

Verification

  • infer_from unit tests (US/EU/subdomain/self-host/lookalike/garbage) — pass.
  • CI-exact fresh-isolated clippy (-D warnings) — clean.
  • RUSTFLAGS="-D warnings" cargo test --workspace --all-targets — all pass, 0 failures.
  • Non-interactive contract: printf '' | vault registervault: missing --server (or $VAULT_SERVER), exit 2 (no hang). Verified.
  • Manual interactive picker + live register → login → sync against bitwarden.com is the maintainer step (real account).

🤖 Generated with Claude Code

`vault register` with no --server on a TTY now shows a server picker
(Bitwarden cloud US / EU / self-hosted) instead of erroring. Choosing a
cloud option only works because this also wires split-domain routing into
the agent — previously the live unlock path always used the single-origin
self_hosted shape, so bitwarden.com/.eu could never connect.

vault-api:
- add BaseUrls::bitwarden_eu() (api/identity.bitwarden.eu), mirroring
  bitwarden_hosted().
- add BaseUrls::infer_from(server): route *.bitwarden.com -> US split,
  *.bitwarden.eu -> EU split, else self_hosted. Implements the method the
  orphaned error.rs doc comment already referenced. Suffix match is
  apex-anchored (lookalike hosts fall through to self_hosted).
- 6 infer_from tests in tests/parsing.rs.

vault-agent:
- ensure_online (state.rs) + online_unlock (unlock.rs) now call infer_from
  instead of self_hosted. The stored server string and cache-dir scheme are
  untouched, so existing caches don't orphan.

vault-cli:
- cmd_register resolves server/email via new resolve_register_server/
  _email: flag -> env -> (TTY only) prompt. prompt_server renders the menu
  and maps choices to canonical origins; self-hosted prompts for a URL that
  the existing http(s):// check validates. Off a TTY with neither flag nor
  env, it still prints the same "missing --server" error and exits 2 — the
  non-interactive contract is preserved (piped register never hangs).
- replace single-use resolve_arg with the non-erroring arg_or_env helper.

Advances the still-open PRD §11.1 end-to-end-against-bitwarden.com gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@UnbreakableMJ UnbreakableMJ merged commit f244c86 into main Jun 22, 2026
9 checks passed
@UnbreakableMJ UnbreakableMJ deleted the register-server-picker branch June 22, 2026 15:27
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