Skip to content

Store IPTV credentials in platform secure storage instead of app database #100

Description

@dwizzle204

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:

  1. On app startup, detect playlists with plaintext credentials in the existing database.
  2. Write those credentials to platform secure storage.
  3. Update the playlist row with a secret_ref.
  4. Remove or null the plaintext password fields from the app database.
  5. Verify the migrated credential can be loaded successfully.
  6. 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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions