feat(cli): interactive register server picker + Bitwarden-cloud routing#44
Merged
Conversation
`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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
vault registerwith no--serveron a terminal now presents a server picker instead of erroring: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), sobitwarden.com/.eucould never connect — the split constructorbitwarden_hosted()existed but had zero call sites.Changes
vault-apiBaseUrls::bitwarden_eu()—api.bitwarden.eu+identity.bitwarden.eu, mirroringbitwarden_hosted().BaseUrls::infer_from(server)— routes*.bitwarden.com→ US split,*.bitwarden.eu→ EU split, elseself_hosted. This is the method the orphanederror.rsdoc comment already referenced. The suffix match is apex-anchored, so lookalike hosts (bitwarden.com.evil.example) fall through toself_hosted.infer_fromtests intests/parsing.rs.vault-agentensure_online(state.rs) andonline_unlock(unlock.rs) callinfer_frominstead ofself_hosted. The stored server string andaccount_dir_namecache-dir scheme are untouched, so existing caches don't orphan.vault-clicmd_registerresolves server/email via newresolve_register_server/resolve_register_email: flag → env → (TTY only) prompt. Off a TTY with neither flag nor env, it prints the samevault: missing --server (or $VAULT_SERVER)and exits 2 — the non-interactive contract is preserved (piped/scriptedregisternever hangs).resolve_argreplaced by the non-erroringarg_or_envhelper.Advances the still-open PRD §11.1 end-to-end-against-bitwarden.com gate.
Verification
infer_fromunit tests (US/EU/subdomain/self-host/lookalike/garbage) — pass.-D warnings) — clean.RUSTFLAGS="-D warnings" cargo test --workspace --all-targets— all pass, 0 failures.printf '' | vault register→vault: missing --server (or $VAULT_SERVER), exit 2 (no hang). Verified.register → login → syncagainst bitwarden.com is the maintainer step (real account).🤖 Generated with Claude Code