• ipx-web 1.3.0 Stable

    rays released this 2026-10-23 09:41:57 -07:00 | 9 commits to main since this release

    Fixed

    • An item opens from the keyboard and with a screen reader: its title is a button. The feed list's rows and the Directory's shows are links to a screen reader, the open one marked current (#298).
    • An item's Play, Download and Delete buttons show while the keyboard is on one, as they do under the pointer (#299).
    • A screen reader names an item's read button for what it does, Mark read or Mark unread, not "●" (#300).
    • The player's position slider has a name, and a screen reader reads where you are as a time, "12:30 of 45:00" (#301).
    • Placeholder text is in the theme's own hint colour, readable in every theme, and the search and feed filter boxes have names of their own (#302).
    • A screen reader reads toasts out, and an error stays until you dismiss it with its x; no more than four show at once (#303).
    • Error messages say what to do, for a server error, a lost connection, a file that would not play or a download that failed, in place of the browser's or the server's own words (#304).
    • Text boxes, selects and switches have an edge you can see in every theme, and a box with the keyboard in it has the same ring as every other control (#305, #308).
    • Dialogs are dialogs to a screen reader, named by their heading. The page behind one is out of reach while it is open, and closing it puts the keyboard back where it was (#306).
    • The boxes in Add a feed, Settings, Download latest and OPML are named by their labels, and clicking a label puts the cursor in its box (#307).
    • With reduced motion on, a check for new items still shows: the refresh button pulses and says "Checking for new items", spinners pulse, and toasts and sheets fade in (#310).
    • On a phone, a tapped button, feed or Directory category no longer stays shaded or fanned out as if it were selected (#311).
    • Scrolling to the end of a dialog or the phone's feed list no longer scrolls the page behind it (#312).
    • Cover artwork has a faint edge, so a dark cover stands off a dark theme (#313).
    • The tab bar's corners follow the tabs inside it (#314), and the Directory's covers fan out smoothly (#315).
    • A feed's page drops an error once a later check succeeds, and its item count and when it was last checked stay current, instead of keeping what they were when you opened it (#316).
    • Settings shows iPX's and the page's versions at its foot: the logo's tooltip was out of reach of a keyboard and of a phone (#309).

    Security

    • Open the original, an episode's View in a new tab, the Directory's item links and the v key follow a link only when it is a web address. A podcast's javascript: or data: link was followed as it was (#326).
    • TRUSTED_HEADER names ipx's trusted_header when it is not Cloudflare's, and ipx-web drops that header from anyone but TUNNEL_PEER too. Only Cloudflare's were dropped, so with another header anyone could sign in as anyone (#323).
    Downloads
  • rays released this 2026-10-23 09:41:57 -07:00 | 9 commits to main since this release

    Fixed

    • A WordPress.com site that answers its feed with a browser check (HTTP 403) is read from WordPress.com's API instead of failing (#317).

    Security

    • HTTPS connections no longer trust certificates from emSign's distrusted intermediates, and certificate checks use constant-time comparisons: rustls-webpki, webpki-roots and ctutils are updated (#351).
    • The public pages read the list from the database at most once a minute, however many people ask. Each page asked for the whole catalogue, so a flood of requests with query strings of their own reached the database every time (#341).
    • The directory no longer fetches feeds at internal addresses (loopback, the LAN, Docker's networks), named in a snapshot or reached by a redirect, unless directory.toml's fetch_internal lists them. It fetched them, and stored what answered as the feed's title and description (#329).
    • A server's count of a feed's subscribers is taken up to a million. Two servers sending the largest number there is made the sum overflow, and every listing and page failed until one was dropped (#342).
    Downloads
  • v1.5.0 0be8eb5cdf

    ipx 1.5.0 Stable

    rays released this 2026-10-23 09:41:57 -07:00 | 9 commits to main since this release

    Changed

    • Traces show more of where a request's time goes: a page of items' query and its files apart, artwork's cache, check and fetch, the status counts, and each part of changing or leaving a feed (#350).
    • A page of items finds its files by feed as well as item: it read every file's row in the database, about a quarter of a second a page (#344).
    • A page of items asks for its count beside the items, and the feed list asks its five questions at once, where each waited for the one before (#346).
    • A Signal's counts of items and of unread ones are worked out in one pass, not two (#348).
    • Artwork kept on disk is read and written off the threads that answer requests, and two requests for the same missing artwork fetch it once (#345, #349).
    • Unread lists and counts start from each person's oldest unread item in each feed, which the daily cleanup works out, instead of reading the whole back catalogue and everything you have read (#347, #352).

    Fixed

    • A WordPress.com site that answers its feed with a browser check (HTTP 403, "Checking your browser...") is read from WordPress.com's API instead, so Pelgrane Press's feed no longer fails for hours at a time. The items are the ones the feed gave: same ids (#317).

    Security

    • An episode that comes as a torrent downloads into a folder of its own, torrent-<id> in its podcast's folder. A torrent could name a path anywhere on the server for Delete, the cleanup and playback to act on, and could overwrite other episodes' files of the same name (#318, #331).
    • A downloaded file opens in the browser only when it is audio, video, an image other than SVG, a PDF or plain text, and is saved otherwise. An SVG or web page a podcast sent ran its script as iPX, signed in as whoever opened it (#319).
    • An OPML nested more than 100 levels deep is refused, uploaded or fetched. A deep enough one stopped iPX, and a subscribed one stopped it again each time it restarted (#322).
    • A .torrent file larger than 10 MB, or slower than the torrent stall limit, is refused. iPX read one into memory however large it was (#330).
    • Feeds, episodes, artwork and .torrent files are no longer fetched from internal addresses (loopback, the LAN, Docker's networks), redirects included, unless config.toml's fetch_internal lists them. Adding a feed could read what a service inside the network answered (#320).
    • HTTPS connections no longer trust certificates from emSign's distrusted intermediates, and certificate checks use constant-time comparisons: rustls-webpki, webpki-roots and ctutils are updated (#351).
    • A new install's admin gets a random password, written to admin-password beside config.toml and readable by iPX's user alone, or the one in IPX_ADMIN_PASSWORD. Every install began as admin / ipodderx, a password published in the README, and the log printed it (#321).
    • A show kept from a private OPML or Patreon list stays private, with the list's username and password, once the list is removed or left. It became public and was shared to the directory (#332).
    • A feed's username and password go to its own host alone: not to its episodes on other hosts, nor to the feeds an OPML lists on other hosts, which took the OPML's password on every check (#327, #328).
    • A check of one feed asks at most eight hosts whether its artwork is on https. A feed could name artwork on as many hosts as it liked, each asked in turn for up to 20 seconds, and hold up every other feed's check for hours (#339).
    • An OPML or Patreon list may bring in up to 2,000 feeds; one with more shows an error and adds none. A list of tens of thousands held up checking for everyone, and adding its feeds read the whole feeds table once for each (#337).
    • A request that changes something is refused when a browser sent it from another site. A page on another site, a sibling subdomain included, could mark everything read, start downloads, subscribe you to a Directory feed or sign you out (#336).
    • ipx user passwd signs the account out of every browser, and says how many of its API tokens still work. A session signed in with the old password went on working (#334).
    • Live updates about a feed go only to the people who read it, and admins. Everyone signed in had every feed's, errors included, which carried a paid feed's address with its key (#325).
    • An open page stops getting live updates within half a minute of its account being removed. They went on until the page was closed (#335).
    • Only someone subscribed to a feed, or an admin, may mark it private. Anyone signed in could keep anyone's feed, or a whole OPML's, out of the directory, and only an admin could undo it (#333).
    • An OPML upload may add up to 2,000 feeds; one with more is refused and adds none. Importing tens of thousands held up every change to the feed list for minutes and left them all in it (#338).
    • Password checks stay a few at a time when the person signing in gives up before the answer. Each sign-in that hung up let another start, so a flood of them used every core (#324).
    • Jev picks at most 20 icons an hour for each person, on the server's key; past that the page says to choose one by hand. Anyone signed in could have it pick without end, on the server's bill, holding back everyone's Signals (#340).
    • Each person's Signals on an item are judged in a call of their own, on the server's key too. One person's description was in the question that decided another's verdicts (#343).
    Downloads
  • ipx-web 1.2.0 Stable

    rays released this 2026-10-19 11:40:00 -07:00 | 47 commits to main since this release

    Added

    • A search box has an x at its right end once something is typed in it, which clears it: items, the feed list, the log in Admin and a Signal's icons (#291).
    • A feed's, an OPML subscription's or a Patreon creator's settings have In All Subscriptions: off keeps its items out of All Subscriptions and its unread count, still there on its own page, in Signals and in Currently Listening (#288).
    • A feed's settings have a Signals switch beside All Subscriptions, to keep its items out of every Signal (#289).
    • An item sent as both HTML and Markdown, as Scripting News's are, has a choice beside its buttons to show it as the publisher's HTML or as the Markdown, kept from one item to the next (#285).
    • A show inside an OPML subscription has a Keep button, a plus, on its page, so it stays on your list as a show of its own if the OPML drops it or you unsubscribe from the OPML (#280).
    • Admin, Server: a setting to give everyone Signals on the server's TypeSafe key (#271).
    • Admin, Server: how many days back a new Signal reads (#276).

    Changed

    • A feed's settings are in parts, each named beside its controls: Address, Downloads, Playback, Where it shows and Directory, with All Subscriptions and Signals drawn as the sidebar draws them, and DeadAir's pause as a slider without a heading (#290).
    • An OPML subscription's page lists the items of all its shows together, newest first, with the same tabs, search and sort as a show's, in place of a list of the shows; the shows are still in the folder in the feed list (#283).
    • Unless the server pays for them, Signals are turned on in Settings with your own TypeSafe key, and the Signals folder shows only once they are on (#271).
    • A Signal's dialog says how far back it reads, and that an edit reads again only what was picked out (#276).
    • Each request's span in Tempo is named for its method and path, such as GET /api/entries, instead of ipx-web for every one (#286).

    Fixed

    • Another person's download, its progress and its failure, no longer shows on your page (#294).
    Downloads
  • rays released this 2026-10-19 11:40:00 -07:00 | 47 commits to main since this release

    Added

    • A feed's items written in Markdown show formatted on its page, from a Markdown description or RSS's <source:markdown> (#284).

    Fixed

    • A listed feed whose address serves something larger than 50 MB is refused as too large, instead of read whole into memory at every check (#295).

    Security

    • ammonia, which cleans publishers' HTML, updated to 4.2.4 for three advisories, among them XSS through SVG animation tags; rustls to 0.23.46 for five and h2 to 0.4.20 for one (#281).
    Downloads
  • v1.4.0 5bad68670a

    ipx 1.4.0 Stable

    rays released this 2026-10-19 11:40:00 -07:00 | 47 commits to main since this release

    Added

    • An item whose feed sends Markdown beside its HTML, as Scripting News does with <source:markdown>, keeps it: markdown and markdown_html in the API's items (#285).
    • An item written in Markdown shows formatted, not as Markdown's raw characters: a description in Markdown, or, with no other text, RSS's <source:markdown>. HTML a feed sends is left as it is (#284).
    • A show from an OPML subscription or a Patreon creator can be kept: kept on PATCH /api/feeds/{id} and in the feed list. When the OPML drops a kept show, or you leave the OPML, it stays on your list as a feed of its own (#280).
    • /metrics counts Signals: items judged and fitting, calls to Jev by how they ended, the time they took and the tokens TypeSafe counted, by person and by whose key paid so the server's bill can be split, time since the judge's last pass, and keys refused; a failed call to Jev shows as a failed trace (#270, #275, #278).
    • An admin setting for how many days back a new Signal reads (#276).
    • A list's trace says which filter, sort and page it was asked for, and whether a search, so a slow list can be told from the others (#287).
    • A feed, an OPML subscription or a Patreon creator can be left out of All Subscriptions: hide_from_all on PATCH /api/feeds/{id} and in the feed list. Set on an OPML or creator it covers every show in it; Signals and Currently Listening still read them (#288).
    • A feed, an OPML subscription or a Patreon creator can be kept out of Signals: hide_from_signals on PATCH /api/feeds/{id} and in the feed list. Jev is not asked about its items, so they cost nothing, and they are left out of each Signal's list and counts (#289).
    • An admin setting, Signals for everyone on the server's TypeSafe key, so the server pays for Jev instead of each person (#271).

    Changed

    • GET /api/feeds/{id}/entries for an OPML subscription or a Patreon creator lists the items of the shows in it that you subscribe to, together, where it listed nothing (#283).
    • A TypeSafe key is checked with TypeSafe before it is saved, and one it refuses is not saved (#271).
    • A new Signal reads the last week instead of the last 30 days, unless an admin sets otherwise (#276).
    • Editing a Signal's name, words or description asks again only about what it had picked out, and about new items as they come, instead of the whole window again (#276).
    • Signals fill faster and cost less: up to ten calls to TypeSafe at once instead of one, paced under TypeSafe's limits of 80 calls and 100,000 input tokens a second, with every call held back while TypeSafe answers 429 (#277), everyone's Signals on an item in one call on the server's key, and an item's text cut at 1,000 characters instead of 2,000 (#275).

    Fixed

    • Artwork comes quickly: an image already kept is served without asking the database again, and the database finds which feed names an image by an index instead of reading every item, which took over half a second an image (#272).
    • The Directory shows the artwork of podcasts nobody on this server subscribes to, where it drew their initials (#273).
    • Artwork a publisher sends without an image type, or as application/octet-stream, is shown when it is a JPEG, PNG, GIF or WebP, instead of initials (#279).
    • Looking for items to read for Signals read every item on the server on each scan; it now reads only recent ones (#274).
    • With the downloads folder out of reach during a clean-up, as when the array stops, every downloaded episode was taken as deleted by hand and forgotten; the clean-up now leaves them alone until the folder is back (#293).
    • A feed address that serves something larger than 50 MB, such as an episode's file given as a feed, is refused as too large, instead of read whole into memory at every check (#295).
    • Searching items for % or _ finds those characters, instead of treating them as wildcards that matched nearly everything (#296).

    Security

    • ammonia, which cleans publishers' HTML, updated to 4.2.4 for three advisories, among them XSS through SVG animation tags; rustls to 0.23.46 for five and h2 to 0.4.20 for one, in every connection ipx makes (#281).
    • The address of a file being downloaded, which for Patreon carries its signature, is sent to open pages and written to the log without its query, as other addresses already were (#292).
    Downloads
  • rays released this 2026-10-16 13:37:33 -07:00 | 97 commits to main since this release

    Added

    • Answers and pages go out compressed, brotli, zstd or gzip as the caller takes them: the feed list ipx asks for was 603 KB of JSON. A snapshot may come gzipped, /metrics answers gzipped, and with OTEL_EXPORTER_OTLP_COMPRESSION=gzip traces go to the collector compressed (#253).
    • With apple_country set, Apple Podcasts' top charts for that country (the top 100 and the top 50 of each category) come into the directory every week, beside what servers share, without counting as subscribers; and a warning says when Apple's categories no longer match ipx's (#252).

    Changed

    • Each feed is checked every twelve hours instead of six (#243).
    • Feeds are fetched accepting brotli and zstd as well as gzip (#244).
    • On Postgres the server keeps all ten of its database connections open, so a request does not wait for a new one (#241).
    Downloads
  • ipx-web 1.1.0 Stable

    rays released this 2026-10-16 13:37:33 -07:00 | 97 commits to main since this release

    Added

    • Signals pick what matters out of the noise of every feed you subscribe to: New signal takes a name, the words to listen for and, if those are not enough, a sentence saying what you mean, and its page lists the items from your feeds that are about it, read and unread as in their own feeds. Settings takes your TypeSafe key, which Signals need, and a Signal without one links to typesafe.ai to get one and to the key's place in Settings (#254, #266). They are kept in a Signals folder first in the feed list, under All Subscriptions, closed or open as an OPML is, with its own page listing them and a + there for a new one (#255, #256, #265). Each can have an icon of its own, searched for among all of Font Awesome Free, in place of its initials (#261), or one picked for it with Auto, which a Signal made without an icon gets by itself; each Signal's row counts its items and unread as a feed's does (#263).
    • A list opens at once when you have seen it before or the page fetched it ahead: All Subscriptions and the feeds with something unread are fetched when the page loads, and a feed or filter as the pointer or a finger reaches it, then refreshed behind once shown. A list that has to be waited for shows a spinner instead of nothing (#247). Currently Listening and the Directory's front page are fetched ahead the same way and open at once (#248).

    Changed

    • The page reports how long each list you open takes to show, from the click to the list drawn, for the dashboard (#246).
    • The page's files are compressed once when built, brotli at its strongest and gzip, and sent in place of the files: the script 30 KB where it was 37, the stylesheet 11 where it was 14. Traces go to the collector compressed (#253).
    • The page and the API's answers are sent compressed, zstd or gzip, which the feed list and item lists, over 100 KB each, were not; live updates and audio are not compressed (#239).
    Downloads
  • v1.3.0 47ad68c7da

    ipx 1.3.0 Stable

    rays released this 2026-10-16 13:37:33 -07:00 | 97 commits to main since this release

    Added

    • Signals: a feed of your own, picked out of the noise of everything you subscribe to, holding the items TypeSafe's Jev says are about the subject you give it: a name, words, and a sentence of your own if they are not enough, from the last 30 days and every new one, judged on your own TypeSafe key, each with an icon of its own if you like, which Jev can pick on the server's TypeSafe key (POST /api/signals/icon) (/api/signals, and typesafe_key on /api/me) (#254).
    • With OTEL_EXPORTER_OTLP_COMPRESSION=gzip, traces go to the collector compressed; /metrics answers gzipped, and a snapshot goes to the directory gzipped (#253).
    • A Directory request's trace shows the call to the directory whole, with the size of its answer, and the steps that match it against your subscriptions (#250).
    • The page's report of how long a list took to show after a click (list_shown, with the view and filter) is logged under that click's trace (#246).

    Changed

    • A feed that sends the same body again, as Patreon and Substack do whatever they are asked, is taken as unchanged instead of read again, and, without a schedule of its own, checked less often the longer it stays the same, up to every four hours, back on schedule when it changes (#242).
    • Feeds are fetched accepting brotli and zstd as well as gzip (#244).
    • On Postgres the daemon keeps all twenty of its database connections open, so a page load no longer waits for new ones, 80-330 ms each: the feed list and item lists took 0.3-1.6 s now and then, where their queries take 5-30 ms (#241).
    • Currently Listening and the Pinned filter answer in a few milliseconds: they read every item on the server, 1.3 s for Currently Listening (#249).
    Downloads
  • ipx-web 1.0.2 Stable

    rays released this 2026-10-15 06:25:18 -07:00 | 133 commits to main since this release

    Fixed

    • The refresh buttons turn from the moment they are pressed until the scan they asked for has finished, smoothly, instead of jerking back upright between one feed and the next (#231, #233).
    • A feed's unread count stays put while a scan checks it quickly; the spinner takes its place only when a check takes a moment (#232).

    Security

    • The ipx-web image no longer carries curl, which Caddy's base image shipped and nothing used: 8.22.0 there is affected by CVE-2026-92392 (#237).
    Downloads