github openVESSL/Anchorr v1.4.3

6 hours ago

🔒 Security

  • Login brute-force protection (ref #80): Account locked for 10 minutes after 5 consecutive failed login attempts per username (HTTP 429 with seconds remaining). Progressive 300ms-per-attempt response delay (capped at 4 s) slows automated tools. bcrypt always runs even for unknown usernames to prevent user enumeration via timing. Existing IP-based rate limit (20 req / 15 min) remains as a first layer
  • XSS fix — user mapping remove button: discordUserId is now escaped with escapeHtml() before being placed in the onclick attribute, and validated against Discord snowflake format (17–19 digits). Fixes stored XSS where a crafted Discord user ID could inject arbitrary JS into any admin's browser on page load

🐛 Fixed

  • Jellyfin webhook Content-Type: express.json() was silently dropping Jellyfin webhook bodies because Jellyfin sends Content-Type: text/plain. The endpoint now uses express.json({ type: "*/*" }) to accept any content type
  • Webhook debounce error no longer blocks a series: A failed Discord send previously left a level: -1 temp marker in sentNotifications, blocking all future webhooks for that series for up to 24 hours. The marker is now deleted immediately on error, and the orphaned-marker cleanup timeout is reduced from 24 h to 5 min
  • Empty channel no longer crashes the webhook handler: When no Discord channel is configured for a library, the handler now logs a clear config error and returns cleanly instead of throwing a cryptic Discord API exception

🚀 Improvements

  • Seerr rebrand: All JELLYSEERR_* config keys renamed to SEERR_*. Existing config.json is migrated automatically on first boot. If you have JELLYSEERR_* set as environment variables outside of config.json, rename them manually
  • Pending DM requests survive restarts: pendingRequests is persisted to pending-requests.json (next to config.json, mode 0600) on every write and loaded on bot startup — users who requested media via /request now receive their DM notification even if the bot was restarted before the media became available
  • Webhook secret visible on page load: The webhook secret field in the dashboard is now populated automatically on load so the value is immediately visible and copyable without digging through the config
  • Better webhook error logs: Errors and warnings in the webhook handler now include ItemType and Name for easier debugging without parsing the raw payload

🏗️ Code Quality

  • Fix timer leak in auth.js: previous cleanup timer is cancelled before a new one is scheduled, preventing unbounded setTimeout handle accumulation under sustained login attacks
  • Remove redundant Map.get call in the login handler immediately after recordFailure
  • /api/webhook-secret returns the in-memory WEBHOOK_SECRET constant instead of calling readConfig() on every request
  • Copy-secret button reads from the already-populated input field instead of making a second fetch to /api/webhook-secret

Don't miss a new Anchorr release

NewReleases is sending notifications on new releases.