Preserve SplashscreenLocation when updating branding config (#13756)

* add BrandingOptionsDto and add branding endpoints

* refactor new HttpGet Configuration Branding into existing API calls

* Add BrandingOptions to _ignoredConfigurations for openAPI

* rename BrandOptionsDto to BrandingOptionsDto
This commit is contained in:
KGT1 2025-04-01 01:46:01 +02:00 committed by GitHub
parent 940c4e8ba8
commit 14b785d188
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 62 additions and 10 deletions

View File

@ -29,9 +29,18 @@ public class BrandingController : BaseJellyfinApiController
/// <returns>An <see cref="OkResult"/> containing the branding configuration.</returns>
[HttpGet("Configuration")]
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<BrandingOptions> GetBrandingOptions()
public ActionResult<BrandingOptionsDto> GetBrandingOptions()
{
return _serverConfigurationManager.GetConfiguration<BrandingOptions>("branding");
var brandingOptions = _serverConfigurationManager.GetConfiguration<BrandingOptions>("branding");
var brandingOptionsDto = new BrandingOptionsDto
{
LoginDisclaimer = brandingOptions.LoginDisclaimer,
CustomCss = brandingOptions.CustomCss,
SplashscreenEnabled = brandingOptions.SplashscreenEnabled
};
return brandingOptionsDto;
}
/// <summary>

View File

@ -9,6 +9,7 @@ using Jellyfin.Extensions.Json;
using MediaBrowser.Common.Api;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Branding;
using MediaBrowser.Model.Configuration;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
@ -119,6 +120,30 @@ public class ConfigurationController : BaseJellyfinApiController
return new MetadataOptions();
}
/// <summary>
/// Updates branding configuration.
/// </summary>
/// <param name="configuration">Branding configuration.</param>
/// <response code="204">Branding configuration updated.</response>
/// <returns>Update status.</returns>
[HttpPost("Configuration/Branding")]
[Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult UpdateBrandingConfiguration([FromBody, Required] BrandingOptionsDto configuration)
{
// Get the current branding configuration to preserve SplashscreenLocation
var currentBranding = (BrandingOptions)_configurationManager.GetConfiguration("branding");
// Update only the properties from BrandingOptionsDto
currentBranding.LoginDisclaimer = configuration.LoginDisclaimer;
currentBranding.CustomCss = configuration.CustomCss;
currentBranding.SplashscreenEnabled = configuration.SplashscreenEnabled;
_configurationManager.SaveConfiguration("branding", currentBranding);
return NoContent();
}
/// <summary>
/// Updates the path to the media encoder.
/// </summary>

View File

@ -25,7 +25,7 @@ namespace Jellyfin.Server.Filters
public class AdditionalModelFilter : IDocumentFilter
{
// Array of options that should not be visible in the api spec.
private static readonly Type[] _ignoredConfigurations = { typeof(MigrationOptions) };
private static readonly Type[] _ignoredConfigurations = { typeof(MigrationOptions), typeof(MediaBrowser.Model.Branding.BrandingOptions) };
private readonly IServerConfigurationManager _serverConfigurationManager;
/// <summary>

View File

@ -1,5 +1,3 @@
using System.Text.Json.Serialization;
namespace MediaBrowser.Model.Branding;
/// <summary>
@ -27,10 +25,5 @@ public class BrandingOptions
/// <summary>
/// Gets or sets the splashscreen location on disk.
/// </summary>
/// <remarks>
/// Not served via the API.
/// Only used to save the custom uploaded user splashscreen in the configuration file.
/// </remarks>
[JsonIgnore]
public string? SplashscreenLocation { get; set; }
}

View File

@ -0,0 +1,25 @@
namespace MediaBrowser.Model.Branding;
/// <summary>
/// The branding options DTO for API use.
/// This DTO excludes SplashscreenLocation to prevent it from being updated via API.
/// </summary>
public class BrandingOptionsDto
{
/// <summary>
/// Gets or sets the login disclaimer.
/// </summary>
/// <value>The login disclaimer.</value>
public string? LoginDisclaimer { get; set; }
/// <summary>
/// Gets or sets the custom CSS.
/// </summary>
/// <value>The custom CSS.</value>
public string? CustomCss { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to enable the splashscreen.
/// </summary>
public bool SplashscreenEnabled { get; set; } = false;
}