Graphe des révisions
22 Révisions
Auteur SHA1 Message Date
Franciskid abbb0d448f hide share tags unless the viewer is a confirmed admin
The check skipped hiding when the Users/Me lookup came back empty, which is the
one case where we do not know who is looking. Only a positive administrator
verdict skips it now.
2026-07-26 20:30:40 +02:00
Franciskid aa8317d081 keep the share tag out of the UI for everyone except admins
The tag has to live in the item's real Tags for Jellyfin's tag policy to confine
the guest, so normal users were seeing a "sharelinks-<guid>" chip on any shared
title and an entry for it in the library tag filter. Admins still see them; for
everyone else the chip is taken back out of the tag row, along with the ", "
Jellyfin puts between chips, and the whole row is hidden when the share tag was
the only one. The tag filter entry gets hidden too.

Only tags matching sharelinks- plus 32 hex are touched, so a real tag that happens
to start with "sharelinks" is left alone. Guests benefit as well, since they were
seeing the tag on the title they were sent.

Worth being clear about the limit: this is the web UI. The tag is still in the API
response, so anyone reading the raw API can see it.
2026-07-26 20:30:26 +02:00
Franciskid 85a80b1c5b re-check who the current user is instead of trusting the first answer
The result of Users/Me was cached in a module level promise for the lifetime of
the page. The web client is a single page app, so signing out or switching
accounts never reloads the document and the script kept whichever user it saw
first. Open the page as an admin, switch to a normal user in the same tab, and
isAdministrator() still said yes: the admin-only ShareLink action was injected
into that user's menus.

The cached user and guest state are now keyed to ApiClient.getCurrentUserId(),
so a switch invalidates them, and a non-admin verdict actively removes any action
left in the DOM by the previous session instead of just declining to add one.

Nothing was reachable through this. The create endpoint checks the Administrator
role server side and answers 403 for a non-admin (confirmed against a real
non-admin session), so the button was there but did nothing.
2026-07-26 20:30:00 +02:00
Franciskid 35631eae46 move the ShareLink action to its own section at the bottom of the item menu
The button used to be cloned in next to "Copy Stream URL", or shoved at the top
of the menu when there was none, which put it in the middle of Jellyfin's own
command groups. Now there is a single injection path: append an actionsheetDivider
plus the action at the end of the sheet's scroller, so it reads as its own
section the way Jellyfin separates its groups.

It also stopped appearing on menus for things that are not media. The old code
resolved the item from the URL, so opening the "..." menu on a cast member inside
a movie page showed ShareLink and would have shared the movie behind it. The item
is now taken from the trigger that opened the menu (card, list row or the detail
page's own button, all of which we can walk up from) and its type is checked
against the server before anything is injected: movie, series, season, episode,
nothing else. The API refuses everything else too, so a hand-rolled request
cannot tag a person or a playlist either.

Clicking the action now dismisses the action sheet instead of leaving it stacked
under the dialog.
2026-07-26 16:21:05 +02:00
Franciskid 36fc574d49 update 1.0.1.0 manifest checksum for the series navigation fixes 2026-07-08 02:10:44 +02:00
Franciskid 6fecdb8902 fix series share navigation and menu placement
Three problems reported on series shares. The ShareLink action landed
at the bottom of the series menu because the fallback injector cloned
the last item and appended; it now clones the first item and inserts
at the top, matching where it sits for movies. Guests could not open
season or episode pages because guest mode disabled pointer events on
all cards; cards are clickable again, since the server-verified route
check and the tag policy already control where a guest can actually
go. The injected item also inherited the template's data-id, which
could shadow a real menu command like Informations; it is stripped
now.
2026-07-08 02:09:49 +02:00
Franciskid dce87e0826 add 1.0.1.0 to the plugin manifest 2026-07-08 01:51:58 +02:00
Franciskid bbb999842f share whole series and seasons, not just single titles
Sharing a series or season now tags the entire tree (series, seasons,
episodes) so the guest can browse and play everything inside it, and
strips it all again at cleanup. Redeeming re-tags the tree, so episodes
added after the link was created show up on the next redemption. The
guest lockdown in the web client now asks the server whether a page's
item is visible to the guest instead of hard-coding the single shared
id, so guests can navigate inside the shared tree but nowhere else.
Libraries and collections are still rejected.

Bumps the version to 1.0.1.0.
2026-07-08 01:50:57 +02:00
Franciskid 06a49d0bfe show a friendly page for dead share links, drop plugin-specific selector defaults
Opening an expired or invalid link used to dump raw problem-details
JSON at the guest. Now they get a small page matching the sign-in
look, with the same neutral wording whether the link expired or never
existed (so tokens cannot be probed by outsiders), and an automatic
redirect to the Jellyfin home page. Fixes #1.

GuestHiddenSelectors now defaults to empty instead of shipping CSS
selectors for a plugin nobody else runs. Existing installs keep their
saved value. Fixes #3.
2026-07-08 01:39:28 +02:00
Franciskid 2fb912e734 update manifest checksum for rebuilt v1.0.0.0 2026-07-08 01:19:41 +02:00
Franciskid f2b523be97 stop storing guest passwords, mint sessions server side
The old flow encrypted the guest password on disk next to its own key,
then sent it to the guest in the bootstrap HTML anyway. Now redemption
mints the session with ISessionManager.AuthenticateDirect and the page
only ever carries the session token. The guest account still gets a
random password nobody knows, so blank login stays impossible, but no
password is stored or sent anywhere anymore. Cleanup now defaults to
every 30 minutes instead of daily at 4am so expired guests die fast.
2026-07-08 00:50:20 +02:00
Franciskid 2f3c4a8213 ShareLinks: only inject the ShareLink button into real item action sheets
The fallback injector matched almost any dialog with a couple of buttons,
so the button leaked into the Edit images and Add to collection dialogs
(both opened from the item menu). Restrict it to genuine action sheets
(.actionSheet / [role=menu]) whose entries are .actionSheetMenuItem and
include a recognizable item command, which also excludes audio/subtitle/
quality pickers. The primary path (next to Copy Stream URL) is unchanged.
2026-07-07 22:15:26 +02:00
Franciskid 3c19c63d8c ShareLinks: add expiry date/time picker and French localization
Replace the 30-days quick button with a native datetime-local picker
(bounded by the server max) so links can expire on an exact date; the
picked date is converted to whole hours through the existing path.

Localize the creation popup and its toasts to French when the Jellyfin
UI language is French, detected from the html lang attribute like the
sibling plugin does; English is the fallback.
2026-07-07 22:10:11 +02:00
Franciskid dfd41279a0 ShareLinks: stop injecting the guest-link button into form dialogs
The action-sheet fallback matched any dialog with 2+ buttons, which
caught the Add to Collection dialog and stuck a Create guest link
button next to OK. Skip containers that have a select/text input/
textarea, since real action sheets are just a list of buttons/links.
2026-07-07 20:12:59 +02:00
Franciskid d965ecd66b ShareLinks: hide add-to-playlist/collection via robust JS match
The CSS data-id selector wasn't reliably hiding the action-sheet item in
guest sessions, so add a JS pass (part of the lockdown refresh) that
matches menu items by data-id, localized visible text, and icon, and
hides them with an inline style. The action sheet is added on menu open,
which the existing mutation observer already picks up.
2026-07-07 10:22:03 +02:00
Franciskid ceb3c03c87 ShareLinks: disable tag links, actually hide add-to-playlist/collection
The movie detail page's Tags section lives in its own .itemTags container,
not inside .detailsGroupItem like genres/studios/cast, so tag chips stayed
clickable for guests. Disable those links too.

The add-to-playlist and add-to-collection entries in the item's "..."
menu render with data-id="playlist"/data-id="addtocollection", not
data-action="addtoplaylist"/"addtocollection" as previously assumed —
that selector matched an unrelated list-row button and never hid the
actual menu items. Target the correct attribute so both are hidden.

Also drop the specific plugin name from the guest-hidden-selectors
description in favor of generic wording; the default selector value
is unchanged.
2026-07-07 09:05:18 +02:00
Franciskid 1f7928527e Add GPL-3.0 license, wire manifest to the v1.0.0.0 release asset 2026-07-07 07:57:52 +02:00
Franciskid 20160b3cbb ShareLinks: rename menu action to ShareLink with a share icon; rewrite README
Rename the injected context-menu action from 'Create guest link' to
'ShareLink' and swap its cloned copy icon (content_copy) for the share
icon, matching the other menu items' style.

Replace the placeholder scaffold README with a user-facing one describing
what the plugin does, the server-side guest confinement, configuration,
and the known Jellyfin cast/crew tag bug (jellyfin/jellyfin#14926).
2026-07-07 00:50:08 +02:00
Franciskid 0fecbb6697 ShareLinks: keep player back button, disable in-item links, hide add-to-playlist, generalize guest plugin hiding
Hiding .headerBackButton for guests also removed the video player's back
button (same class), so a guest could not return from playback to the
movie page. Stop hiding that class; keep home/drawer/search hidden.

Cast, studio, genre and tag links on the detail page now have
pointer-events disabled for guests so they stay visible but inert
(clicking Studio no longer spins on a page the guest cannot load), and
the add-to-playlist/add-to-collection actions are hidden.

Add a GuestHiddenSelectors config field (comma-separated CSS selectors,
surfaced through GuestState since guests cannot read plugin config) so
other plugins injected UI can be suppressed for guest sessions without
code changes; defaults to hiding the AI Search elements.
2026-07-07 00:35:10 +02:00
Franciskid e560c65d5a ShareLinks: resolve movie id from home cards and tighten guest lockdown
Creating a link from a home-page carousel resolved the wrong id: the
card context menu detaches into a body-level action sheet, so the DOM
walk missed the movie and fell back to the first data-id on the page (a
library folder), which then got rejected. Capture the pointed-at card's
item id at pointerdown so the action injects the right id.

Guest lockdown let guests reach the home page: nav was hidden by
matching English label keywords, which never matched the French UI, and
any details/list route counted as allowed. Hide the header
back/home/drawer/search buttons by CSS class instead, and treat only the
guest's own item page (or a playback route) as allowed so off-item
routes redirect back to the shared title.
2026-07-06 23:49:01 +02:00
Franciskid c964b4e37a ShareLinks: make guest redemption actually work end to end
The sign-in bootstrap sent the auth request body as a JS object, so it
was coerced to [object Object] and AuthenticateByName returned 400. Send
JSON.stringify(...) instead.

Guest credentials were written to localStorage as a flat object under
made-up keys. jellyfin-web reads jellyfin_credentials as
{Servers:[{Id,AccessToken,UserId,...}]}, so the guest was treated as
logged out. Write that shape, pulling server Id/name from
System/Info/Public, and redirect with the 10.11 hash route
(#/details?id=...&serverId=...) instead of the legacy #!/ form that
rendered a blank page.

Creating a link now rejects folders and libraries (only movies and
episodes are shareable) so a guest cannot land on an empty tag-filtered
library. Item ids from the menu action are validated as GUIDs client
side, rejected creates are logged server side, malformed redeem tokens
return 404 instead of 500, and the admin table shows the item name and a
copyable link instead of the raw item id.
2026-07-06 23:37:08 +02:00
Franciskid c29ea7f20c ShareLinks plugin: guest share links for Jellyfin
Includes fix for redemption failing with DbUpdateConcurrencyException:
change the guest password before applying the user policy, since
UpdatePolicyAsync bumps the user's EF concurrency token and a stale
instance then breaks ChangePassword.
2026-07-06 18:21:22 +02:00