fix(flutter): cover URLs send Bearer auth + audio handler diag logging

Two issues from on-device testing against prod HTTPS:

1. ServerImage was resolving cover URLs correctly
   (https://minstrel.fabledsword.com/api/albums/.../cover) but the server
   returned 401 because Image.network doesn't carry the session token
   automatically the way the browser sends cookies. Forwards the stored
   session token as an Authorization: Bearer header. No-op when no token
   is present.

2. The "Cleartext HTTP traffic to 127.0.0.1" audio error reproduced even
   after the previous defensive check landed, which means the URL handed
   to ExoPlayer has a valid scheme+host (just the wrong host). The check
   only catches scheme-less URLs, so it didn't fire. Added debugPrint
   logging at configure() and setQueueFromTracks() time to show the
   actual baseUrl + per-track resolved URL on the next reproduction.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-08 23:15:56 -04:00
parent 088e8f4bf8
commit 83df3773ae
2 changed files with 16 additions and 1 deletions
@@ -31,7 +31,15 @@ class ServerImage extends ConsumerWidget {
final base = ref.watch(serverUrlProvider).value;
final resolved = _resolve(base, url);
if (resolved == null) return empty;
return Image.network(resolved, fit: fit);
// Cover endpoints are gated by RequireUser server-side. Image.network
// doesn't carry cookies/Bearer tokens automatically the way the
// browser's <img> tag does, so we forward the session token as a
// header. Without this, the server returns 401 and the image fails.
final token = ref.watch(sessionTokenProvider).value;
final headers = (token != null && token.isNotEmpty)
? {'Authorization': 'Bearer $token'}
: null;
return Image.network(resolved, fit: fit, headers: headers);
}
static String? _resolve(String? baseUrl, String url) {