Adapts the login flows to usernames (includes a DB migration). Tested with unit + e2e tests and manually end-to-end.
- What this branch does (one line): introduces usernames across the passkey login flows so we can move off broadcasting all credentials, with a zero-touch migration path for existing users.
- Migration — no passkey churn: because we don't re-derive passkeys, there's nothing to remove/re-add. The migration is simply: pick a username if you haven't — same for everyone, non-resident or resident keys.
- UI forces it: you can't do anything until you've claimed a username.
- CLI forces it too: it requires the passkey to sign the claim.
- Works with --qr, and I added a --username flag you can pass alongside --qr for non-resident keys.
- New gateway flag LOGIN_ALLOW_BROADCAST: set it to false and we stop sending the full allowCredentials list — this stops leaking everyone's credentials. Trade-off: anyone with non-resident-only keys and no username can no longer log in. Mitigation for those users: contact us and we hand them their auto-generated legacy username (e.g. u_2dbdee49).
- e2e tests: added a software-passkey round-trip test (test_webauthn_roundtrip.sh + a standalone soft-authenticator Rust helper using webauthn-authenticator-rs) that does a real register + login assertion ceremony against a live gateway — covering the finish-side signature verification that the existing begin-side tests couldn't.
(削除) Note this covers the non-resident path; resident/discoverable browser coverage (Chrome virtual authenticator) is a planned follow-up. (削除ここまで) - Chrome CDP e2e test (discoverable login): Puppeteer test (test_webauthn_browser.sh → browser-authenticator/cdp-passkey.mjs) attaches a CDP virtual authenticator, registers a real resident passkey through the actual Vue UI, then logs in username-less via the discoverable path (LOGIN_ALLOW_BROADCAST=false, empty allowCredentials, resolved by userHandle). Unlike the earlier Rust soft-authenticator test (ee7, non-resident only — SoftPasskey can't mint resident credentials), this covers the branch's actual feature end-to-end: the real useWebAuthn.js glue, the gateway's discoverable begin/finish path, and Chrome's own WebAuthn stack.