diff --git a/allstarr.Tests/JellyfinProxyServiceTests.cs b/allstarr.Tests/JellyfinProxyServiceTests.cs index 6d268db..088581f 100644 --- a/allstarr.Tests/JellyfinProxyServiceTests.cs +++ b/allstarr.Tests/JellyfinProxyServiceTests.cs @@ -85,7 +85,7 @@ public class JellyfinProxyServiceTests } [Fact] - public async Task GetJsonAsync_IncludesAuthHeader() + public async Task GetJsonAsync_WithoutClientHeaders_SendsNoAuth() { // Arrange HttpRequestMessage? captured = null; @@ -102,13 +102,10 @@ public class JellyfinProxyServiceTests // Act await _service.GetJsonAsync("Items"); - // Assert + // Assert - Should NOT include auth when no client headers provided Assert.NotNull(captured); - Assert.True(captured!.Headers.Contains("Authorization")); - var authHeader = captured.Headers.GetValues("Authorization").First(); - Assert.Contains("MediaBrowser", authHeader); - Assert.Contains(_settings.ApiKey!, authHeader); - Assert.Contains(_settings.ClientName!, authHeader); + Assert.False(captured!.Headers.Contains("Authorization")); + Assert.False(captured.Headers.Contains("X-Emby-Authorization")); } [Fact] diff --git a/allstarr/Services/Jellyfin/JellyfinProxyService.cs b/allstarr/Services/Jellyfin/JellyfinProxyService.cs index 308dfd3..b21554c 100644 --- a/allstarr/Services/Jellyfin/JellyfinProxyService.cs +++ b/allstarr/Services/Jellyfin/JellyfinProxyService.cs @@ -205,18 +205,11 @@ public class JellyfinProxyService _logger.LogWarning("✗ No client headers provided for {Url}", url); } - // Use API key if no valid client auth was found + // DO NOT use server API key as fallback - let Jellyfin handle unauthenticated requests + // If client doesn't provide auth, they get what they deserve (401 from Jellyfin) if (!authHeaderAdded) { - if (!string.IsNullOrEmpty(_settings.ApiKey)) - { - request.Headers.Add("Authorization", GetAuthorizationHeader()); - _logger.LogInformation("→ Using API key for {Url}", url); - } - else - { - _logger.LogWarning("✗ No authentication available for {Url} - request will fail", url); - } + _logger.LogInformation("No client auth provided for {Url} - forwarding without auth", url); } request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); @@ -333,16 +326,12 @@ public class JellyfinProxyService } } - // For non-auth requests without headers, use API key - // For auth requests, client MUST provide their own client info - if (!authHeaderAdded && !endpoint.Contains("Authenticate", StringComparison.OrdinalIgnoreCase)) + // DO NOT use server credentials as fallback + // Exception: For auth endpoints, client provides their own credentials in the body + // For all other endpoints, if client doesn't provide auth, let Jellyfin reject it + if (!authHeaderAdded) { - var clientAuthHeader = $"MediaBrowser Client=\"{_settings.ClientName}\", " + - $"Device=\"{_settings.DeviceName}\", " + - $"DeviceId=\"{_settings.DeviceId}\", " + - $"Version=\"{_settings.ClientVersion}\""; - request.Headers.TryAddWithoutValidation("X-Emby-Authorization", clientAuthHeader); - _logger.LogDebug("Using server API key for non-auth request"); + _logger.LogInformation("No client auth provided for POST {Url} - forwarding without auth", url); } request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));