99 lines
4.2 KiB
Markdown
99 lines
4.2 KiB
Markdown
# TASK METADATA
|
|
|
|
- **Target Files:** `ui/components/LoginPage.tsx`,
|
|
`ui/components/RegisterPage.tsx`, `ui/components/RecoveryPage.tsx`,
|
|
`ui/public/auth-client.js`, `server/main.ts`, `server/recovery.ts`
|
|
- **Core Objective:** Modernize the login, registration, and recovery screens
|
|
with one-tap hero passkey trigger, WebAuthn conditional mediation, and full
|
|
2-step onboarding featuring Recovery PIN setup and 12-Word BIP-39 voucher
|
|
generation.
|
|
- **Dependencies:**
|
|
`tasks/new/2026-0824.04.gem.feat.ui-shell.design-tokens-and-adaptive-nav-2215.md`
|
|
- **Additional Important Notes:** Must support seamless WebAuthn conditional
|
|
mediation (`startAuthentication(..., true)`) and provide a zero-knowledge
|
|
12-word BIP-39 recovery voucher generated in-browser during account
|
|
registration.
|
|
|
|
---
|
|
|
|
## 1. TASK METADATA
|
|
|
|
The header block specifies the authentication templates, client-side WebAuthn
|
|
handler, recovery endpoints, core objective, dependencies, and constraints.
|
|
|
|
## 2. Architectural Considerations & Risks
|
|
|
|
### Risks
|
|
|
|
- **Autofill Abort Collisions:** If conditional mediation
|
|
(`mediation: 'conditional'`) is running in the background and the user
|
|
explicitly taps "Sign In with Passkey", some browsers can throw an
|
|
`AbortError` if not handled cleanly.
|
|
- _Mitigation:_ Cancel or ignore active conditional mediation promises before
|
|
starting explicit user-gesture WebAuthn authentication.
|
|
- **Zero-Knowledge Recovery Voucher Loss:** If the 12-word BIP39 seed phrase
|
|
during registration is skipped or lost without user confirmation, the account
|
|
cannot be recovered if the physical device is lost.
|
|
- _Mitigation:_ Provide a clear, high-contrast 12-word grid with a prominent
|
|
1-tap "Copy All Words" clipboard button and require a confirmation
|
|
acknowledgment before proceeding to the dashboard.
|
|
- **Server Share Storage Security:** The Hot Server Share must be stored with a
|
|
strong Argon2id/SHA-256 hash of the user's PIN in `recovery_shares` and
|
|
rate-limited.
|
|
|
|
### Alternatives
|
|
|
|
- **Static Username Input vs Progressive Disclosure:** Showing a prominent
|
|
username input confuses 95%+ of mobile passkey users whose credentials are
|
|
discoverable resident keys. Collapsing the username field into an expandable
|
|
drawer retains full backward compatibility for non-resident keys while
|
|
providing a clean 1-tap experience for passkeys.
|
|
|
|
## 3. Proposed Implementation
|
|
|
|
### Phase 1: Hero Passkey Login Screen
|
|
|
|
1. Refactor `ui/components/LoginPage.tsx`:
|
|
- Add a 52px biometric hero button: "Sign In with Passkey" with fingerprint
|
|
SVG icon and subtle focus/press feedback.
|
|
- Collapse optional username field and USB instructions behind an accessible
|
|
`<details>` / toggle trigger.
|
|
- Add pulse/spinner state when authenticator is active.
|
|
|
|
### Phase 2: WebAuthn Client Conditional UI
|
|
|
|
1. Update `ui/public/auth-client.js`:
|
|
- Check `PublicKeyCredential.isConditionalMediationAvailable()` on page load.
|
|
- If available, trigger
|
|
`SimpleWebAuthnBrowser.startAuthentication(options, true)` in conditional
|
|
mode.
|
|
- On explicit button click, execute modal WebAuthn login.
|
|
|
|
### Phase 3: Registration & 12-Word Voucher Setup Flow
|
|
|
|
1. In `ui/components/RegisterPage.tsx`:
|
|
- Step 1: Username & Invite Code validation.
|
|
- Step 2: Passkey creation via WebAuthn.
|
|
- Step 3 (Recovery Setup): Prompt the user to set a **Recovery PIN** (minimum
|
|
6 digits/chars) and generate the 2-of-3 SSS shares in-browser via
|
|
Wasm/WebCrypto.
|
|
- Display the **12-Word BIP-39 Recovery Voucher** in a clean 2-column mobile
|
|
card grid with a 1-tap "Copy Words" button.
|
|
- Send the encrypted Server Share + PIN hash to the backend to persist in
|
|
`recovery_shares`.
|
|
|
|
### Phase 4: Account Recovery Verification Matrix
|
|
|
|
1. In `ui/components/RecoveryPage.tsx`:
|
|
- Support auto-advance input matrix and paste-all text box for 12-word seed
|
|
phrase verification.
|
|
- Connect client-side Wasm reconstructor to bind a replacement passkey upon
|
|
successful validation.
|
|
|
|
### Phase 5: Verification & Quality Gates
|
|
|
|
1. Run `deno fmt ui/**/*.tsx ui/public/**/*.js server/**/*.ts`.
|
|
2. Run `deno task lint` and `deno task check`.
|
|
3. Run `deno task test` to verify zero regression in authentication endpoints
|
|
and redirects.
|