Skip to content

v1.3.0 — Native client support, device pairing, security hardening

Choose a tag to compare

@ZL154 ZL154 released this 16 Apr 23:32

What's new

Native client support (Swiftfin, Findroid, etc.)

For users WITH a Jellyfin password — app passwords:
Go to `/TwoFactorAuth/Setup` → App Passwords → Generate. Enter the generated password in Swiftfin's password field. Each app password is independent, labeled, and revocable. Hashed with PBKDF2-SHA256 (200k iterations).

For passwordless users — device pairing:

  1. Open Swiftfin, tap Sign In → login fails (2FA required).
  2. Open Jellyfin web on a verified browser → `/TwoFactorAuth/Setup` → Devices Waiting for Approval shows your Swiftfin device.
  3. Click Trust → done. Go back to Swiftfin and sign in again — it works.

Redesigned Setup page

Unified dashboard: status + TOTP enrollment + recovery codes + email backup + pending device approvals + paired devices + app passwords + trusted browsers + active sessions. All in one page, dark theme.

Sidebar injection

"Two-Factor Auth" now appears in Jellyfin's nav drawer and settings page, matching your theme's styling via the AchievementBadges `.navMenuOption` pattern.

Admin fixes

  • Users tab fixed — was 404'ing because it used the wrong config endpoint (`System/Configuration` instead of `getPluginConfiguration`).
  • Test SMTP button and custom TOTP issuer name (from v1.2.x) preserved.

Security audit fixes

  • Atomic user data updates — `MutateAsync` prevents lost writes under concurrent requests.
  • Rate-limited app-password verification — 10 attempts/min per IP in the middleware.
  • Bounded pending dict — 5000 global cap, 50 per user, 30-min TTL.
  • Chunked-encoding support — middleware can now extract the password from chunked request bodies.
  • Fail-closed — middleware returns 503 (not the raw auth token) if challenge issuance throws.
  • Pending cleanup on disable — orphaned pending pairings are removed when 2FA is disabled.

Limitations

  • App passwords only work for users who have a Jellyfin password. For passwordless users, use device pairing instead.
  • QR pairing (scan a code to pair a device) deferred to v1.3.1. The auto-pending flow covers the same use case.
  • Native clients see "login failed" on first attempt — they have to retry after approval. There's no way to make them show a "pending approval" screen without client-side changes.

Upgrade

Install over v1.2.x. Restart Jellyfin. Hard-refresh all browsers (Ctrl+Shift+R).