From da8cb29e08dbcaaa89e0a94cd047ea35923d5b95 Mon Sep 17 00:00:00 2001 From: Josh Patra Date: Sat, 7 Feb 2026 11:45:16 -0500 Subject: [PATCH] refactor: make authentication truly transparent proxy - Pass through ALL Jellyfin responses (success and error) without modification - Move session capabilities posting to background task (don't block auth response) - Remove generic error fallbacks - always return Jellyfin's actual response - Simplify logic: if Jellyfin returns a response, pass it through; if not, return status code only --- allstarr/Controllers/JellyfinController.cs | 91 +++++++++++----------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/allstarr/Controllers/JellyfinController.cs b/allstarr/Controllers/JellyfinController.cs index 276a118..af57b0d 100644 --- a/allstarr/Controllers/JellyfinController.cs +++ b/allstarr/Controllers/JellyfinController.cs @@ -1830,61 +1830,64 @@ public class JellyfinController : ControllerBase _logger.LogInformation("Authentication request received"); // DO NOT log request body or detailed headers - contains password - // Forward to Jellyfin server with client headers + // Forward to Jellyfin server with client headers - completely transparent proxy var (result, statusCode) = await _proxyService.PostJsonAsync("Users/AuthenticateByName", body, Request.Headers); - if (statusCode != 200) + // Pass through Jellyfin's response exactly as-is (transparent proxy) + if (result != null) { - _logger.LogWarning("Authentication failed - status {StatusCode}", statusCode); + var responseJson = result.RootElement.GetRawText(); - // Pass through Jellyfin's error response if available - if (result != null) + // On successful auth, post session capabilities in background + if (statusCode == 200) { - return StatusCode(statusCode, result.RootElement.GetRawText()); - } - - // Fallback to generic error if no response body - if (statusCode == 401) - { - return Unauthorized(new { error = "Invalid username or password" }); - } - return StatusCode(statusCode, new { error = "Authentication failed" }); - } - - _logger.LogInformation("Authentication successful"); - - // Post session capabilities immediately after authentication - // This ensures Jellyfin creates a session that will show up in the dashboard - try - { - _logger.LogInformation("🔧 Posting session capabilities after authentication"); - var capabilities = new - { - PlayableMediaTypes = new[] { "Audio" }, - SupportedCommands = Array.Empty(), - SupportsMediaControl = false, - SupportsPersistentIdentifier = true, - SupportsSync = false - }; - - var capabilitiesJson = JsonSerializer.Serialize(capabilities); - var (capResult, capStatus) = await _proxyService.PostJsonAsync("Sessions/Capabilities/Full", capabilitiesJson, Request.Headers); - - if (capStatus == 204 || capStatus == 200) - { - _logger.LogInformation("✓ Session capabilities posted after auth ({StatusCode})", capStatus); + _logger.LogInformation("Authentication successful, posting session capabilities in background"); + + // Don't await - do this in background so we return auth response immediately + _ = Task.Run(async () => + { + try + { + _logger.LogInformation("🔧 Posting session capabilities after authentication"); + var capabilities = new + { + PlayableMediaTypes = new[] { "Audio" }, + SupportedCommands = Array.Empty(), + SupportsMediaControl = false, + SupportsPersistentIdentifier = true, + SupportsSync = false + }; + + var capabilitiesJson = JsonSerializer.Serialize(capabilities); + var (capResult, capStatus) = await _proxyService.PostJsonAsync("Sessions/Capabilities/Full", capabilitiesJson, Request.Headers); + + if (capStatus == 204 || capStatus == 200) + { + _logger.LogInformation("✓ Session capabilities posted after auth ({StatusCode})", capStatus); + } + else + { + _logger.LogWarning("⚠ Session capabilities returned {StatusCode} after auth", capStatus); + } + } + catch (Exception ex) + { + _logger.LogWarning(ex, "Failed to post session capabilities after auth"); + } + }); } else { - _logger.LogWarning("⚠ Session capabilities returned {StatusCode} after auth", capStatus); + _logger.LogWarning("Authentication failed - status {StatusCode}", statusCode); } - } - catch (Exception ex) - { - _logger.LogWarning(ex, "Failed to post session capabilities after auth, continuing anyway"); + + // Return Jellyfin's exact response + return Content(responseJson, "application/json"); } - return Content(result.RootElement.GetRawText(), "application/json"); + // No response body from Jellyfin - return status code only + _logger.LogWarning("Authentication request returned {StatusCode} with no response body", statusCode); + return StatusCode(statusCode); } catch (Exception ex) {