e25240c2f3
The Jellyseerr API key was stored as plaintext in the Jellyfin service config. It is now a SecretField on the Jellyfin service, so it is encrypted at rest and rendered as a masked secret input (the generic config editor stops exposing it, and the secret editor picks it up automatically). Migration (idempotent, runs in ensure_defaults): - _migrate_jellyseerr_api_key_to_secret: for every Jellyfin service with a plaintext jellyseerr_api_key still in config, encrypt it ONCE into the secrets blob (direct UPDATE so existing encrypted secrets are preserved, not re-encrypted) and remove it from config. - _migrate_jellyseerr_into_jellyfin: standalone-jellyseerr absorption now stores the key as a secret, and decrypts the Jellyfin api_key before handing it to upsert_service (fixes a pre-existing double-encrypt on that rare path). The stats provider already reads jellyseerr_api_key from secrets-or-config, so it works before, during, and after the migration. Tests: absorbed-key lands in secrets (and existing api_key isn't corrupted); new plaintext-config -> secret migration + idempotency. 401/401 backend pass.
915 B
915 B
backend/src/media_library_viewer_api/integrations (index)
dir: backend/src/media_library_viewer_api/integrations
role
Provides a pluggable integration layer for connecting to and monitoring external self-hosted services (e.g., Jellyfin, Prometheus, qBittorrent, Nextcloud) with unified config schemas, connection testing, and widget definitions.
parent
index: backend/src/media_library_viewer_api/.pi-map.index.md map: backend/src/media_library_viewer_api/.pi-map.md
children
files
- __init__.py
- alertmanager.py
- authentik.py
- backups.py
- base.py
- jellyfin.py
- nextcloud.py
- prometheus.py
- qbittorrent.py
- registry.py
- ssh_tasks.py
links
index: backend/src/media_library_viewer_api/integrations/.pi-map.index.md map: backend/src/media_library_viewer_api/integrations/.pi-map.md
workflows
- change integrations behavior read: __init__.py, alertmanager.py, authentik.py