github ZL154/AchievementBadges_for_Jellyfin v1.9.0
v1.9.0 — UI Revamp + Security A+ + plugin-wide efficiency overhaul

latest releases: v2.4.0, v2.3.1, v2.3.0...
4 months ago

Cumulative release covering all work since v1.8.10. New features, major architectural improvements, and a security posture upgrade from B+ to A+.

New features

  • Full Revamp UI on /achievements — magazine hero, conic donut, asymmetric stats grid, chapter tabs, control-panel filter strip, ambient orb + film grain
  • Friends drawer Revamp — follows the same Classic/Revamp toggle as the achievements page
  • "Offline — last watched X" — offline friends now mirror the online "Watching X" treatment
  • HideLastWatched privacy preference — opt out of the last-watched echo
  • HMAC-SHA256 webhook signing — outbound POSTs now include X-AchievementBadges-Signature and X-AchievementBadges-Timestamp headers when admin sets WebhookSigningSecret. Same envelope as Stripe / GitHub.

Backend efficiency

  • AchievementBadgeService.Save() and MessagingService.Save() debounced 1.5s — coalesces back-to-back writes from playback/messaging hot paths into one disk flush
  • FriendsService LastWatched lookups cached 90s with play-event invalidation (eliminates per-friend 50-item DB query on every friends-list call)
  • AuditLogService.Log uses RemoveRange for in-place FIFO trim; GetRecent does an O(limit) tail walk instead of OrderByDescending
  • WriteIndented disabled on production stores (~50% smaller files)
  • Embedded resource cache in client-script route (no more re-streaming CSS/JS/JSON/PNG/MP3/SVG from the assembly on every request)
  • Cache-Control: public, max-age=86400, immutable on assets, with version-only cache busting (browsers actually cache between page loads now)
  • SidebarInjectionMiddleware marker fast-path (last-4KB scan) + injection log dropped from INF to Debug
  • Sidebar showcase poller backs off from 5s to 30s steady state after page settled

Security A+

  • Default class-level rate limit (user-60-per-min) on every controller route, with stricter overrides preserved on cooldown routes
  • AdminAuditLogFilter writes an entry on every RequiresElevation action
  • CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy on the anonymous profile-card endpoint
  • New Jellyfin.Plugin.AchievementBadges.Tests project — 34 xUnit security regression tests covering WebhookUrlValidator and SvgSanitizer (SSRF, IPv6 SSRF, scheme rejection, malformed URL rejection, dangerous SVG element rejection, on-event-handler rejection, external DTD rejection, oversized payload rejection, external <use href> rejection)
  • GitHub Actions workflow .github/workflows/security.yml runs the tests + dotnet list package --vulnerable + gitleaks on every push, PR, and weekly cron
  • SECURITY.md expanded with full threat model, trust boundaries, defences-in-place inventory, continuous verification matrix, and disclosure SLA
  • Three medium-severity audit findings fixed: GetActivityFeed + GetMessageThread + GetConvMessages clamp page/limit to safe bounds; WebhookUrlValidator now fails closed on DNS errors instead of allowing through

Verification

  • 34/34 security regression tests pass
  • Plugin starts clean on the live host with v1.9.0;

Don't miss a new AchievementBadges_for_Jellyfin release

NewReleases is sending notifications on new releases.