- Add workflow Action
Release / build-and-release (push) Successful in 32s

- Version .5
Cette révision appartient à :
2026-09-19 21:48:19 +02:00
Parent ce42fff915
révision 51b4909cbd
4 fichiers modifiés avec 291 ajouts et 105 suppressions
+49 -36
Voir le fichier
@@ -1,3 +1,16 @@
## Changes in this fork
This repository is based on the original ShareLinks plugin and includes the following modifications and improvements:
- Added support for sharing **collections, videos, and images**.
- Added support for sharing **BoxSet subsets**.
- Added the ability to **hide or remove items from playlists and BoxSets** for guests.
- Hidden the empty **"..."** menu button on BoxSet detail pages for guests.
- Added **ShareLinks** to the administrator **Extensions** menu with a share icon.
- Translated the **ShareLink** action sheet label into French.
- Added a **French translation** for the plugin configuration page.
- Updated media card filtering so that cards are **not hidden when their titles merely contain a guard keyword as a substring**.
# ShareLinks for Jellyfin
Share a movie, episode, season or series with a link. The person you send it to does not need
@@ -68,18 +81,18 @@ sequenceDiagram
## Design decisions
| Decision | Reason |
|---|---|
| Only the token HMAC hash is stored | The raw token is returned once and is never saved to disk. Lookups hash the presented token and compare with `FixedTimeEquals`. |
| The HMAC key is a per-server file, mode 0600 | The `sharelinks.json` file alone cannot be used to recover a token. The key is generated on first use. |
| Tags propagate down, never up | A bug fixed in 1.0.3: a shared season tagged its parent series, and Jellyfin's tag inheritance then exposed every other season of that series. |
| Guest accounts use a dedicated authentication provider | Guests cannot sign in through the login page with a password. If the plugin is disabled, Jellyfin also refuses those sign-ins. |
| The password is generated per redemption and thrown away | This prevents sign-in with a blank password. The browser receives only a session token. |
| Links are redeemed one request at a time | This prevents two simultaneous requests from both using the same single-use link. |
| Each multi-use viewer receives its own device id | Jellyfin logs out any session with the same user and device id, so a shared device id would kick out the previous viewer on every new arrival. |
| The viewer limit is checked before changing anything | Handling the limit before Jellyfin raises an error lets the plugin turn away a new viewer without interrupting anyone already watching. |
| Other plugins are blocked by default | The filter distinguishes Jellyfin core from plugin code, so newly installed plugins are blocked too. |
| Guest devices are deleted before the user | Jellyfin does not remove devices when a user is deleted. Leftover devices can break the admin devices page. |
| Decision | Reason |
| -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| Only the token HMAC hash is stored | The raw token is returned once and is never saved to disk. Lookups hash the presented token and compare with `FixedTimeEquals`. |
| The HMAC key is a per-server file, mode 0600 | The `sharelinks.json` file alone cannot be used to recover a token. The key is generated on first use. |
| Tags propagate down, never up | A bug fixed in 1.0.3: a shared season tagged its parent series, and Jellyfin's tag inheritance then exposed every other season of that series. |
| Guest accounts use a dedicated authentication provider | Guests cannot sign in through the login page with a password. If the plugin is disabled, Jellyfin also refuses those sign-ins. |
| The password is generated per redemption and thrown away | This prevents sign-in with a blank password. The browser receives only a session token. |
| Links are redeemed one request at a time | This prevents two simultaneous requests from both using the same single-use link. |
| Each multi-use viewer receives its own device id | Jellyfin logs out any session with the same user and device id, so a shared device id would kick out the previous viewer on every new arrival. |
| The viewer limit is checked before changing anything | Handling the limit before Jellyfin raises an error lets the plugin turn away a new viewer without interrupting anyone already watching. |
| Other plugins are blocked by default | The filter distinguishes Jellyfin core from plugin code, so newly installed plugins are blocked too. |
| Guest devices are deleted before the user | Jellyfin does not remove devices when a user is deleted. Leftover devices can break the admin devices page. |
## What the guest can do
@@ -122,20 +135,20 @@ to appear.
## Configuration
| Setting | Effect | Default |
|---|---|---|
| Default expiry | The expiry the create popup offers first | 24 h |
| Maximum expiry | The longest allowed lifetime for a link | 720 h |
| Public base URL override | Forces the host used to build links, instead of the request host | derived |
| Guest username prefix | Prefix for the temporary accounts | `share-` |
| Allow transcoding / remuxing | Whether guest playback may transcode or remux | on |
| Cleanup interval | How often the background cleanup runs | 60 min |
| Maximum viewers per multi-use link | Concurrent viewers on one multi-use link. 0 means no limit | 10 |
| Single use by default | How the create popup starts | on |
| Guest lockdown | Hides navigation controls in the guest interface | on |
| Block other plugins for guests | Blocks guest access to other plugins on the server | on |
| Plugin access list | Plugins guests are allowed to access | empty |
| Cosmetic hidden selectors | Hides matching elements in the browser; does not restrict access | empty |
| Setting | Effect | Default |
| ---------------------------------- | ---------------------------------------------------------------- | -------- |
| Default expiry | The expiry the create popup offers first | 24 h |
| Maximum expiry | The longest allowed lifetime for a link | 720 h |
| Public base URL override | Forces the host used to build links, instead of the request host | derived |
| Guest username prefix | Prefix for the temporary accounts | `share-` |
| Allow transcoding / remuxing | Whether guest playback may transcode or remux | on |
| Cleanup interval | How often the background cleanup runs | 60 min |
| Maximum viewers per multi-use link | Concurrent viewers on one multi-use link. 0 means no limit | 10 |
| Single use by default | How the create popup starts | on |
| Guest lockdown | Hides navigation controls in the guest interface | on |
| Block other plugins for guests | Blocks guest access to other plugins on the server | on |
| Plugin access list | Plugins guests are allowed to access | empty |
| Cosmetic hidden selectors | Hides matching elements in the browser; does not restrict access | empty |
**On the plugin access list:** some plugins have to answer guests. An intro skipper, for example,
is called by the client during playback. Enable access for that plugin in the list. Plugins are blocked by default, including newly
@@ -147,16 +160,16 @@ settings above.
## HTTP API
| Endpoint | Auth | Purpose |
|---|---|---|
| `POST /ShareLinks/Admin/Create` | Admin | Create a link. Returns the raw URL once |
| `GET /ShareLinks/Admin/List` | Admin | All records with status and expiry |
| `POST /ShareLinks/Admin/Revoke/{id}` | Admin | Revoke a link and remove its guest account and tags |
| `POST /ShareLinks/Admin/Cleanup` | Admin | Remove revoked, expired and failed records |
| `GET /ShareLinks/Admin/Plugins` | Admin | Installed plugins and their guest access state |
| `GET /ShareLinks/GuestState` | Session | Whether the caller is a guest, and what to lock down |
| `GET /ShareLinks/Redeem?t=...` | none | Redeem a token, return the bootstrap page |
| `GET /ShareLinks/ClientScript` | none | The injected web-client script |
| Endpoint | Auth | Purpose |
| ------------------------------------ | ------- | ---------------------------------------------------- |
| `POST /ShareLinks/Admin/Create` | Admin | Create a link. Returns the raw URL once |
| `GET /ShareLinks/Admin/List` | Admin | All records with status and expiry |
| `POST /ShareLinks/Admin/Revoke/{id}` | Admin | Revoke a link and remove its guest account and tags |
| `POST /ShareLinks/Admin/Cleanup` | Admin | Remove revoked, expired and failed records |
| `GET /ShareLinks/Admin/Plugins` | Admin | Installed plugins and their guest access state |
| `GET /ShareLinks/GuestState` | Session | Whether the caller is a guest, and what to lock down |
| `GET /ShareLinks/Redeem?t=...` | none | Redeem a token, return the bootstrap page |
| `GET /ShareLinks/ClientScript` | none | The injected web-client script |
Records live in `sharelinks/sharelinks.json` under Jellyfin's data folder. The HMAC key lives beside
it in `token-secret.key`.