diff --git a/Jellyfin.Plugin.ShareLinks/Api/ShareLinksController.cs b/Jellyfin.Plugin.ShareLinks/Api/ShareLinksController.cs index 1f475bb..8249342 100644 --- a/Jellyfin.Plugin.ShareLinks/Api/ShareLinksController.cs +++ b/Jellyfin.Plugin.ShareLinks/Api/ShareLinksController.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Security.Claims; using System.Text; +using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Jellyfin.Plugin.ShareLinks.Configuration; @@ -13,6 +14,7 @@ using Jellyfin.Plugin.ShareLinks.Storage; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; @@ -315,18 +317,63 @@ public sealed class ShareLinksController : ControllerBase SetNoStoreHeaders(); if (string.IsNullOrWhiteSpace(token)) { - return NotFound(); + return LinkUnavailablePage(Request); } var html = await _redemptionService.RedeemAsync(token, Request, cancellationToken).ConfigureAwait(false); if (html is null) { - return NotFound(); + return LinkUnavailablePage(Request); } return Content(html, "text/html; charset=utf-8"); } + private static ContentResult LinkUnavailablePage(HttpRequest request) + { + var pathBase = request.PathBase.Value ?? string.Empty; + var redirectUrl = $"{pathBase}/web/"; + + var redirectUrlJson = JsonSerializer.Serialize(redirectUrl); + var redirectUrlHtml = System.Net.WebUtility.HtmlEncode(redirectUrl); + + var html = $$""" + + + + + + + Link unavailable + + + +
+
This share link is no longer valid.
+
Ce lien de partage n'est plus valide.
+
Taking you to the home page...
+

Open Jellyfin

+
+ + + +"""; + + return new ContentResult + { + StatusCode = StatusCodes.Status404NotFound, + ContentType = "text/html; charset=utf-8", + Content = html + }; + } + private static ShareLinkAdminRecordDto ToDto(ShareLinkRecord record) { return new ShareLinkAdminRecordDto diff --git a/Jellyfin.Plugin.ShareLinks/Configuration/PluginConfiguration.cs b/Jellyfin.Plugin.ShareLinks/Configuration/PluginConfiguration.cs index a3af8d0..f4839ed 100644 --- a/Jellyfin.Plugin.ShareLinks/Configuration/PluginConfiguration.cs +++ b/Jellyfin.Plugin.ShareLinks/Configuration/PluginConfiguration.cs @@ -45,9 +45,7 @@ public class PluginConfiguration : BasePluginConfiguration /// /// Gets or sets a comma-separated list of CSS selectors that are hidden from guest /// sessions in the web client. Used to suppress other plugins' injected UI (search - /// bars, floating buttons) so a guest only sees the shared title. The default value - /// hides the elements of a plugin that injects its own floating button and panel - /// into the web client; edit or clear it to match whatever else you run. + /// bars, floating buttons) so a guest only sees the shared title. Empty by default. /// - public string GuestHiddenSelectors { get; set; } = ".ais-fab,.ais-overlay,#ais-styles"; + public string GuestHiddenSelectors { get; set; } = string.Empty; } diff --git a/Jellyfin.Plugin.ShareLinks/Web/configPage.html b/Jellyfin.Plugin.ShareLinks/Web/configPage.html index 05bd89d..2b5a11d 100644 --- a/Jellyfin.Plugin.ShareLinks/Web/configPage.html +++ b/Jellyfin.Plugin.ShareLinks/Web/configPage.html @@ -125,7 +125,7 @@
-
Elements hidden from guest sessions, e.g. other plugins' buttons. The default hides a plugin I had installed that injects its own floating UI into the web client.
+
Elements hidden from guest sessions, e.g. other plugins' buttons. Empty by default.
@@ -212,7 +212,7 @@ page.querySelector('#MaxExpiryHours').value = cfg.MaxExpiryHours || 720; page.querySelector('#PublicBaseUrlOverride').value = cfg.PublicBaseUrlOverride || ''; page.querySelector('#GuestUsernamePrefix').value = cfg.GuestUsernamePrefix || 'share-'; - page.querySelector('#GuestHiddenSelectors').value = cfg.GuestHiddenSelectors != null ? cfg.GuestHiddenSelectors : '.ais-fab,.ais-overlay,#ais-styles'; + page.querySelector('#GuestHiddenSelectors').value = cfg.GuestHiddenSelectors != null ? cfg.GuestHiddenSelectors : ''; page.querySelector('#AllowTranscoding').checked = cfg.AllowTranscoding !== false; page.querySelector('#AllowRemuxing').checked = cfg.AllowRemuxing !== false; page.querySelector('#CleanupIntervalMinutes').value = cfg.CleanupIntervalMinutes || 60;