All checks were successful
PR Checks / android-build (pull_request) Successful in 6m22s
feat(auth): trusted devices & recovery codes on the mobile client Consumes the merged backend trusted-device + MFA feature (RunicGateway/website#93, docs#32) per docs/android/PLAN.md §4.1.1. Login (POST /auth/mobile/login): - "Trust this device" checkbox and a "use a recovery code instead" toggle on the 401 { totpRequired } step; sends trustDevice / recoveryCode / device_name and replays a stored X-Trust-Token. - A returned trustToken is stored in a dedicated, username-scoped EncryptedSharedPreferences file (runic_trust, AES-256-GCM), separate from the session store so it deliberately SURVIVES logout — the token is only consulted at a fresh login, so clearing it there would make the feature a no-op. Cleared only on a Settings→Server switch, untrust-all, or server-side revocation. (Supersedes the handoff note that said clear-on-logout; matches the canonical rg_trust design.) Account → Security: - Trusted Devices screen: list / revoke one / untrust all / trust this device (persists the returned token). - Recovery Codes screen: remaining count + password-stepped regenerate with a show-once copy/share display; the one-time batch from enabling 2FA is also surfaced on the account screen. Login-time trust cap (trustLimitReached) is surfaced + resolved on the Trusted Devices screen rather than a blocking login modal, since the native login has already issued the session. Tests: DTO decode for all new wire shapes + AccountRepository logic (the 409 cap-body parse, revoke, recovery). 154 unit tests pass; assembleDebug clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NgyHnrNa8WwG3doxvxjuCr @