From 4be476ec5312387f87134915d0fd132b2ad5fa3f Mon Sep 17 00:00:00 2001
From: ConfusedPolarBear <33811686+ConfusedPolarBear@users.noreply.github.com>
Date: Thu, 18 Jun 2020 01:29:47 -0500
Subject: Move all settings into the main server configuration
Decreased the timeout from 30 minutes to 5.
Public lookup values have been replaced with the short code.
---
MediaBrowser.Model/Configuration/ServerConfiguration.cs | 6 ++++++
1 file changed, 6 insertions(+)
(limited to 'MediaBrowser.Model/Configuration/ServerConfiguration.cs')
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index afbe02dd3..76b290606 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -76,6 +76,11 @@ namespace MediaBrowser.Model.Configuration
/// true if this instance is port authorized; otherwise, false.
public bool IsPortAuthorized { get; set; }
+ ///
+ /// Gets or sets if quick connect is available for use on this server.
+ ///
+ public bool QuickConnectAvailable { get; set; }
+
public bool AutoRunWebApp { get; set; }
public bool EnableRemoteAccess { get; set; }
@@ -281,6 +286,7 @@ namespace MediaBrowser.Model.Configuration
AutoRunWebApp = true;
EnableRemoteAccess = true;
+ QuickConnectAvailable = false;
EnableUPnP = false;
MinResumePct = 5;
--
cgit v1.2.3
From 3c0484cc9730c06892b996d0b884a05ecada07af Mon Sep 17 00:00:00 2001
From: crobibero
Date: Sun, 30 Aug 2020 09:32:14 -0600
Subject: Allow for dynamic cors response
---
.../Extensions/ApiServiceCollectionExtensions.cs | 8 ++-
.../Middleware/DynamicCorsMiddleware.cs | 68 ++++++++++++++++++++++
Jellyfin.Server/Models/ServerCorsPolicy.cs | 43 +++++++++-----
Jellyfin.Server/Startup.cs | 8 ++-
.../Configuration/ServerConfiguration.cs | 6 ++
5 files changed, 115 insertions(+), 18 deletions(-)
create mode 100644 Jellyfin.Server/Middleware/DynamicCorsMiddleware.cs
(limited to 'MediaBrowser.Model/Configuration/ServerConfiguration.cs')
diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
index 0fd599cfc..b2f861542 100644
--- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
+++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
@@ -135,13 +135,17 @@ namespace Jellyfin.Server.Extensions
///
/// The service collection.
/// The base url for the API.
+ /// The configured cors hosts.
/// The MVC builder.
- public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, string baseUrl)
+ public static IMvcBuilder AddJellyfinApi(
+ this IServiceCollection serviceCollection,
+ string baseUrl,
+ string[] corsHosts)
{
return serviceCollection
.AddCors(options =>
{
- options.AddPolicy(ServerCorsPolicy.DefaultPolicyName, ServerCorsPolicy.DefaultPolicy);
+ options.AddPolicy(ServerCorsPolicy.DefaultPolicyName, new ServerCorsPolicy(corsHosts).Policy);
})
.Configure(options =>
{
diff --git a/Jellyfin.Server/Middleware/DynamicCorsMiddleware.cs b/Jellyfin.Server/Middleware/DynamicCorsMiddleware.cs
new file mode 100644
index 000000000..4fad898a7
--- /dev/null
+++ b/Jellyfin.Server/Middleware/DynamicCorsMiddleware.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Cors.Infrastructure;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Logging;
+using Microsoft.Net.Http.Headers;
+
+namespace Jellyfin.Server.Middleware
+{
+ ///
+ /// Dynamic cors middleware.
+ ///
+ public class DynamicCorsMiddleware
+ {
+ private readonly RequestDelegate _next;
+ private readonly ILogger _logger;
+ private readonly CorsMiddleware _corsMiddleware;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Next request delegate.
+ /// Instance of the interface.
+ /// Instance of the interface.
+ /// The cors policy name.
+ public DynamicCorsMiddleware(
+ RequestDelegate next,
+ ICorsService corsService,
+ ILoggerFactory loggerFactory,
+ string policyName)
+ {
+ _corsMiddleware = new CorsMiddleware(next, corsService, loggerFactory, policyName);
+ _next = next;
+ _logger = loggerFactory.CreateLogger();
+ }
+
+ ///
+ /// Invoke request.
+ ///
+ /// Request context.
+ /// Instance of the interface.
+ /// Task.
+ ///
+ public async Task Invoke(HttpContext context, ICorsPolicyProvider corsPolicyProvider)
+ {
+ // Only execute if is preflight request.
+ if (string.Equals(context.Request.Method, CorsConstants.PreflightHttpMethod, StringComparison.OrdinalIgnoreCase))
+ {
+ // Invoke original cors middleware.
+ await _corsMiddleware.Invoke(context, corsPolicyProvider).ConfigureAwait(false);
+ if (context.Response.Headers.TryGetValue(HeaderNames.AccessControlAllowOrigin, out var headerValue)
+ && string.Equals(headerValue, "*", StringComparison.Ordinal))
+ {
+ context.Response.Headers[HeaderNames.AccessControlAllowOrigin] = context.Request.Host.Value;
+ _logger.LogDebug("Overwriting CORS response header: {HeaderName}: {HeaderValue}", HeaderNames.AccessControlAllowOrigin, context.Request.Host.Value);
+
+ if (!context.Response.Headers.ContainsKey(HeaderNames.AccessControlAllowCredentials))
+ {
+ context.Response.Headers[HeaderNames.AccessControlAllowCredentials] = "true";
+ }
+ }
+ }
+
+ // Call the next delegate/middleware in the pipeline
+ await this._next(context).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/Jellyfin.Server/Models/ServerCorsPolicy.cs b/Jellyfin.Server/Models/ServerCorsPolicy.cs
index ae010c042..3a45db3b4 100644
--- a/Jellyfin.Server/Models/ServerCorsPolicy.cs
+++ b/Jellyfin.Server/Models/ServerCorsPolicy.cs
@@ -1,30 +1,47 @@
-using Microsoft.AspNetCore.Cors.Infrastructure;
+using System;
+using Microsoft.AspNetCore.Cors.Infrastructure;
namespace Jellyfin.Server.Models
{
///
/// Server Cors Policy.
///
- public static class ServerCorsPolicy
+ public class ServerCorsPolicy
{
///
/// Default policy name.
///
- public const string DefaultPolicyName = "DefaultCorsPolicy";
+ public const string DefaultPolicyName = nameof(ServerCorsPolicy);
///
- /// Default Policy. Allow Everything.
+ /// Initializes a new instance of the class.
///
- public static readonly CorsPolicy DefaultPolicy = new CorsPolicy
+ /// The configured cors hosts.
+ public ServerCorsPolicy(string[] corsHosts)
{
- // Allow any origin
- Origins = { "*" },
+ var builder = new CorsPolicyBuilder()
+ .AllowAnyMethod()
+ .AllowAnyHeader();
- // Allow any method
- Methods = { "*" },
+ // No hosts configured or only default configured.
+ if (corsHosts.Length == 0
+ || (corsHosts.Length == 1
+ && string.Equals(corsHosts[0], "*", StringComparison.Ordinal)))
+ {
+ builder.AllowAnyOrigin();
+ }
+ else
+ {
+ builder.WithOrigins(corsHosts)
+ .AllowCredentials();
+ }
- // Allow any header
- Headers = { "*" }
- };
+ Policy = builder.Build();
+ }
+
+ ///
+ /// Gets the cors policy.
+ ///
+ public CorsPolicy Policy { get; }
}
-}
\ No newline at end of file
+}
diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs
index d0dd183c6..76f5e69ce 100644
--- a/Jellyfin.Server/Startup.cs
+++ b/Jellyfin.Server/Startup.cs
@@ -38,7 +38,9 @@ namespace Jellyfin.Server
{
services.AddResponseCompression();
services.AddHttpContextAccessor();
- services.AddJellyfinApi(_serverConfigurationManager.Configuration.BaseUrl.TrimStart('/'));
+ services.AddJellyfinApi(
+ _serverConfigurationManager.Configuration.BaseUrl.TrimStart('/'),
+ _serverConfigurationManager.Configuration.CorsHosts);
services.AddJellyfinApiSwagger();
@@ -78,11 +80,11 @@ namespace Jellyfin.Server
app.UseAuthentication();
app.UseJellyfinApiSwagger(_serverConfigurationManager);
app.UseRouting();
- app.UseCors(ServerCorsPolicy.DefaultPolicyName);
+ app.UseMiddleware(ServerCorsPolicy.DefaultPolicyName);
app.UseAuthorization();
if (_serverConfigurationManager.Configuration.EnableMetrics)
{
- // Must be registered after any middleware that could chagne HTTP response codes or the data will be bad
+ // Must be registered after any middleware that could change HTTP response codes or the data will be bad
app.UseHttpMetrics();
}
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index c66091f9d..a743277d7 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -264,6 +264,11 @@ namespace MediaBrowser.Model.Configuration
///
public long SlowResponseThresholdMs { get; set; }
+ ///
+ /// Gets or sets the cors hosts.
+ ///
+ public string[] CorsHosts { get; set; }
+
///
/// Initializes a new instance of the class.
///
@@ -372,6 +377,7 @@ namespace MediaBrowser.Model.Configuration
EnableSlowResponseWarning = true;
SlowResponseThresholdMs = 500;
+ CorsHosts = new[] { "*" };
}
}
--
cgit v1.2.3
From 1feee6f95e00cf579ab16c7ca004947534545d9b Mon Sep 17 00:00:00 2001
From: crobibero
Date: Wed, 2 Sep 2020 08:03:15 -0600
Subject: Properly host static files and set base url
---
Jellyfin.Api/Controllers/DashboardController.cs | 102 +--------------------
.../Extensions/ApiApplicationBuilderExtensions.cs | 21 +----
.../Extensions/ApiServiceCollectionExtensions.cs | 6 +-
Jellyfin.Server/Program.cs | 2 +-
Jellyfin.Server/Startup.cs | 21 ++++-
.../Configuration/IApplicationPaths.cs | 5 +-
.../Configuration/ServerConfiguration.cs | 6 --
7 files changed, 27 insertions(+), 136 deletions(-)
(limited to 'MediaBrowser.Model/Configuration/ServerConfiguration.cs')
diff --git a/Jellyfin.Api/Controllers/DashboardController.cs b/Jellyfin.Api/Controllers/DashboardController.cs
index 33abe3ccd..3f0fc2e91 100644
--- a/Jellyfin.Api/Controllers/DashboardController.cs
+++ b/Jellyfin.Api/Controllers/DashboardController.cs
@@ -15,6 +15,7 @@ using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
+using Microsoft.Net.Http.Headers;
namespace Jellyfin.Api.Controllers
{
@@ -26,38 +27,20 @@ namespace Jellyfin.Api.Controllers
{
private readonly ILogger _logger;
private readonly IServerApplicationHost _appHost;
- private readonly IConfiguration _appConfig;
- private readonly IServerConfigurationManager _serverConfigurationManager;
- private readonly IResourceFileManager _resourceFileManager;
///
/// Initializes a new instance of the class.
///
/// Instance of interface.
/// Instance of interface.
- /// Instance of interface.
- /// Instance of interface.
- /// Instance of interface.
public DashboardController(
ILogger logger,
- IServerApplicationHost appHost,
- IConfiguration appConfig,
- IResourceFileManager resourceFileManager,
- IServerConfigurationManager serverConfigurationManager)
+ IServerApplicationHost appHost)
{
_logger = logger;
_appHost = appHost;
- _appConfig = appConfig;
- _resourceFileManager = resourceFileManager;
- _serverConfigurationManager = serverConfigurationManager;
}
- ///
- /// Gets the path of the directory containing the static web interface content, or null if the server is not
- /// hosting the web client.
- ///
- private string? WebClientUiPath => GetWebClientUiPath(_appConfig, _serverConfigurationManager);
-
///
/// Gets the configuration pages.
///
@@ -169,87 +152,6 @@ namespace Jellyfin.Api.Controllers
return NotFound();
}
- ///
- /// Gets the robots.txt.
- ///
- /// Robots.txt returned.
- /// The robots.txt.
- [HttpGet("robots.txt")]
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ApiExplorerSettings(IgnoreApi = true)]
- public ActionResult GetRobotsTxt()
- {
- return GetWebClientResource("robots.txt");
- }
-
- ///
- /// Gets a resource from the web client.
- ///
- /// The resource name.
- /// Web client returned.
- /// Server does not host a web client.
- /// The resource.
- [HttpGet("web/{*resourceName}")]
- [ApiExplorerSettings(IgnoreApi = true)]
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status404NotFound)]
- public ActionResult GetWebClientResource([FromRoute] string resourceName)
- {
- if (!_appConfig.HostWebClient() || WebClientUiPath == null)
- {
- return NotFound("Server does not host a web client.");
- }
-
- var path = resourceName;
- var basePath = WebClientUiPath;
-
- var requestPathAndQuery = Request.GetEncodedPathAndQuery();
- // Bounce them to the startup wizard if it hasn't been completed yet
- if (!_serverConfigurationManager.Configuration.IsStartupWizardCompleted
- && !requestPathAndQuery.Contains("wizard", StringComparison.OrdinalIgnoreCase)
- && requestPathAndQuery.Contains("index", StringComparison.OrdinalIgnoreCase))
- {
- return Redirect("index.html?start=wizard#!/wizardstart.html");
- }
-
- var stream = new FileStream(_resourceFileManager.GetResourcePath(basePath, path), FileMode.Open, FileAccess.Read);
- return File(stream, MimeTypes.GetMimeType(path));
- }
-
- ///
- /// Gets the favicon.
- ///
- /// Favicon.ico returned.
- /// The favicon.
- [HttpGet("favicon.ico")]
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ApiExplorerSettings(IgnoreApi = true)]
- public ActionResult GetFavIcon()
- {
- return GetWebClientResource("favicon.ico");
- }
-
- ///
- /// Gets the path of the directory containing the static web interface content.
- ///
- /// The app configuration.
- /// The server configuration manager.
- /// The directory path, or null if the server is not hosting the web client.
- public static string? GetWebClientUiPath(IConfiguration appConfig, IServerConfigurationManager serverConfigManager)
- {
- if (!appConfig.HostWebClient())
- {
- return null;
- }
-
- if (!string.IsNullOrEmpty(serverConfigManager.Configuration.DashboardSourcePath))
- {
- return serverConfigManager.Configuration.DashboardSourcePath;
- }
-
- return serverConfigManager.ApplicationPaths.WebPath;
- }
-
private IEnumerable GetConfigPages(IPlugin plugin)
{
return GetPluginPages(plugin).Select(i => new ConfigurationPageInfo(plugin, i.Item1));
diff --git a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs
index a1a68bcf0..e23de86d9 100644
--- a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs
+++ b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs
@@ -34,38 +34,23 @@ namespace Jellyfin.Server.Extensions
.UseSwagger(c =>
{
// Custom path requires {documentName}, SwaggerDoc documentName is 'api-docs'
- c.RouteTemplate = $"/{baseUrl}{{documentName}}/openapi.json";
+ c.RouteTemplate = "{documentName}/openapi.json";
c.PreSerializeFilters.Add((swagger, httpReq) =>
{
swagger.Servers = new List { new OpenApiServer { Url = $"{httpReq.Scheme}://{httpReq.Host.Value}{apiDocBaseUrl}" } };
-
- // BaseUrl is empty, ignore
- if (apiDocBaseUrl.Length != 0)
- {
- // Update all relative paths to remove baseUrl.
- var updatedPaths = new OpenApiPaths();
- foreach (var (key, value) in swagger.Paths)
- {
- var relativePath = key;
- relativePath = relativePath.Remove(0, apiDocBaseUrl.Length);
- updatedPaths.Add(relativePath, value);
- }
-
- swagger.Paths = updatedPaths;
- }
});
})
.UseSwaggerUI(c =>
{
c.DocumentTitle = "Jellyfin API";
c.SwaggerEndpoint($"/{baseUrl}api-docs/openapi.json", "Jellyfin API");
- c.RoutePrefix = $"{baseUrl}api-docs/swagger";
+ c.RoutePrefix = "api-docs/swagger";
})
.UseReDoc(c =>
{
c.DocumentTitle = "Jellyfin API";
c.SpecUrl($"/{baseUrl}api-docs/openapi.json");
- c.RoutePrefix = $"{baseUrl}api-docs/redoc";
+ c.RoutePrefix = "api-docs/redoc";
});
}
}
diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
index 0160a05f9..283c870fd 100644
--- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
+++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
@@ -135,10 +135,9 @@ namespace Jellyfin.Server.Extensions
/// Extension method for adding the jellyfin API to the service collection.
///
/// The service collection.
- /// The base url for the API.
- /// An IEnumberable containing all plugin assemblies with API controllers.
+ /// An IEnumerable containing all plugin assemblies with API controllers.
/// The MVC builder.
- public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, string baseUrl, IEnumerable pluginAssemblies)
+ public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, IEnumerable pluginAssemblies)
{
IMvcBuilder mvcBuilder = serviceCollection
.AddCors(options =>
@@ -151,7 +150,6 @@ namespace Jellyfin.Server.Extensions
})
.AddMvc(opts =>
{
- opts.UseGeneralRoutePrefix(baseUrl);
opts.OutputFormatters.Insert(0, new CamelCaseJsonProfileFormatter());
opts.OutputFormatters.Insert(0, new PascalCaseJsonProfileFormatter());
diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs
index 14cc5f4c2..223bb2558 100644
--- a/Jellyfin.Server/Program.cs
+++ b/Jellyfin.Server/Program.cs
@@ -169,7 +169,7 @@ namespace Jellyfin.Server
// If hosting the web client, validate the client content path
if (startupConfig.HostWebClient())
{
- string? webContentPath = DashboardController.GetWebClientUiPath(startupConfig, appHost.ServerConfigurationManager);
+ string? webContentPath = appHost.ServerConfigurationManager.ApplicationPaths.WebPath;
if (!Directory.Exists(webContentPath) || Directory.GetFiles(webContentPath).Length == 0)
{
throw new InvalidOperationException(
diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs
index cbc1c040c..73c00260e 100644
--- a/Jellyfin.Server/Startup.cs
+++ b/Jellyfin.Server/Startup.cs
@@ -9,9 +9,12 @@ using MediaBrowser.Common;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Extensions;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using Prometheus;
@@ -44,7 +47,7 @@ namespace Jellyfin.Server
{
services.AddResponseCompression();
services.AddHttpContextAccessor();
- services.AddJellyfinApi(_serverConfigurationManager.Configuration.BaseUrl.TrimStart('/'), _applicationHost.GetApiPluginAssemblies());
+ services.AddJellyfinApi(_applicationHost.GetApiPluginAssemblies());
services.AddJellyfinApiSwagger();
@@ -75,10 +78,12 @@ namespace Jellyfin.Server
/// The application builder.
/// The webhost environment.
/// The server application host.
+ /// The application config.
public void Configure(
IApplicationBuilder app,
IWebHostEnvironment env,
- IServerApplicationHost serverApplicationHost)
+ IServerApplicationHost serverApplicationHost,
+ IConfiguration appConfig)
{
if (env.IsDevelopment())
{
@@ -95,6 +100,16 @@ namespace Jellyfin.Server
// TODO app.UseMiddleware();
+ app.UsePathBase(_serverConfigurationManager.Configuration.BaseUrl);
+ if (appConfig.HostWebClient())
+ {
+ app.UseStaticFiles(new StaticFileOptions
+ {
+ FileProvider = new PhysicalFileProvider(_serverConfigurationManager.ApplicationPaths.WebPath),
+ RequestPath = "/web"
+ });
+ }
+
app.UseAuthentication();
app.UseJellyfinApiSwagger(_serverConfigurationManager);
app.UseRouting();
@@ -102,7 +117,7 @@ namespace Jellyfin.Server
app.UseAuthorization();
if (_serverConfigurationManager.Configuration.EnableMetrics)
{
- // Must be registered after any middleware that could chagne HTTP response codes or the data will be bad
+ // Must be registered after any middleware that could change HTTP response codes or the data will be bad
app.UseHttpMetrics();
}
diff --git a/MediaBrowser.Common/Configuration/IApplicationPaths.cs b/MediaBrowser.Common/Configuration/IApplicationPaths.cs
index 4cea61682..57c654667 100644
--- a/MediaBrowser.Common/Configuration/IApplicationPaths.cs
+++ b/MediaBrowser.Common/Configuration/IApplicationPaths.cs
@@ -1,5 +1,3 @@
-using MediaBrowser.Model.Configuration;
-
namespace MediaBrowser.Common.Configuration
{
///
@@ -17,8 +15,7 @@ namespace MediaBrowser.Common.Configuration
/// Gets the path to the web UI resources folder.
///
///
- /// This value is not relevant if the server is configured to not host any static web content. Additionally,
- /// the value for takes precedence over this one.
+ /// This value is not relevant if the server is configured to not host any static web content.
///
string WebPath { get; }
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index 33975bc1e..97748bd0c 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -166,12 +166,6 @@ namespace MediaBrowser.Model.Configuration
/// true if [enable dashboard response caching]; otherwise, false.
public bool EnableDashboardResponseCaching { get; set; }
- ///
- /// Gets or sets a custom path to serve the dashboard from.
- ///
- /// The dashboard source path, or null if the default path should be used.
- public string DashboardSourcePath { get; set; }
-
///
/// Gets or sets the image saving convention.
///
--
cgit v1.2.3
From 78cab77f819e8d8b283f95f2e48f635bcf66fea5 Mon Sep 17 00:00:00 2001
From: cvium
Date: Thu, 10 Sep 2020 11:05:46 +0200
Subject: Add Known Proxies to system configuration
---
.../Extensions/ApiServiceCollectionExtensions.cs | 13 +++++++++++--
Jellyfin.Server/Startup.cs | 3 ++-
MediaBrowser.Model/Configuration/ServerConfiguration.cs | 6 ++++++
3 files changed, 19 insertions(+), 3 deletions(-)
(limited to 'MediaBrowser.Model/Configuration/ServerConfiguration.cs')
diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
index 9319b573a..873e22819 100644
--- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
+++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Net;
using System.Reflection;
using Jellyfin.Api.Auth;
using Jellyfin.Api.Auth.DefaultAuthorizationPolicy;
@@ -17,7 +18,6 @@ using Jellyfin.Api.Constants;
using Jellyfin.Api.Controllers;
using Jellyfin.Server.Configuration;
using Jellyfin.Server.Formatters;
-using Jellyfin.Server.Middleware;
using MediaBrowser.Common.Json;
using MediaBrowser.Model.Entities;
using Microsoft.AspNetCore.Authentication;
@@ -28,6 +28,7 @@ using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
+using AuthenticationSchemes = Jellyfin.Api.Constants.AuthenticationSchemes;
namespace Jellyfin.Server.Extensions
{
@@ -136,8 +137,9 @@ namespace Jellyfin.Server.Extensions
///
/// The service collection.
/// An IEnumerable containing all plugin assemblies with API controllers.
+ /// A list of all known proxies to trust for X-Forwarded-For.
/// The MVC builder.
- public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, IEnumerable pluginAssemblies)
+ public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, IEnumerable pluginAssemblies, IReadOnlyList knownProxies)
{
IMvcBuilder mvcBuilder = serviceCollection
.AddCors()
@@ -145,6 +147,13 @@ namespace Jellyfin.Server.Extensions
.Configure(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
+ for (var i = 0; i < knownProxies.Count; i++)
+ {
+ if (IPAddress.TryParse(knownProxies[i], out var address))
+ {
+ options.KnownProxies.Add(address);
+ }
+ }
})
.AddMvc(opts =>
{
diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs
index 9e969c0c1..2f4620aa6 100644
--- a/Jellyfin.Server/Startup.cs
+++ b/Jellyfin.Server/Startup.cs
@@ -52,7 +52,7 @@ namespace Jellyfin.Server
{
options.HttpsPort = _serverApplicationHost.HttpsPort;
});
- services.AddJellyfinApi(_serverApplicationHost.GetApiPluginAssemblies());
+ services.AddJellyfinApi(_serverApplicationHost.GetApiPluginAssemblies(), _serverConfigurationManager.Configuration.KnownProxies);
services.AddJellyfinApiSwagger();
@@ -103,6 +103,7 @@ namespace Jellyfin.Server
mainApp.UseDeveloperExceptionPage();
}
+ mainApp.UseForwardedHeaders();
mainApp.UseMiddleware();
mainApp.UseMiddleware();
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index 68dc1cc83..48d1a7346 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -268,6 +268,11 @@ namespace MediaBrowser.Model.Configuration
///
public string[] CorsHosts { get; set; }
+ ///
+ /// Gets or sets the known proxies.
+ ///
+ public string[] KnownProxies { get; set; }
+
///
/// Initializes a new instance of the class.
///
@@ -378,6 +383,7 @@ namespace MediaBrowser.Model.Configuration
EnableSlowResponseWarning = true;
SlowResponseThresholdMs = 500;
CorsHosts = new[] { "*" };
+ KnownProxies = Array.Empty();
}
}
--
cgit v1.2.3
From 5cca8bffea339f1043d692f337ab002dbee3a03b Mon Sep 17 00:00:00 2001
From: spookbits <71300703+spooksbit@users.noreply.github.com>
Date: Wed, 16 Sep 2020 13:17:14 -0400
Subject: Removed browser auto-load functionality from the server. Added
profiles in launchSettings to start either the web client or the swagger API
page. Removed --noautorunwebapp as this is the default functionality.
---
CONTRIBUTORS.md | 1 +
.../Browser/BrowserLauncher.cs | 51 -------------
.../EntryPoints/StartupWizard.cs | 83 ----------------------
Emby.Server.Implementations/IStartupOptions.cs | 5 --
Jellyfin.Server/Jellyfin.Server.csproj | 2 +-
Jellyfin.Server/Properties/launchSettings.json | 8 ++-
Jellyfin.Server/StartupOptions.cs | 4 --
.../Configuration/ServerConfiguration.cs | 3 -
.../JellyfinApplicationFactory.cs | 3 +-
9 files changed, 10 insertions(+), 150 deletions(-)
delete mode 100644 Emby.Server.Implementations/Browser/BrowserLauncher.cs
delete mode 100644 Emby.Server.Implementations/EntryPoints/StartupWizard.cs
(limited to 'MediaBrowser.Model/Configuration/ServerConfiguration.cs')
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index f1fe65064..2ec147ba2 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -103,6 +103,7 @@
- [sl1288](https://github.com/sl1288)
- [sorinyo2004](https://github.com/sorinyo2004)
- [sparky8251](https://github.com/sparky8251)
+ - [spookbits](https://github.com/spookbits)
- [stanionascu](https://github.com/stanionascu)
- [stevehayles](https://github.com/stevehayles)
- [SuperSandro2000](https://github.com/SuperSandro2000)
diff --git a/Emby.Server.Implementations/Browser/BrowserLauncher.cs b/Emby.Server.Implementations/Browser/BrowserLauncher.cs
deleted file mode 100644
index f8108d1c2..000000000
--- a/Emby.Server.Implementations/Browser/BrowserLauncher.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using System;
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Configuration;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.Logging;
-
-namespace Emby.Server.Implementations.Browser
-{
- ///
- /// Assists in opening application URLs in an external browser.
- ///
- public static class BrowserLauncher
- {
- ///
- /// Opens the home page of the web client.
- ///
- /// The app host.
- public static void OpenWebApp(IServerApplicationHost appHost)
- {
- TryOpenUrl(appHost, "/web/index.html");
- }
-
- ///
- /// Opens the swagger API page.
- ///
- /// The app host.
- public static void OpenSwaggerPage(IServerApplicationHost appHost)
- {
- TryOpenUrl(appHost, "/api-docs/swagger");
- }
-
- ///
- /// Opens the specified URL in an external browser window. Any exceptions will be logged, but ignored.
- ///
- /// The application host.
- /// The URL to open, relative to the server base URL.
- private static void TryOpenUrl(IServerApplicationHost appHost, string relativeUrl)
- {
- try
- {
- string baseUrl = appHost.GetLocalApiUrl("localhost");
- appHost.LaunchUrl(baseUrl + relativeUrl);
- }
- catch (Exception ex)
- {
- var logger = appHost.Resolve>();
- logger?.LogError(ex, "Failed to open browser window with URL {URL}", relativeUrl);
- }
- }
- }
-}
diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs
deleted file mode 100644
index 2e738deeb..000000000
--- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using System.Threading.Tasks;
-using Emby.Server.Implementations.Browser;
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Extensions;
-using MediaBrowser.Controller.Plugins;
-using Microsoft.Extensions.Configuration;
-
-namespace Emby.Server.Implementations.EntryPoints
-{
- ///
- /// Class StartupWizard.
- ///
- public sealed class StartupWizard : IServerEntryPoint
- {
- private readonly IServerApplicationHost _appHost;
- private readonly IConfiguration _appConfig;
- private readonly IServerConfigurationManager _config;
- private readonly IStartupOptions _startupOptions;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The application host.
- /// The application configuration.
- /// The configuration manager.
- /// The application startup options.
- public StartupWizard(
- IServerApplicationHost appHost,
- IConfiguration appConfig,
- IServerConfigurationManager config,
- IStartupOptions startupOptions)
- {
- _appHost = appHost;
- _appConfig = appConfig;
- _config = config;
- _startupOptions = startupOptions;
- }
-
- ///
- public Task RunAsync()
- {
- Run();
- return Task.CompletedTask;
- }
-
- private void Run()
- {
- if (!_appHost.CanLaunchWebBrowser)
- {
- return;
- }
-
- // Always launch the startup wizard if possible when it has not been completed
- if (!_config.Configuration.IsStartupWizardCompleted && _appConfig.HostWebClient())
- {
- BrowserLauncher.OpenWebApp(_appHost);
- return;
- }
-
- // Do nothing if the web app is configured to not run automatically
- if (!_config.Configuration.AutoRunWebApp || _startupOptions.NoAutoRunWebApp)
- {
- return;
- }
-
- // Launch the swagger page if the web client is not hosted, otherwise open the web client
- if (_appConfig.HostWebClient())
- {
- BrowserLauncher.OpenWebApp(_appHost);
- }
- else
- {
- BrowserLauncher.OpenSwaggerPage(_appHost);
- }
- }
-
- ///
- public void Dispose()
- {
- }
- }
-}
diff --git a/Emby.Server.Implementations/IStartupOptions.cs b/Emby.Server.Implementations/IStartupOptions.cs
index e7e72c686..4bef59543 100644
--- a/Emby.Server.Implementations/IStartupOptions.cs
+++ b/Emby.Server.Implementations/IStartupOptions.cs
@@ -16,11 +16,6 @@ namespace Emby.Server.Implementations
///
bool IsService { get; }
- ///
- /// Gets the value of the --noautorunwebapp command line option.
- ///
- bool NoAutoRunWebApp { get; }
-
///
/// Gets the value of the --package-name command line option.
///
diff --git a/Jellyfin.Server/Jellyfin.Server.csproj b/Jellyfin.Server/Jellyfin.Server.csproj
index 0ac309a0b..b66314a8e 100644
--- a/Jellyfin.Server/Jellyfin.Server.csproj
+++ b/Jellyfin.Server/Jellyfin.Server.csproj
@@ -1,4 +1,4 @@
-
+
diff --git a/Jellyfin.Server/Properties/launchSettings.json b/Jellyfin.Server/Properties/launchSettings.json
index b6e2bcf97..ebdd0deda 100644
--- a/Jellyfin.Server/Properties/launchSettings.json
+++ b/Jellyfin.Server/Properties/launchSettings.json
@@ -2,14 +2,20 @@
"profiles": {
"Jellyfin.Server": {
"commandName": "Project",
+ "launchBrowser": true,
+ "launchUrl": "web",
+ "applicationUrl": "http://localhost:8096",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Jellyfin.Server (nowebclient)": {
"commandName": "Project",
+ "launchBrowser": true,
+ "launchUrl": "api-docs/swagger",
+ "applicationUrl": "http://localhost:8096",
"environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
+ "ASPNETCORE_ENVIRONMENT": "Development"
},
"commandLineArgs": "--nowebclient"
}
diff --git a/Jellyfin.Server/StartupOptions.cs b/Jellyfin.Server/StartupOptions.cs
index 41a1430d2..b63434092 100644
--- a/Jellyfin.Server/StartupOptions.cs
+++ b/Jellyfin.Server/StartupOptions.cs
@@ -63,10 +63,6 @@ namespace Jellyfin.Server
[Option("service", Required = false, HelpText = "Run as headless service.")]
public bool IsService { get; set; }
- ///
- [Option("noautorunwebapp", Required = false, HelpText = "Run headless if startup wizard is complete.")]
- public bool NoAutoRunWebApp { get; set; }
-
///
[Option("package-name", Required = false, HelpText = "Used when packaging Jellyfin (example, synology).")]
public string? PackageName { get; set; }
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index 48d1a7346..8b78ad842 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -83,8 +83,6 @@ namespace MediaBrowser.Model.Configuration
///
public bool QuickConnectAvailable { get; set; }
- public bool AutoRunWebApp { get; set; }
-
public bool EnableRemoteAccess { get; set; }
///
@@ -306,7 +304,6 @@ namespace MediaBrowser.Model.Configuration
DisableLiveTvChannelUserDataName = true;
EnableNewOmdbSupport = true;
- AutoRunWebApp = true;
EnableRemoteAccess = true;
QuickConnectAvailable = false;
diff --git a/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs b/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs
index 77f1640fa..bd3d35687 100644
--- a/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs
+++ b/tests/Jellyfin.Api.Tests/JellyfinApplicationFactory.cs
@@ -47,8 +47,7 @@ namespace Jellyfin.Api.Tests
// Specify the startup command line options
var commandLineOpts = new StartupOptions
{
- NoWebClient = true,
- NoAutoRunWebApp = true
+ NoWebClient = true
};
// Use a temporary directory for the application paths
--
cgit v1.2.3
From ceecc80bb3816ca41d470e3b537a1bf7b632e8e2 Mon Sep 17 00:00:00 2001
From: crobibero
Date: Sun, 1 Nov 2020 18:32:41 -0700
Subject: Allow configuration of ActivityLogRetention
---
.../ScheduledTasks/Tasks/CleanActivityLogTask.cs | 16 +++++++++++++---
MediaBrowser.Model/Configuration/ServerConfiguration.cs | 6 ++++++
2 files changed, 19 insertions(+), 3 deletions(-)
(limited to 'MediaBrowser.Model/Configuration/ServerConfiguration.cs')
diff --git a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanActivityLogTask.cs b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanActivityLogTask.cs
index 50bc091c8..4abbf784b 100644
--- a/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanActivityLogTask.cs
+++ b/Emby.Server.Implementations/ScheduledTasks/Tasks/CleanActivityLogTask.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Tasks;
@@ -16,18 +17,22 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
{
private readonly ILocalizationManager _localization;
private readonly IActivityManager _activityManager;
+ private readonly IServerConfigurationManager _serverConfigurationManager;
///
/// Initializes a new instance of the class.
///
/// Instance of the interface.
/// Instance of the interface.
+ /// Instance of the interface.
public CleanActivityLogTask(
ILocalizationManager localization,
- IActivityManager activityManager)
+ IActivityManager activityManager,
+ IServerConfigurationManager serverConfigurationManager)
{
_localization = localization;
_activityManager = activityManager;
+ _serverConfigurationManager = serverConfigurationManager;
}
///
@@ -54,8 +59,13 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
///
public Task Execute(CancellationToken cancellationToken, IProgress progress)
{
- // TODO allow configure
- var startDate = DateTime.UtcNow.AddDays(-30);
+ var retentionDays = _serverConfigurationManager.Configuration.ActivityLogRetentionDays;
+ if (!retentionDays.HasValue || retentionDays <= 0)
+ {
+ throw new Exception($"Activity Log Retention days must be at least 0. Currently: {retentionDays}");
+ }
+
+ var startDate = DateTime.UtcNow.AddDays(retentionDays.Value * -1);
return _activityManager.CleanAsync(startDate);
}
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index 8b78ad842..23a5201f7 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -271,6 +271,11 @@ namespace MediaBrowser.Model.Configuration
///
public string[] KnownProxies { get; set; }
+ ///
+ /// Gets or sets the number of days we should retain activity logs.
+ ///
+ public int? ActivityLogRetentionDays { get; set; }
+
///
/// Initializes a new instance of the class.
///
@@ -381,6 +386,7 @@ namespace MediaBrowser.Model.Configuration
SlowResponseThresholdMs = 500;
CorsHosts = new[] { "*" };
KnownProxies = Array.Empty();
+ ActivityLogRetentionDays = 30;
}
}
--
cgit v1.2.3