mirror of
https://github.com/SoPat712/allstarr.git
synced 2026-02-09 23:55:10 -05:00
websocket 3
This commit is contained in:
@@ -1777,15 +1777,30 @@ public class JellyfinController : ControllerBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure session capabilities are posted to Jellyfin (if not already done)
|
// Ensure session capabilities are posted to Jellyfin (if not already done)
|
||||||
|
// Jellyfin automatically creates a session when the client authenticates, but we need to
|
||||||
|
// post capabilities so the session shows up in the dashboard with proper device info
|
||||||
if (!string.IsNullOrEmpty(deviceId))
|
if (!string.IsNullOrEmpty(deviceId))
|
||||||
{
|
{
|
||||||
_logger.LogInformation("🔧 Ensuring session exists for device: {DeviceId} ({Client} {Version})", deviceId, client, version);
|
_logger.LogInformation("🔧 Ensuring session exists for device: {DeviceId} ({Client} {Version})", deviceId, client, version);
|
||||||
|
|
||||||
// Post capabilities to ensure session is created
|
// Post capabilities - Jellyfin will match this to the authenticated session by device ID
|
||||||
var capabilitiesEndpoint = $"Sessions/Capabilities?playableMediaTypes=Audio&supportedCommands=&supportsMediaControl=false&supportsPersistentIdentifier=true";
|
// The query parameters tell Jellyfin what this device can do
|
||||||
|
var capabilitiesEndpoint = $"Sessions/Capabilities/Full";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var (capResult, capStatus) = await _proxyService.PostJsonAsync(capabilitiesEndpoint, "{}", Request.Headers);
|
// Send full capabilities as JSON body (more reliable than query params)
|
||||||
|
var capabilities = new
|
||||||
|
{
|
||||||
|
PlayableMediaTypes = new[] { "Audio" },
|
||||||
|
SupportedCommands = Array.Empty<string>(),
|
||||||
|
SupportsMediaControl = false,
|
||||||
|
SupportsPersistentIdentifier = true,
|
||||||
|
SupportsSync = false,
|
||||||
|
DeviceProfile = (object?)null // Let Jellyfin use defaults
|
||||||
|
};
|
||||||
|
|
||||||
|
var capabilitiesJson = JsonSerializer.Serialize(capabilities);
|
||||||
|
var (capResult, capStatus) = await _proxyService.PostJsonAsync(capabilitiesEndpoint, capabilitiesJson, Request.Headers);
|
||||||
_logger.LogInformation("✓ Session capabilities posted ({StatusCode})", capStatus);
|
_logger.LogInformation("✓ Session capabilities posted ({StatusCode})", capStatus);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -1992,21 +2007,29 @@ public class JellyfinController : ControllerBase
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Catch-all for any other session-related requests.
|
/// Catch-all for any other session-related requests.
|
||||||
|
/// <summary>
|
||||||
|
/// Catch-all proxy for any other session-related endpoints we haven't explicitly implemented.
|
||||||
/// This ensures all session management calls get proxied to Jellyfin.
|
/// This ensures all session management calls get proxied to Jellyfin.
|
||||||
|
/// Examples: GET /Sessions, POST /Sessions/Logout, etc.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[HttpGet("Sessions")]
|
||||||
|
[HttpPost("Sessions")]
|
||||||
[HttpGet("Sessions/{**path}")]
|
[HttpGet("Sessions/{**path}")]
|
||||||
[HttpPost("Sessions/{**path}")]
|
[HttpPost("Sessions/{**path}")]
|
||||||
[HttpPut("Sessions/{**path}")]
|
[HttpPut("Sessions/{**path}")]
|
||||||
[HttpDelete("Sessions/{**path}")]
|
[HttpDelete("Sessions/{**path}")]
|
||||||
public async Task<IActionResult> ProxySessionRequest(string path)
|
public async Task<IActionResult> ProxySessionRequest(string? path = null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var method = Request.Method;
|
var method = Request.Method;
|
||||||
var queryString = Request.QueryString.HasValue ? Request.QueryString.Value : "";
|
var queryString = Request.QueryString.HasValue ? Request.QueryString.Value : "";
|
||||||
var endpoint = $"Sessions/{path}{queryString}";
|
var endpoint = string.IsNullOrEmpty(path) ? $"Sessions{queryString}" : $"Sessions/{path}{queryString}";
|
||||||
|
|
||||||
_logger.LogInformation("🔄 Proxying session request: {Method} {Endpoint}", method, endpoint);
|
_logger.LogInformation("🔄 Proxying session request: {Method} {Endpoint}", method, endpoint);
|
||||||
|
_logger.LogDebug("Session proxy headers: {Headers}",
|
||||||
|
string.Join(", ", Request.Headers.Where(h => h.Key.Contains("Auth", StringComparison.OrdinalIgnoreCase))
|
||||||
|
.Select(h => $"{h.Key}={h.Value}")));
|
||||||
|
|
||||||
// Read body if present
|
// Read body if present
|
||||||
string body = "{}";
|
string body = "{}";
|
||||||
@@ -2018,6 +2041,7 @@ public class JellyfinController : ControllerBase
|
|||||||
body = await reader.ReadToEndAsync();
|
body = await reader.ReadToEndAsync();
|
||||||
}
|
}
|
||||||
Request.Body.Position = 0;
|
Request.Body.Position = 0;
|
||||||
|
_logger.LogDebug("Session proxy body: {Body}", body);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward to Jellyfin
|
// Forward to Jellyfin
|
||||||
@@ -2032,14 +2056,16 @@ public class JellyfinController : ControllerBase
|
|||||||
|
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
|
_logger.LogInformation("✓ Session request proxied successfully ({StatusCode})", statusCode);
|
||||||
return new JsonResult(result.RootElement.Clone());
|
return new JsonResult(result.RootElement.Clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_logger.LogInformation("✓ Session request proxied ({StatusCode}, no body)", statusCode);
|
||||||
return StatusCode(statusCode);
|
return StatusCode(statusCode);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Failed to proxy session request");
|
_logger.LogError(ex, "Failed to proxy session request: {Path}", path);
|
||||||
return StatusCode(500);
|
return StatusCode(500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user