From 94b3b877856cb55d88b23f583fc7ac822412ef5d Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Tue, 2 Jun 2026 21:47:53 -0400 Subject: [PATCH] =?UTF-8?q?fix(android):=20interceptor=20order=20=E2=80=94?= =?UTF-8?q?=20auth=20before=20baseUrl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drift #568/#569 scoped AuthCookieInterceptor to PLACEHOLDER_HOST so the shared OkHttp client wouldn't leak the session cookie to external image fetches (Coil → musicbrainz, coverartarchive, Lidarr). The fix was correct but assumed AuthCookieInterceptor would see the original placeholder.invalid URL — production NetworkModule had BaseUrlInterceptor running FIRST, so by the time auth's intercept() ran the host was already rewritten to the real Minstrel server and the placeholder check failed on every request. Symptom on v2026.06.02: fresh install login appears to succeed but no cookie is captured from Set-Cookie and no cookie is attached to subsequent requests, so the user stays at the Welcome screen. AuthCookieInterceptorTest already chains the interceptors in the correct order, which is why the regression went undetected — only production was wrong. Fix: swap to (auth, baseUrl, logging). Auth now sees placeholder.invalid, attaches/captures the cookie, then BaseUrl rewrites the host for transport. --- .../fabledsword/minstrel/api/NetworkModule.kt | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/android/app/src/main/java/com/fabledsword/minstrel/api/NetworkModule.kt b/android/app/src/main/java/com/fabledsword/minstrel/api/NetworkModule.kt index 9f68df80..040b203b 100644 --- a/android/app/src/main/java/com/fabledsword/minstrel/api/NetworkModule.kt +++ b/android/app/src/main/java/com/fabledsword/minstrel/api/NetworkModule.kt @@ -48,11 +48,20 @@ object NetworkModule { logging: HttpLoggingInterceptor, ): OkHttpClient = OkHttpClient.Builder() - // BaseUrlInterceptor first — it rewrites scheme/host/port - // to match the live AuthStore.baseUrl on every request. - // Auth then sees the final URL. - .addInterceptor(baseUrl) + // AuthCookieInterceptor MUST run before BaseUrlInterceptor. + // Both scope on `host == PLACEHOLDER_HOST` to distinguish + // Minstrel-server requests from external image fetches + // (drift #568 / #569). If BaseUrlInterceptor runs first it + // rewrites the host to the real server before auth sees the + // request, auth's placeholder check fails, and the session + // cookie is neither attached on outgoing requests nor + // captured from Set-Cookie on login — fresh installs get + // stuck at the Welcome screen. Auth first means it sees + // placeholder.invalid, attaches/captures correctly, then + // BaseUrlInterceptor retargets to the live AuthStore host + // for transport. .addInterceptor(auth) + .addInterceptor(baseUrl) .addInterceptor(logging) .connectTimeout(CONNECT_TIMEOUT_SECONDS, TimeUnit.SECONDS) .readTimeout(READ_TIMEOUT_SECONDS, TimeUnit.SECONDS)