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 @
This commit is contained in:
@@ -201,6 +201,49 @@
|
||||
<string name="account_identity_unlinked">Account unlinked.</string>
|
||||
<string name="account_identity_error">Couldn\'t unlink that account.</string>
|
||||
|
||||
<!-- ── Trusted devices & recovery codes (TRUSTED_DEVICES_MFA.md) ─────── -->
|
||||
<!-- Login 2FA step -->
|
||||
<string name="login_recovery_code">Recovery code</string>
|
||||
<string name="login_recovery_hint">Enter one of your single-use backup codes.</string>
|
||||
<string name="login_use_recovery_instead">Use a recovery code instead</string>
|
||||
<string name="login_use_totp_instead">Use your authenticator code instead</string>
|
||||
<string name="login_trust_device">Trust this device (skip codes for 30 days)</string>
|
||||
|
||||
<!-- Account: security section -->
|
||||
<string name="account_security_title">Security</string>
|
||||
<string name="account_security_trusted_devices">Trusted devices</string>
|
||||
<string name="account_security_recovery_codes">Recovery codes</string>
|
||||
|
||||
<!-- Trusted devices screen -->
|
||||
<string name="trusted_devices_title">Trusted devices</string>
|
||||
<string name="trusted_devices_subtitle">These devices can skip the authentication code at sign-in for 30 days.</string>
|
||||
<string name="trusted_devices_empty">No trusted devices yet.</string>
|
||||
<string name="trusted_devices_unknown">Unknown device</string>
|
||||
<string name="trusted_devices_last_used">Last used %1$s</string>
|
||||
<string name="trusted_devices_revoke">Revoke</string>
|
||||
<string name="trusted_devices_trust_this">Trust this device</string>
|
||||
<string name="trusted_devices_untrust_all">Untrust all devices</string>
|
||||
<string name="trusted_devices_trusted">This device is now trusted.</string>
|
||||
<string name="trusted_devices_revoked">Device revoked.</string>
|
||||
<string name="trusted_devices_revoked_all">All devices untrusted.</string>
|
||||
<string name="trusted_devices_limit">You\'ve reached the trusted-device limit. Revoke one, then try again.</string>
|
||||
<string name="trusted_devices_error">Something went wrong. Please try again.</string>
|
||||
|
||||
<!-- Recovery codes screen -->
|
||||
<string name="recovery_codes_title">Recovery codes</string>
|
||||
<string name="recovery_codes_subtitle">Single-use backup codes let you sign in if you lose your authenticator.</string>
|
||||
<string name="recovery_codes_remaining">%1$d codes remaining</string>
|
||||
<string name="recovery_codes_remaining_loading">Checking remaining codes…</string>
|
||||
<string name="recovery_codes_remaining_unknown">Couldn\'t load the remaining count.</string>
|
||||
<string name="recovery_codes_password_hint">Enter your current password to generate a new set.</string>
|
||||
<string name="recovery_codes_regenerate">Generate new codes</string>
|
||||
<string name="recovery_codes_error">Couldn\'t generate codes. Check your password and that two-factor is on.</string>
|
||||
<string name="recovery_codes_new_title">Your new recovery codes</string>
|
||||
<string name="recovery_codes_new_hint">Save these now — they\'re shown only once and each works a single time.</string>
|
||||
<string name="recovery_codes_copy">Copy</string>
|
||||
<string name="recovery_codes_share">Share</string>
|
||||
<string name="recovery_codes_done">Done</string>
|
||||
|
||||
<!-- ── Player: game-account linking (§6.3) ─────────────────────────── -->
|
||||
<string name="player_link_title">Link your game account</string>
|
||||
<string name="player_link_hint">In game, type [link to get a one-time code, then enter it here to see your characters, vendors and houses.</string>
|
||||
|
||||
Reference in New Issue
Block a user