harden(app): keep native token + backup-safe secure storage

Merged
UN
2mo ago
+29-3

Summary

Follow-up to #11917. That squash landed the Flutter secure-storage move before the Codex items were on the branch.

Ports from #11352 (now closed) plus the Codex review:

  • Mirror authToken to nativeAuthToken in prefs so Android BLE/WS can still read a token after the Flutter key is gone from SharedPreferences.
  • OmiBackgroundAudioStreamer reads nativeAuthToken, then falls back to authToken.
  • android:allowBackup="false" so encrypted prefs cannot restore without the keystore key.
  • iOS Keychain accessibility is first_unlock so a locked BLE restore can still get the token.
  • If secure-store migration fails, keep the leftover prefs token instead of logging the user out.

Test plan

  • Fresh login: Flutter session works; Android background streamer can auth.
  • Upgrade from a pre-#11917 install: token migrates; native path still has nativeAuthToken.
  • iOS locked-device BLE restore after first unlock.
  • Confirm no backend/token-format change (app-only).

[!NOTE]
Medium Risk
Touches session-token storage, Android backup, and iOS Keychain accessibility. Native still mirrors the token in SharedPreferences for background BLE/WS.

Overview
Follow-up to the Flutter secure-storage migration so native Android can still auth background transcription after authToken leaves SharedPreferences.

Mirrors the live session into a dedicated nativeAuthToken prefs key on init, set, and delete. OmiBackgroundAudioStreamer reads that first, then falls back to authToken. If a secure write fails, init still uses a leftover prefs token instead of logging the user out.

Also sets android:allowBackup="false" so encrypted prefs cannot restore without the keystore key, and uses iOS Keychain first_unlock so a locked-device BLE restore can still read the token. Migration tests now assert the native mirror.

Reviewed by Cursor Bugbot for commit d4934527002a7addbab9a0bcbb421b3869f4ba5c. Configure here.