- Version .5
Cette révision appartient à :
@@ -0,0 +1,165 @@
|
|||||||
|
name: "Release"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "v*"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Extract version from tag
|
||||||
|
id: version
|
||||||
|
run: |
|
||||||
|
TAG="${GITHUB_REF_NAME}"
|
||||||
|
VERSION="${TAG#v}"
|
||||||
|
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Setup .NET
|
||||||
|
uses: actions/setup-dotnet@v4
|
||||||
|
with:
|
||||||
|
dotnet-version: "10.0.x"
|
||||||
|
|
||||||
|
- name: Update version in .csproj
|
||||||
|
run: |
|
||||||
|
CSPROJ="Jellyfin.Plugin.ShareLinks/Jellyfin.Plugin.ShareLinks.csproj"
|
||||||
|
VERSION="${{ steps.version.outputs.version }}"
|
||||||
|
sed -i "s|<Version>.*</Version>|<Version>${VERSION}</Version>|" "$CSPROJ"
|
||||||
|
sed -i "s|<AssemblyVersion>.*</AssemblyVersion>|<AssemblyVersion>${VERSION}</AssemblyVersion>|" "$CSPROJ"
|
||||||
|
sed -i "s|<FileVersion>.*</FileVersion>|<FileVersion>${VERSION}</FileVersion>|" "$CSPROJ"
|
||||||
|
grep -E "Version>" "$CSPROJ"
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: dotnet build Jellyfin.Plugin.ShareLinks -c Release
|
||||||
|
|
||||||
|
- name: Compute build timestamp
|
||||||
|
id: timestamp
|
||||||
|
run: |
|
||||||
|
TS=$(date -u +"%Y-%m-%dT%H:%M:%S.%6N0Z")
|
||||||
|
echo "timestamp=${TS}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Update meta.json
|
||||||
|
run: |
|
||||||
|
META="Jellyfin.Plugin.ShareLinks/meta.json"
|
||||||
|
VERSION="${{ steps.version.outputs.version }}"
|
||||||
|
TIMESTAMP="${{ steps.timestamp.outputs.timestamp }}"
|
||||||
|
jq --arg v "$VERSION" --arg ts "$TIMESTAMP" \
|
||||||
|
'.version = $v | .timestamp = $ts' \
|
||||||
|
"$META" > "${META}.tmp"
|
||||||
|
mv "${META}.tmp" "$META"
|
||||||
|
cat "$META"
|
||||||
|
|
||||||
|
- name: Package release archive
|
||||||
|
run: |
|
||||||
|
VERSION="${{ steps.version.outputs.version }}"
|
||||||
|
OUT="Jellyfin.Plugin.ShareLinks/bin/Release/net9.0"
|
||||||
|
STAGING="staging"
|
||||||
|
mkdir -p "$STAGING"
|
||||||
|
cp "${OUT}/Jellyfin.Plugin.ShareLinks.dll" "$STAGING/"
|
||||||
|
cp "Jellyfin.Plugin.ShareLinks/meta.json" "$STAGING/"
|
||||||
|
cd "$STAGING"
|
||||||
|
zip -r "../sharelinks_${VERSION}.zip" .
|
||||||
|
cd ..
|
||||||
|
ls -la sharelinks_${VERSION}.zip
|
||||||
|
|
||||||
|
- name: Compute checksum
|
||||||
|
id: checksum
|
||||||
|
run: |
|
||||||
|
VERSION="${{ steps.version.outputs.version }}"
|
||||||
|
CHECKSUM=$(md5sum "sharelinks_${VERSION}.zip" | awk '{print $1}')
|
||||||
|
echo "checksum=${CHECKSUM}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "MD5: ${CHECKSUM}"
|
||||||
|
|
||||||
|
- name: Update manifest.json
|
||||||
|
run: |
|
||||||
|
MANIFEST="manifest.json"
|
||||||
|
VERSION="${{ steps.version.outputs.version }}"
|
||||||
|
TIMESTAMP="${{ steps.timestamp.outputs.timestamp }}"
|
||||||
|
CHECKSUM="${{ steps.checksum.outputs.checksum }}"
|
||||||
|
|
||||||
|
jq \
|
||||||
|
--arg version "$VERSION" \
|
||||||
|
--arg timestamp "$TIMESTAMP" \
|
||||||
|
--arg checksum "$CHECKSUM" \
|
||||||
|
'
|
||||||
|
.[0].versions |= (
|
||||||
|
if any(.[]; .version == $version) then
|
||||||
|
|
||||||
|
map(
|
||||||
|
if .version == $version then
|
||||||
|
if has("changelog") | not then
|
||||||
|
.changelog = ""
|
||||||
|
else
|
||||||
|
.
|
||||||
|
end
|
||||||
|
| if has("targetAbi") then
|
||||||
|
.targetAbi = "10.11.0.0"
|
||||||
|
else
|
||||||
|
.
|
||||||
|
end
|
||||||
|
| if has("sourceUrl") then
|
||||||
|
.sourceUrl = "https://git.celjim.fr/public/jellyfin-plugin-sharelinks/releases/download/v\($version)/sharelinks_\($version).zip"
|
||||||
|
else
|
||||||
|
.
|
||||||
|
end
|
||||||
|
| if has("checksum") then
|
||||||
|
.checksum = $checksum
|
||||||
|
else
|
||||||
|
.
|
||||||
|
end
|
||||||
|
| if has("timestamp") then
|
||||||
|
.timestamp = $timestamp
|
||||||
|
else
|
||||||
|
.
|
||||||
|
end
|
||||||
|
else
|
||||||
|
.
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
[{
|
||||||
|
"version": $version,
|
||||||
|
"changelog": "",
|
||||||
|
"targetAbi": "10.11.0.0",
|
||||||
|
"sourceUrl": "https://git.celjim.fr/public/jellyfin-plugin-sharelinks/releases/download/v\($version)/sharelinks_\($version).zip",
|
||||||
|
"checksum": $checksum,
|
||||||
|
"timestamp": $timestamp
|
||||||
|
}] + .
|
||||||
|
|
||||||
|
end
|
||||||
|
)
|
||||||
|
' "$MANIFEST" > "${MANIFEST}.tmp"
|
||||||
|
|
||||||
|
mv "${MANIFEST}.tmp" "$MANIFEST"
|
||||||
|
|
||||||
|
cat "$MANIFEST"
|
||||||
|
|
||||||
|
- name: Commit and push manifest
|
||||||
|
run: |
|
||||||
|
git config user.name "Gitea Actions"
|
||||||
|
git config user.email "actions@celjim.fr"
|
||||||
|
|
||||||
|
git add manifest.json Jellyfin.Plugin.ShareLinks/meta.json Jellyfin.Plugin.ShareLinks/Jellyfin.Plugin.ShareLinks.csproj
|
||||||
|
|
||||||
|
if git diff --cached --quiet; then
|
||||||
|
echo "No changes to commit"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
git commit -m "Update manifest/meta for v${{ steps.version.outputs.version }}"
|
||||||
|
git push origin HEAD:${{ github.event.repository.default_branch }}
|
||||||
|
|
||||||
|
- name: Publish Gitea release
|
||||||
|
uses: https://gitea.com/actions/gitea-release-action@main
|
||||||
|
with:
|
||||||
|
files: |-
|
||||||
|
sharelinks_${{ steps.version.outputs.version }}.zip
|
||||||
|
token: "${{ secrets.RELEASE_TOKEN }}"
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"guid": "68540b76-ee74-436d-85ff-2abc884bbea6",
|
"guid": "68540b76-ee74-436d-85ff-2abc884bbea6",
|
||||||
"name": "ShareLinks",
|
"name": "ShareLinks",
|
||||||
"version": "1.0.6.0",
|
"version": "1.0.6.5",
|
||||||
"targetAbi": "10.11.0.0",
|
"targetAbi": "10.11.0.0",
|
||||||
"framework": "net9.0",
|
"framework": "net9.0",
|
||||||
"owner": "Franciskid",
|
"owner": "Franciskid",
|
||||||
"overview": "Secure expiring guest-share links for Jellyfin items.",
|
"overview": "Secure expiring guest-share links for Jellyfin items.",
|
||||||
"description": "Adds secure, expiring share links for Jellyfin items with JSON-backed storage, token hashing, and cleanup scaffolding.",
|
"description": "Adds secure, expiring share links for Jellyfin items with JSON-backed storage, token hashing, and cleanup scaffolding.",
|
||||||
"category": "General",
|
"category": "General",
|
||||||
"timestamp": "2026-09-18T18:00:00.0000000Z"
|
"timestamp": ""
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-3
@@ -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
|
# ShareLinks for Jellyfin
|
||||||
|
|
||||||
Share a movie, episode, season or series with a link. The person you send it to does not need
|
Share a movie, episode, season or series with a link. The person you send it to does not need
|
||||||
@@ -69,7 +82,7 @@ sequenceDiagram
|
|||||||
## Design decisions
|
## Design decisions
|
||||||
|
|
||||||
| Decision | Reason |
|
| 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`. |
|
| 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. |
|
| 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. |
|
| 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. |
|
||||||
@@ -123,7 +136,7 @@ to appear.
|
|||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
| Setting | Effect | Default |
|
| Setting | Effect | Default |
|
||||||
|---|---|---|
|
| ---------------------------------- | ---------------------------------------------------------------- | -------- |
|
||||||
| Default expiry | The expiry the create popup offers first | 24 h |
|
| Default expiry | The expiry the create popup offers first | 24 h |
|
||||||
| Maximum expiry | The longest allowed lifetime for a link | 720 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 |
|
| Public base URL override | Forces the host used to build links, instead of the request host | derived |
|
||||||
@@ -148,7 +161,7 @@ settings above.
|
|||||||
## HTTP API
|
## HTTP API
|
||||||
|
|
||||||
| Endpoint | Auth | Purpose |
|
| Endpoint | Auth | Purpose |
|
||||||
|---|---|---|
|
| ------------------------------------ | ------- | ---------------------------------------------------- |
|
||||||
| `POST /ShareLinks/Admin/Create` | Admin | Create a link. Returns the raw URL once |
|
| `POST /ShareLinks/Admin/Create` | Admin | Create a link. Returns the raw URL once |
|
||||||
| `GET /ShareLinks/Admin/List` | Admin | All records with status and expiry |
|
| `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/Revoke/{id}` | Admin | Revoke a link and remove its guest account and tags |
|
||||||
|
|||||||
@@ -8,6 +8,14 @@
|
|||||||
"category": "General",
|
"category": "General",
|
||||||
"imageUrl": "",
|
"imageUrl": "",
|
||||||
"versions": [
|
"versions": [
|
||||||
|
{
|
||||||
|
"version": "1.0.6.5",
|
||||||
|
"changelog": "Add collections, videos, and images to shareable items\nAdd sharing of BoxSet subsets\nHide/remove items from playlists or BoxSets\nHide the empty '...' menu button on BoxSet detail pages for guests\nAdd ShareLinks to the admin Extensions menu with a share icon\nTranslate the ShareLink action sheet label into French\nAdd French translation to the plugin configuration page\nDon't hide media cards whose titles contain a guard keyword as a substring",
|
||||||
|
"targetAbi": "10.11.0.0",
|
||||||
|
"sourceUrl": "https://git.celjim.fr/public/jellyfin-plugin-sharelinks/releases/download/v1.0.6.5/sharelinks_1.0.6.5.zip",
|
||||||
|
"checksum": "",
|
||||||
|
"timestamp": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "1.0.6.0",
|
"version": "1.0.6.0",
|
||||||
"changelog": "Fixes share links on Jellyfin 12 and the ShareLink button missing on new Docker installs.",
|
"changelog": "Fixes share links on Jellyfin 12 and the ShareLink button missing on new Docker installs.",
|
||||||
|
|||||||
Référencer dans un nouveau ticket
Bloquer un utilisateur