Summary
IPTV provider credentials should be stored using platform secure storage rather than directly in the normal app database or local preference storage.
The app currently needs to persist playlist/provider credentials such as:
server URL
username
password
These values are sensitive because they can grant access to a user's IPTV provider account. They should be protected differently from normal playlist metadata such as display name, sort order, favorites, hidden categories, or cached guide data.
Proposed behavior
Store playlist metadata in the normal app database, but store secrets in platform secure storage:
App database
- playlist_id
- display_name
- server_url
- provider_type
- secret_ref
Secure storage
- secret_ref -> username/password
Recommended platform mappings:
- iOS: Keychain
- Android: Android Keystore-backed storage, such as EncryptedSharedPreferences or equivalent
- Flutter legacy app: security fixes only, or flutter_secure_storage if still supported
Why this matters
Storing IPTV credentials in a normal local database increases the chance that credentials are exposed through:
- device backups
- debug extraction
- local database inspection
- accidental support bundles
- future sync/export features
- compromised devices
- unrelated bugs that expose app database contents
Secure storage does not make credentials impossible to extract on a compromised device, but it is the standard platform pattern for app secrets and is a better default than storing passwords directly with normal application data.
Suggested implementation direction
Introduce a small credential-store abstraction per active platform.
Example shape:
CredentialStore
- saveCredential(playlistId, username, password)
- loadCredential(playlistId)
- deleteCredential(playlistId)
The database should only retain a stable reference, for example:
secret_ref = "playlist:<uuid>"
The provider clients should retrieve credentials through the credential store when making API or playback requests.
Migration approach
For existing users:
- On app startup, detect playlists with plaintext credentials in the existing database.
- Write those credentials to platform secure storage.
- Update the playlist row with a
secret_ref.
- Remove or null the plaintext password fields from the app database.
- Verify the migrated credential can be loaded successfully.
- Avoid logging any credential values during migration.
Migration should be idempotent so it can safely resume if interrupted.
Acceptance criteria
- New playlist credentials are stored in platform secure storage.
- The normal app database no longer stores plaintext passwords for newly created playlists.
- Existing plaintext credentials are migrated safely.
- Deleting a playlist also deletes its secure-storage credential entry.
- Export/debug/logging paths do not include raw usernames or passwords.
- Unit tests or equivalent checks cover save, load, delete, and migration behavior.
- iOS and Android use equivalent credential-store interfaces to reduce platform drift.
Non-goals
This issue does not need to change IPTV provider behavior or playback URL construction.
Xtream-style providers may still require credentials in API or playback URLs at request time. The goal here is to avoid storing those credentials in the normal app database and to reduce accidental exposure at rest.
Summary
IPTV provider credentials should be stored using platform secure storage rather than directly in the normal app database or local preference storage.
The app currently needs to persist playlist/provider credentials such as:
These values are sensitive because they can grant access to a user's IPTV provider account. They should be protected differently from normal playlist metadata such as display name, sort order, favorites, hidden categories, or cached guide data.
Proposed behavior
Store playlist metadata in the normal app database, but store secrets in platform secure storage:
Recommended platform mappings:
Why this matters
Storing IPTV credentials in a normal local database increases the chance that credentials are exposed through:
Secure storage does not make credentials impossible to extract on a compromised device, but it is the standard platform pattern for app secrets and is a better default than storing passwords directly with normal application data.
Suggested implementation direction
Introduce a small credential-store abstraction per active platform.
Example shape:
The database should only retain a stable reference, for example:
The provider clients should retrieve credentials through the credential store when making API or playback requests.
Migration approach
For existing users:
secret_ref.Migration should be idempotent so it can safely resume if interrupted.
Acceptance criteria
Non-goals
This issue does not need to change IPTV provider behavior or playback URL construction.
Xtream-style providers may still require credentials in API or playback URLs at request time. The goal here is to avoid storing those credentials in the normal app database and to reduce accidental exposure at rest.