Skip to content

Releases: ib0ndar/Torrentinel

Torrentinel 1.0.1

Choose a tag to compare

@ib0ndar ib0ndar released this 26 Oct 14:01

Torrentinel 1.0.1 makes tracker checks faster and lighter and fixes two monitoring bugs. Updating needs no configuration change: the database gains three columns automatically, and the first poll after the update silently refreshes the saved state of releases watched by link, without notifications.

Faster polls. Kinozal, Rutor and RuTracker are checked side by side instead of one after another, so a poll takes about as long as the slowest tracker, and a slow tracker no longer holds up the others. Each tracker still gets one request at a time. If checking one tracker fails unexpectedly, the others still finish.

RuTracker topics watched by link. A scheduled poll opens a topic in the integrated browser only when the RuTracker feed lists it with a new update time or a different torrent since its page was last loaded. Every topic is still loaded at least once a day, after any gap in the feed, and whenever you press Check now. Administration › Diagnostics shows a skipped page as "Unchanged in feed". The feed is now also read for users who only watch topics by link.

RuTracker rules. A poll reads the feed and the 14-day release buffer once instead of once for every rule group (with 20 rule groups, about 0.9 s became 0.05 s on a desktop computer). When the feed cannot be read, the error is reported on every rule without requesting the feed again for each of them.

Feed gaps. A gap in the RuTracker feed no longer stays open, with every rule searching again on every poll, because one rule cannot catch up. A rule whose owner has no RuTracker login, or whose catch-up search needs more pages than it reads, reports that on the rule instead. Rules that already caught up skip their search, and new rules skip it entirely. A gap is also no longer missed when a topic updated during an outage appears in the feeds before and after it.

Mirrors. Switching a tracker's mirror no longer reports every release watched by link as changed, and the Tracker page and Torrent file links move to the new mirror at the next check.

Integrated browser. Chrome now closes after 10 minutes without a request instead of running between polls, and starts again with the same profile, cookies and sign-ins. The new optional BROWSER_IDLE_TIMEOUT_MS sets the idle time; a value above the poll interval keeps browsers open between polls.

Smaller fix. Collections created within the same millisecond are always listed in the order they were created.

Container images are available for linux/amd64 and linux/arm64 as bah0/torrentinel:v1.0.1 and latest.

Validation: 324 automated tests, run locally and in both architecture image builds, a typechecked production build, release metadata validation, and an upgrade of a 1.0.0 database followed by stubbed polls (no notifications on the silent refresh, then pages skipped as unchanged in the feed). A rollback from that database to 1.0.0 was also checked. GitHub CI failed on the release commit because two new scheduler tests requested the real RuTracker feed; the follow-up commit 2acb417 stubs it, changes only those tests, and passed CI.

Both published architecture images passed isolated container checks covering image labels, the health response and the Docker health check, the web interface, robots.txt and the noindex header, and first sign-in with the required password change. A rootless Podman installation upgraded from 1.0.0 kept its data intact, with a passing integrity check and unchanged row counts. Its first poll refreshed the saved state of five releases watched by link without notifications. Its next scheduled poll took 36.3 s instead of about 44 s, skipped all four RuTracker topic pages as unchanged in the feed, and matched RuTracker's 30 rule groups in 0.1 s instead of 2.5 s. Chrome had closed between the two polls, and Kinozal needed no new sign-in after it started again. No errors were logged.

Torrentinel 1.0.0

Choose a tag to compare

@ib0ndar ib0ndar released this 25 Oct 21:15

Torrentinel 1.0.0 reworks the web interface. Monitoring, notifications, the API and the database are unchanged, so updating needs no configuration change.

Sign-in. The language switch sits in the corner instead of inside the form, and the page opens in the language last used in that browser or the browser's own. A rejected sign-in is shown in the form above the button and clears the password field for the next try. The password field has a show/hide button, and the Sign in button keeps a readable label and shows a spinner while it works.

Type and layout. The interface ships its own typeface, Inter, instead of falling back to whatever the system has, with one scale of seven sizes and nothing smaller than 12 px. Secondary text and every badge reach at least 4.5:1 contrast in all eight themes. Every page shares one frame, so titles no longer jump when you switch pages, and form labels share one style.

Monitor. Only states worth a look get a badge (Needs attention, Learning, Paused); rows that are simply being watched no longer repeat a green "Watching". Unread rows have an accent edge, read titles step back to grey, rule phrases read as titles rather than buttons, and a subscription that needs attention says why under its title instead of repeating its tracker address. A collection's Edit and Delete sit next to its name. An empty collection shows only a hint, and a search without results offers Clear search.

Subscription pages have a breadcrumb back to the Monitor and the collection, use the same words as the list, and move a subscription to another collection from Edit without starting a new baseline. An address that no longer exists says so once, with a way back.

Settings is split into tabs with their own addresses: Account, Preferences, Telegram bot and Tracker access. Older /settings#section links open the right tab. Every password and token field, including tracker logins and the Telegram bot token, has a show/hide button.

Administration. Diagnostics names outcomes and operations in words in English and Russian, shows routine results in grey, and turns log and delivery rows into cards on phones. The Users table only marks disabled accounts and pending password changes, and the polling interval readout sits under its label.

Smaller changes. English counts use the singular for one ("1 subscription"). The browser tab shows the page and the unread count, for example "(3) Series 2026 · Torrentinel". robots.txt and an X-Robots-Tag: noindex, nofollow header keep an instance that is reachable from the internet out of search engines. The container build runs its tests with 6 workers instead of 2.

No configuration or database schema changes. Container images are available for linux/amd64 and linux/arm64 as bah0/torrentinel:v1.0.0 and latest.

Validation: 297 automated tests, run locally and in both architecture image builds, a typechecked production build, a layout check of every page at five widths and in Russian (84 page checks), a text contrast scan of 14 pages in all eight themes, and release metadata validation.

Both published architecture images passed isolated container checks covering the health response and the Docker health check, the web interface and its styles, robots.txt and the noindex header, and first sign-in with the required password change. GitHub CI passed. A rootless Podman installation upgraded to 1.0.0 kept its data intact, with a passing integrity check and unchanged row counts, and completed a full poll of all three trackers without errors.

Torrentinel 0.9.9

Choose a tag to compare

@ib0ndar ib0ndar released this 25 Oct 16:32

Torrentinel 0.9.9 is a security release. Updating is recommended for every installation, especially those with more than one account.

Tracker pages are now always requested from the tracker's configured mirror: a direct subscription's address supplies only the page's path and query. Some subscription addresses could previously make the server request a different host, including addresses on the local network. The integrated browser now trusts only the tracker's own domains and the mirror each request is made for. Existing subscriptions need no change.

Sign-in no longer locks an account for everyone after repeated failures from different addresses. From 10 failures within 15 minutes, attempts on the account wait their turn, 1 second apart and doubling up to 10 seconds, so the right password still gets in after a short wait while guessing stays at about 100 attempts per account in 15 minutes. The limits per address are unchanged.

GET /api/health, which answers without signing in, now returns only {"status":"ok","database":"ready"} and queries the database. Monitoring that read its scheduler fields should use Administration or the signed-in GET /api/system/status. The supplied Docker, Compose and Quadlet health checks need no change.

Fastify 5.12.7, undici 8.12.3 and Zod 4.6.7 include upstream security fixes.

No configuration or database schema changes. Container images are available for linux/amd64 and linux/arm64 as bah0/torrentinel:v0.9.9 and latest.

Validation: 286 automated tests, run in both architecture image builds, a typechecked production build, and release metadata and Compose validation.

Both published architecture images passed isolated container checks covering the health response, first sign-in and password change, tracker addresses staying on the mirror, the integrated browser refusing a host it was not given, and the integrated-browser sandbox. GitHub CI passed. A rootless Podman installation upgraded from 0.9.8 kept its data intact and completed a full poll of all three trackers without errors.

Torrentinel 0.9.8

Choose a tag to compare

@ib0ndar ib0ndar released this 14 Oct 08:51

Torrentinel 0.9.8 adds a Subscription button to Telegram release notifications alongside Tracker page and Magnet (or Torrent file). The button opens the direct or rule subscription's details, configuration, and change history, retaining the destination through sign-in. English and Russian labels are supported.

Links use the existing PUBLIC_URL setting, supporting deployment domains, IP addresses, and custom ports. Set it to the HTTP or HTTPS address reachable from your Telegram device and restart Torrentinel. When PUBLIC_URL is unset, the Subscription button is omitted. Deleted or inaccessible subscriptions show a clear error.

No database schema changes. Container images are available for linux/amd64 and linux/arm64 as bah0/torrentinel:v0.9.8 and latest.

Validation: 280 automated tests, a typechecked production build, release metadata and Compose validation, and 66 responsive layout checks including direct and rule subscription pages in English and Russian.

Both published architecture images passed isolated container checks covering the subscription button payload, direct and rule pages, sign-in destination, reload, and integrated-browser sandbox. GitHub CI passed.

Torrentinel 0.9.7

Choose a tag to compare

@ib0ndar ib0ndar released this 04 Oct 10:33

Torrentinel 0.9.7 lets each account choose where it starts and how each collection opens.

Choose a start page under Settings → Start page: Monitor, which opens your last used collection, or Activity, which opens unread changes across all collections. It opens for the main address and for unknown addresses, so it is what you see after signing in at the main address, after the first password change, and when the home-screen app starts. Addresses of a specific page, bookmarks and Back/Forward still open that page, and /collections always opens Monitor. Signing out now returns to the main address, so the next sign-in opens the start page; when a session expires or is ended elsewhere, the address is kept so signing back in resumes there.

Each collection now has a default view: All, Unread, or Errors. Set it when creating a collection or with Edit collection, which replaces Rename and offers the name and the default view together. A collection opens in its default view from the collection list, from the main address and the Monitor link, right after it is created, and when it replaces a deleted collection. Search and sort still carry over between collections, selecting the collection that is already open keeps its current view, and changing a default never changes the view on screen. An empty Unread or Errors view now says there is nothing unread or nothing needing attention and offers Show all.

Upgrade notes: opening another collection now uses that collection's default view instead of keeping the current status filter. Startup adds users.start_page and collections.default_filter with defaults that keep today's behaviour (Monitor, and All for every collection); 0.9.6 ignores both columns, so it still runs against an upgraded database. The API adds startPage to PUT /api/settings/preferences and the signed-in user, and defaultFilter to GET, POST and PATCH /api/collections. Back up the database and application data together before upgrading.

Validation: 267 automated tests, run in CI and inside both the linux/amd64 and linux/arm64 image builds, a typechecked production build, and the npm run check:ui layout check (54 page checks, including an empty Errors view in English and Russian). Both published images passed a fresh-install browser smoke test that sets a collection's default view, checks that collection links open in it while the open collection keeps its view, chooses Activity as the start page, and confirms that the main address, an unknown address and the next sign-in after signing out open it, in addition to the earlier first-run, host-name and integrated-browser checks.

Container images are provided for linux/amd64 and linux/arm64 under bah0/torrentinel:v0.9.7 and latest.

Torrentinel 0.9.6

Choose a tag to compare

@ib0ndar ib0ndar released this 04 Oct 09:12

Torrentinel 0.9.6 removes the last known way to take over a new installation.

There is no default admin/admin password any more. On first start Torrentinel creates the account admin with a random password, saves it in initial-admin-password in the application-data directory (readable only by Torrentinel's user), and prints it in the log line starting "First sign-in:" until it has been changed. Set INITIAL_ADMIN_PASSWORD to choose it instead. The file is deleted after the first password change. An existing installation that nobody has signed in to yet has its admin/admin password replaced the same way at startup, and any session that used it ends. The README shows how to read the password for each installation method.

Torrentinel now answers only requests addressed to an IP address, a single-word or local-only name (.local, .lan, .home, .home.arpa, .internal, .localdomain), the host of PUBLIC_URL, or a name in the new ALLOWED_HOSTS setting; other names receive HTTP 403 and a log warning. This stops DNS rebinding, where a web page reaches an installation on the visitor's network, for example to try passwords, under the attacker's own domain name.

The supplied Docker Compose file and Podman Quadlet now publish Torrentinel on the local machine only. Set TORRENTINEL_BIND_ADDRESS=0.0.0.0 in .env (Compose) or PublishPort=8999:8080/tcp (Quadlet) to open it to other devices.

Upgrade notes: if you open Torrentinel under a domain name that is not the host of PUBLIC_URL, for example through a reverse proxy, add it to ALLOWED_HOSTS before updating. IP addresses and names such as nas or nas.lan keep working. Docker Compose users who reach Torrentinel from other devices should set TORRENTINEL_BIND_ADDRESS. Accounts that have already changed their password are unaffected, and there is no database change. Back up the database and application data together before upgrading.

Validation: 255 automated tests, run in CI and inside both the linux/amd64 and linux/arm64 image builds, a typechecked production build, and the npm run check:ui layout check (48 page checks). Both published images passed a fresh-install browser smoke test that signs in with the generated password, confirms admin/admin is rejected and the password file is deleted after the change, and checks that a foreign host name is refused while addresses and local names are served.

Container images are provided for linux/amd64 and linux/arm64 under bah0/torrentinel:v0.9.6 and latest.

Torrentinel 0.9.5

Choose a tag to compare

@ib0ndar ib0ndar released this 04 Oct 08:15

Torrentinel 0.9.5 is a security release. Upgrading is recommended for every installation, especially those with more than one account.

Personal tracker mirrors are now limited to the tracker's own domains (for example rutracker.net) and the global mirror. Previously any signed-in account could point a personal mirror at any address and make the server request pages on the local network, then read part of the response. A stored personal mirror that is no longer allowed is ignored and the global mirror is used instead; administrators can still set any global mirror, including one on the local network. This also stops an account from feeding made-up RuTracker search results into the release buffer that all accounts' rules share.

The integrated browser now starts Chrome with its sandbox. The supplied Compose file applies a seccomp profile (deploy/torrentinel-seccomp.json, Docker's default plus user namespaces) that makes this possible; Podman's default profile already allows it, so the Quadlet is unchanged. The log says "The integrated browser runs Chrome with its sandbox." when it works and warns when it falls back; BROWSER_SANDBOX=true refuses to run without it. Independently of the sandbox, the browser only opens pages on the tracker's own domains, cannot open further windows, and connects only through a proxy inside Torrentinel that resolves host names itself and refuses local and private network addresses for everything except the tracker, including frames, workers, service workers, WebSockets and WebRTC.

Cover art is downloaded only from public internet addresses, checked for every redirect and again when connecting, unless it comes from the release page's own host. Tracker sessions send cookies only to the site that set them, refuse redirects to local addresses and form re-submission to another host, and stop reading responses above 20 MB. Magnet and torrent links read from tracker pages are kept only when they are real magnet or http(s) links.

Sign-in is limited after repeated failures (HTTP 429 with Retry-After), as are current-password guesses on the password change form, and unknown or disabled accounts take as long to reject as a wrong password. Behind a reverse proxy, set the new TRUST_PROXY to the proxy's address so the limits apply per client. State-changing requests from other sites are rejected. Disabled accounts' subscriptions are no longer checked, Telegram bot tokens must have BotFather's format, and the server warns when PUBLIC_URL uses HTTPS without SESSION_COOKIE_SECURE=true. Fastify is updated to 5.12.5.

Upgrade notes: there is no database change, and 0.9.1 runs unchanged against the same data. Docker Compose needs deploy/torrentinel-seccomp.json from the same checkout, which the documented update provides. Personal mirrors outside the tracker's domains stop being used; ask an administrator to set such a mirror globally. Back up the database and application data together before upgrading.

Validation: 250 automated tests, run in CI and inside both the linux/amd64 and linux/arm64 image builds, a typechecked production build, and the npm run check:ui layout check (48 page checks). Both published images passed a fresh-install browser smoke test, which now also confirms that the integrated Chrome reports itself sandboxed, cannot reach a local address or leave the tracker, and that cross-site requests and disallowed personal mirrors are refused.

Container images are provided for linux/amd64 and linux/arm64 under bah0/torrentinel:v0.9.5 and latest.

Torrentinel 0.9.1

Choose a tag to compare

@ib0ndar ib0ndar released this 04 Oct 06:14

Torrentinel 0.9.1 makes sign-in and password changes clearer and fixes several smaller interface issues found after 0.9.0.

When an administrator resets your password or disables your account, or you change your password in another browser, the signed-out browser now says what happened (for example "An administrator reset your password. Sign in with the temporary password you were given.") instead of "Your session has expired". The password change screen also explains why a change is needed: after an administrator reset it says so and asks for the temporary password, and administrators created with a temporary password no longer see the first-run "Secure the admin account" wording.

Back/Forward and reloads return a long collection list to where you were instead of near the top. Closing details opened from an Unread list moves focus to the entry that took its place. With a panel open, Tab also reaches visible notifications, so an error can be read and dismissed without closing the panel. Tracker icons in Diagnostics line up across rows, and the Keyboard shortcuts menu item is hidden on touch-only devices.

This release adds the revoked_sessions table, which keeps the reason a session was ended until it would have expired. Ended sessions are still deleted, and 0.9.0 ignores the new table, so it runs unchanged against an upgraded database. Back up database and application data together before upgrading. API: GET /api/auth/me returns passwordChangeReason while a change is required, and a 401 for an ended session carries code SESSION_ENDED with details.reason.

Validation: 229 automated tests, run in CI and inside both the linux/amd64 and linux/arm64 image builds, a typechecked production build, and the npm run check:ui layout check (48 page checks). Both published images passed a fresh-install browser smoke test, which now also checks the password change reason and that a session ended by a password change reports why.

Container images are provided for linux/amd64 and linux/arm64 under bah0/torrentinel:v0.9.1 and latest.

Torrentinel 0.9.0

Choose a tag to compare

@ib0ndar ib0ndar released this 03 Oct 21:19

Torrentinel 0.9.0 reorganizes Administration, lets you change your own password, and makes the interface easier to use with a keyboard and a screen reader.

Administration is split into Overview, Users, Mirrors, and Diagnostics tabs, each with its own address. Tracker logs and Telegram deliveries are paged instead of showing only the latest 100 records, their filters and pages survive reloads and Back/Forward, and the notification queue and logs show subscription names instead of numeric IDs.

You can now change your own password under Settings → Account, or with Change password in the account menu; other browsers and devices signed in to the account are signed out. Settings opens with shortcuts to each section and says which sections save automatically. Tracker access and mirror rows show Unsaved changes with a Discard action, and Save is only available when something changed.

Notifications stack instead of replacing each other, errors stay until closed, and screen readers announce them. Side panels keep keyboard focus inside and return it when closed. The collection filters show counts. Keyboard shortcuts on Monitor and Activity: / to search, j and k to move between rows, a to add a subscription, and ? for the list. Background refreshes pause while the tab is hidden.

Fixed: the Activity page scrolling sideways on phones, tracker choices spilling out of the subscription forms on phones, long outcome badges in Diagnostics, scroll position carrying over between pages, and saving one tracker row discarding edits in the others.

There are no database changes, and 0.8.0 runs unchanged against the same database. Back up database and application data together before upgrading. New administrator API endpoints: GET /api/admin/diagnostics/observations and /deliveries (paged) and /queue; GET /api/collections adds errorCount.

Validation: 219 automated tests, run in CI and inside both the linux/amd64 and linux/arm64 image builds, and a typechecked production build. A new layout check (npm run check:ui) passed 48 page checks across 8 routes at 320 to 1440 px and in Russian. Both published images passed a fresh-install browser smoke test covering sign-in, Activity, addresses that survive a reload, sorting, the Administration tabs, paged diagnostics, filter counts, the keyboard shortcuts dialog, no horizontal overflow from 320 to 1280 px, and the account menu.

Container images are provided for linux/amd64 and linux/arm64 under bah0/torrentinel:v0.9.0 and latest.

Torrentinel 0.8.0

Choose a tag to compare

@ib0ndar ib0ndar released this 02 Oct 16:06

Torrentinel 0.8.0 adds an Activity view and makes the monitor easier to use on phones.

Activity lists changes across all your collections, newest first and grouped by day. Opening an entry shows its details and marks it read, and Mark all read clears everything at once or one collection at a time. Subscriptions you marked unread appear in their own group, and the sidebar badge always matches what the Unread view lists.

Subscription details now show what changed: the old and new title, and links to the new and previous magnet and torrent file. Rule matches have their own magnet and torrent-file buttons.

The collection list shows the date of the last change and can be sorted by date changed, name, or errors first. The selected collection, filter, search, page, and sort are kept in the address, so reloads, bookmarks, and Back/Forward return to the same view, and opening the app returns to the last used collection.

On phones, status badges such as Needs attention are visible again, collections can be renamed and deleted from a new menu, the collections strip is about half as tall, the bottom bar has an Account item with Sign out, and the Russian sort and search labels fit the toolbar. On all screen sizes, the account control opens a menu instead of signing out immediately, pagination only appears when there is more than one page, and the sign-in form is no longer pre-filled with the default credentials. When a session expires, the app returns to sign-in with one clear message instead of repeated errors.

This release adds one database index for the Activity view, created automatically on startup. There are no table or column changes, and 0.7.0 runs unchanged against an upgraded database. Back up database and application data together before upgrading. New API endpoints: GET /api/activity and POST /api/activity/read; GET /api/subscriptions accepts sort=changed|name|attention.

Validation: 172 automated tests, run in CI and inside both the linux/amd64 and linux/arm64 image builds, and a typechecked production build. Browser checks covered phone, tablet, and desktop layouts in English and Russian and in light and dark themes. Both published images passed a fresh-install browser smoke test: sign-in, the Activity view, addresses that survive a reload, sorting, navigation between pages, no horizontal overflow at 320 to 1280 px, and signing out from the account menu.

Container images are provided for linux/amd64 and linux/arm64 under bah0/torrentinel:v0.8.0 and latest.