fix(MM-144): address PR review feedback on account creation and keychain handling
CRITICAL fix:
- Prevent orphaned private key on token-storage failure: add keychain::delete_item()
and best-effort cleanup when device-token or session-token write fails after relay
201 success. This prevents a situation where the account is created on relay but
the device has no tokens due to local Keychain failure.
IMPORTANT fixes:
- Map keychain failures to new CreateAccountError::KeychainError (not Unknown),
giving users accurate error message: 'Couldn't save credentials to your device.
Try again.' instead of misleading 'Couldn't reach the server.'
- Distinguish UNKNOWN from NETWORK_ERROR: NETWORK_ERROR is genuine connectivity
failure, UNKNOWN is for relay-reachable errors (e.g., unrecognized 409 subcodes).
Frontend routes each to different screens with appropriate messages.
- Fix 404 comment to clarify relay returns 404 for both invalid and expired codes.
- Add unit test for 409 subcode dispatch table to prevent typos in
CLAIM_CODE_REDEEMED/ACCOUNT_EXISTS/HANDLE_TAKEN mapping.
- Fix HandleScreen handle validation: change from non-empty string to ATProto
regex /^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?$/ to prevent relying on
relay validation for invalid formats.
- Update CreateMobileAccountResponse comment to note that relay returns 5 fields
but only 3 are captured (additional fields ignored by serde).
- Add console.error for unexpected nextStep values in submit flow.
- Update ipc.ts with KEYCHAIN_ERROR variant and clean up JSDoc.
- Add Cargo.toml comment explaining rustls-tls requirement (no OpenSSL on iOS).
- Update CLAUDE.md to clarify keypair generation behavior: fresh keypair per
attempt (with best-effort Keychain cleanup on failure), not retry reuse.
TESTS:
- Add CreateAccountError::KeychainError serialization test
- Add CreateAccountError::Unknown serialization test
- Add 409 subcode dispatch table test (verifies correct mapping of
CLAIM_CODE_REDEEMED, ACCOUNT_EXISTS, HANDLE_TAKEN, unknown subcodes)
All tests pass: cargo test --workspace (231 tests)
Clippy: no warnings
Formatting: passes
Frontend: pnpm build succeeds, svelte-check passes
authored by
malpercio.dev
and committed by