Skip to content

v2.5.8

Choose a tag to compare

@github-actions github-actions released this 07 Jun 16:47

v2.5.8 — Admin step-up UX + smoke-test followups.

Iterative release. Fixes a handful of admin-UX bugs found during community
testing of v2.5.7, plus the lingering #55 design gap where the Users tab
silently dropped Jellyfin users who hadn't yet interacted with the plugin.

What's fixed

  • Issue #57 (lorenatkin) — StepUpLevel was enabled but clicking
    Save did nothing. The server-side gate (the v2.5.6
    PluginConfigStepUpFilter) was firing correctly and returning
    403 { stepUpRequired: true }, but the admin Save handler routed
    the main config POST through Jellyfin's built-in
    ApiClient.updatePluginConfiguration, which doesn't recognise the
    stepUpRequired body and silently rejected. The sibling
    HardeningConfig POST a few lines below already used our
    step-up-aware fetch wrapper; the main POST didn't. Now both flow
    through the same wrapper so the existing step-up modal opens on
    any gated save and the original request transparently replays
    after verification. Failure cases also surface visibly (was silent
    before).
  • StepUpLevel dropdown enum mismatch (found re-smoke-testing #57)
    Jellyfin's JsonStringEnumConverter serialises the enum by name
    ("Off" / "Destructive" / "AllConfigChanges" / "Everything")
    but the dropdown <option value=> strings were "0" / "1" /
    "2" / "3". Load handler set select.value = "Destructive"
    no matching option → dropdown went blank. Save handler
    parseInt("")NaN → defaulted to 0 → server stored Off.
    Net effect: the step-up level reset itself to Off on every Save,
    which is also why subsequent settings toggles weren't gated.
    Option values now use enum names directly.
  • Issue #55 followup (Dasnap) — the v2.5.7 fix made GetUsers
    resilient to corrupt Guid.Empty rows but didn't address the
    underlying gap that the listing only enumerated users with plugin
    data files. Users who'd never interacted with the plugin were
    invisible until their next sign-in. Enumeration now starts from
    Jellyfin's user table and merges plugin data per user, defaulting
    to all-zero counts for unenrolled users. A single user's data file
    failing to read no longer 500s the whole listing.
  • Issue #56 (cwildfoerster, derpacco) — when an admin's
    TrustedProxyCidrs entry is too broad (e.g. RFC1918 ranges) the
    SEC-H3 guard from v2.4.12 silently refuses LAN bypass for every
    direct LAN client. Added an inline help block under the admin field
    explaining the trap with concrete fix examples, and promoted the
    refusal log line from Debug to Information on first hit per peer
    IP (subsequent hits stay at Debug to avoid spam) with the matched
    CIDR in the payload so admins can self-diagnose without a
    debug-level filter.
  • Pending-pair Approve / Deny / QR buttons no longer fail silently
    each click handler now disables the button + shows a spinner during
    the request, and surfaces server errors via alert +
    console.error on failure. Previously a 4xx left the button looking
    dead.
  • Textarea clipping (found during #57 smoke test).tfa-input
    default box-sizing: content-box caused every width:100% textarea
    (LAN CIDRs, Trusted Proxy CIDRs, Admin email addresses, Exempt
    CIDRs, Restore JSON paste box) to bleed its horizontal padding
    outside the parent panel. The Allowed-origins textarea was the only
    one not visibly broken because its parent is a .tfa-row flex
    container that absorbed the overflow. One-line CSS fix.

What's new

  • Tooltip for Trusted Proxy CIDRs — admin Hardening section now
    carries explicit guidance to enter only the actual reverse-proxy
    host IPs (127.0.0.1/32 for same-host nginx, etc.), not broad LAN
    ranges. Includes a reference to issue #56.

Code-quality

  • Two CodeQL cs/cleartext-storage-of-sensitive-information alerts
    dismissed as false positives. CIDRs from TrustedProxyCidrs are
    admin-configured network topology, already cleartext in
    PluginConfiguration.xml by necessity, and the SEC-H3 diagnostic
    depends on surfacing the matched CIDR — the entire point of
    showing it is admin self-diagnosis.

Upgrade

  • In-place. No schema breakage, no required config edits.
  • 254/254 tests pass on .NET 9 / Jellyfin 10.11.10.
  • If StepUpLevel was set to anything other than Off on v2.5.7 with
    a fresh-installed plugin, the dropdown bug may have silently reset
    it to Off on the first Save. After upgrading to v2.5.8 and hard-
    refreshing the admin page, the actual saved value will be visible
    in the dropdown again — re-pick the value you want and Save once.

Verification

gh attestation verify Jellyfin.Plugin.TwoFactorAuthv2.5.8.0.zip --owner ZL154
cosign verify-blob --certificate Jellyfin.Plugin.TwoFactorAuthv2.5.8.0.zip.pem \
    --signature Jellyfin.Plugin.TwoFactorAuthv2.5.8.0.zip.sig \
    --certificate-identity-regexp "https://github.com/ZL154/JellyfinSecurity/.*" \
    --certificate-oidc-issuer https://token.actions.githubusercontent.com \
    Jellyfin.Plugin.TwoFactorAuthv2.5.8.0.zip

Thanks to @lorenatkin for the #57 report and @Dasnap for following
up on #55 with reproducible details.