github ZL154/JellyfinSecurity v2.6.0

2 hours ago

v2.6.0

Jellyfin 12 is supported. This release ships a second build so the plugin loads and runs on Jellyfin 12 (which moved to .NET 10), while the existing build keeps serving Jellyfin 10.11.x exactly as before. Both live in the one plugin catalog under the same entry, so your server downloads the build that matches its version: there is nothing to pick and existing installs update themselves. It also fixes the admin step-up prompt on the settings save path and the OIDC provider form, and makes the GeoIP diagnostics finally explain themselves. Drop-in from any 2.5.x, with no config or data migration.

Jellyfin 12 support, without dropping 10.11

(Closes #196 and #172.)

Jellyfin 12 moved to .NET 10, and a plugin compiled against 10.11 (.NET 9) will not load on it, which is why every action returned 401 / "Unauthorized" on 12 (#172). Rather than fork the plugin or abandon 10.11 users, this release builds the same source twice:

  • a .NET 9 build for Jellyfin 10.11.x hosts, and
  • a .NET 10 build for Jellyfin 12.x hosts.

Both are published in the one manifest.json under the same plugin, keyed by the Jellyfin version each needs. Jellyfin's own catalog keeps the builds whose target version is at or below your server's and installs the newest, so a 12 server pulls the .NET 10 build, a 10.11 server pulls the .NET 9 build, and neither ever sees the other. You do not choose a download: the catalog and auto-update do it for you. If you install manually from the Releases page instead, grab the -jf12 zip on Jellyfin 12 and the plain zip on 10.11.

Everything was verified end to end on a real Jellyfin 12 server and a Jellyfin 10.11 server: sign-in, refresh persistence, OIDC/SSO, TOTP, email OTP, recovery codes, passkeys, app passwords, admin step-up, the PDF recovery-code export, and the admin dashboard page.

Related 12 fixes rolled in:

  • #191 (camarigor): in-app OIDC sign-in on 12 froze on a blank screen. On 12 the router asks for the server connection before the reconnect that 10.11 did first, so the stored credential (which had no resolvable address) left the client pointing at nothing. The sign-in bridge now stores the address it just authenticated against, in the connection mode 12 expects.
  • #193 (camarigor): 12 changed some web routes, so the plugin's setup link and the way it re-enters the setup page needed updating. 12 users get a working way back to the setup page from the avatar menu.
  • Completes the header work from v2.5.22 (#174/#180): the plugin's pages and endpoints accept Jellyfin's current Authorization: MediaBrowser Token header, which 12 requires once legacy authorization is disabled.

The admin step-up prompt now appears everywhere it should

(Closes #198 and #194; helps #189 and #148.)

The server has gated the sensitive admin actions (creating, editing and deleting OIDC providers, toggling a user's 2FA, "require password setup", and reading the audit log) behind a step-up re-authentication since v2.5.6. But some of the admin page's own calls sent those requests with a plain fetch, so the server's 403 { stepUpRequired: true } came back as a bare "Save failed" and, for provider Delete, nothing happened at all (#198). Adding an identity provider on a step-up-protected server was simply impossible.

  • #198 / #199 (camarigor): the provider form and the shared admin helpers now go through the step-up-aware fetch that Save Settings has used since v2.5.8. When step-up is required you get the prompt; when something else fails you get the server's actual reason instead of a generic message.
  • #194 / #195 (camarigor): the admin step-up modal previously accepted only a typed TOTP code, locking out admins whose second factor is an emailed code or a passkey. It now offers the emailed code and a passkey alongside TOTP, using the same unified proof the rest of the plugin uses.

If you hit "valid code rejected at step-up" on 10.11 (#189), please retest on this build: the step-up verification and the admin-call routing both changed here.

GeoIP diagnostics that explain themselves

(#200, camarigor. Refs #51.)

Three people reported GeoIP databases loaded = Fail with the files in place, and none had a log line to go on, because the loader had nothing to say: it fixed the configured path before trying to open it, a file the process could not see was skipped in silence, and a failed load was never retried until the path changed or Jellyfin restarted. Now the loader keeps the reason, retries, and falls back to an in-memory open, and the Diagnostics tab prints what it saw for each database. A bad path no longer reads as a blank "Fail": it says, for example, not found at /config/geoip/GeoLite2-ASN.mmdb (its directory is not visible to the Jellyfin process; checked as user root) or rejected (not absolute), so you can actually fix it.

Upgrade notes

In-place upgrade from any 2.5.x, with no schema or configuration migration. 500 tests pass. Sigstore-signed and SLSA build-provenance attested. Both the 10.11 (.NET 9) and 12 (.NET 10) packages are published for this version; your server selects the right one automatically.

Don't miss a new JellyfinSecurity release

NewReleases is sending notifications on new releases.