Skip to content

Release v0.6.0

Choose a tag to compare

@github-actions github-actions released this 08 Oct 12:46
· 141 commits to main since this release
106b702

✨ New features

  • Bonus points, shop & bounties (#48, #55)
    • Earn points: by seeding (per torrent per day), when an upload is approved, and by filling bounties. All rates are set by the admin.
    • Shop: the admin defines the items and their prices. Available item types are upload credit, invites, and an animated avatar unlock.
    • Avatars: PNG, JPEG and WebP for everyone; animated GIF, WebP and APNG once unlocked.
    • Bounties: request a torrent with points held in escrow. Others can contribute, the uploader of the accepted torrent gets the reward, and cancelling refunds every contributor.
  • Translations (#43, #54): the whole UI is available in English and French. The browser language is detected and there is a switcher in the footer. New languages can be added by copying i18n/locales/en/.
  • IMDb / TMDb / TheTVDB IDs (#47): set at upload or edited later, and shown as links on the torrent page. Torznab now really searches by imdbid, tmdbid and tvdbid, returns them as attributes and advertises them in caps, so Sonarr and Radarr can match releases by ID.
  • Upload modal (#42): shows your personal announce URL with a copy button, plus an optional display name. The name can be edited afterwards.

🐛 Fixes

  • "Torrent not found or inactive" after downloading (#49): torrents uploaded without the private flag changed info hash on download. Uploads are now made private when stored, and the stored hash matches the downloaded file.
  • Announce URL pointing to localhost (#49): tracker URLs are now applied at runtime (NUXT_PUBLIC_TRACKER_*), and install.sh builds the image with the URLs from your .env.

🔒 Security

A full security audit (#50). Highlights:

  • Panic mode: the encryption key is now derived from the panic password itself, every value gets its own IV, and both encrypt and restore are transactional. The anonymous access that existed outside production is removed.
  • Stored XSS: torrent descriptions and admin rich text are now sanitized.
  • Roles and bans: checked against the database on every request, and sessions expire after 7 days.
  • Client IP: proxy headers are only trusted from known proxies (TRUSTED_PROXIES), which closes IP-ban and rate-limit bypasses.
  • Data leaks:
    • the raw .torrent file (which contained the uploader's passkey) is no longer exposed;
    • pending torrents are hidden;
    • RSS and scrape require a passkey.
  • Tracker: upload credit is capped by elapsed time, left=0 no longer bypasses the minimum ratio, and peers are bound to their owner.
  • Atomic operations: invites, registration, login challenges and proof of work can no longer be reused or raced.
  • Infrastructure:
    • no more default credentials (Grafana admin/admin, tracker/tracker);
    • data services are bound to localhost in the local compose files;
    • passkeys are stripped from Caddy logs;
    • Node 22;
    • dependency updates: 71 → 28 advisories, none high or critical in runtime code.

⚠️ Upgrading from 0.5.x

  1. Rotate NUXT_SESSION_PASSWORD. Old session cookies never expire and still contain the passkey; changing the secret logs everyone out once.
  2. Required secrets:
    • docker-compose.prod.yml now refuses to start when DB_PASSWORD, REDIS_PASSWORD, NUXT_SESSION_SECRET, IP_HASH_SECRET or GRAFANA_ADMIN_PASSWORD is missing.
    • IP_HASH_SECRET must be random and at least 32 characters long; otherwise IP hashing fails in production.
  3. Grafana: if it still uses admin/admin, change the password (an existing volume keeps the old one).
  4. New optional variables (see .env.example): TRUSTED_PROXIES, TRUST_CLOUDFLARE, TRACKER_TRUST_PROXY, TRACKER_MAX_RATE_MIBPS.
  5. Removed: ADMIN_API_KEY is no longer used.
  6. Behaviour changes:
    • RSS feeds need ?passkey=;
    • the panic button asks for the panic password;
    • uploaders seed the .torrent downloaded from the site.
  7. Database: new columns and tables are applied automatically at startup (drizzle-kit push).
  8. Bonus shop: create your items in Admin → Bonus & Shop. The shop starts empty.
git pull
docker compose -f docker-compose.prod.yml build app
docker compose -f docker-compose.prod.yml up -d

Summary by CodeRabbit

  • Chores
    • Updated the package version to 0.6.0. No user-facing feature or behavior changes are specified in this release.

What's Changed

  • Fix branding by @IkiaeM in #41
  • fix(security): address security audit findings by @florianjs in #50
  • fix(torrents): keep downloaded info hash in sync with the tracker by @florianjs in #51
  • feat(torrents): external media ids, custom name and announce url in upload by @florianjs in #52
  • feat(torrents): external media ids, custom name and announce url in upload by @florianjs in #53
  • feat(i18n): translate the front-end (english, french) by @florianjs in #54
  • feat(bonus): bonus points, shop, avatars and bounties by @florianjs in #55
  • chore(release): v0.6.0 by @florianjs in #56

Full Changelog: v0.5.7...v0.6.0