LWT 3.4.2: The RSS feed wizard works again
A repair release for the RSS feed wizard, which has not been able to produce a feed since 3.4.0. If you add feeds by pasting a URL and letting the wizard walk you through picking the article, take this one.
The wizard could not save a feed
Two faults sat in the same flow, and either one alone was enough to stop it.
The last step saved nothing. Step 4 posted the finished feed to /feeds/edit. In 3.4.0 that route became a redirect to the feeds manager, when the duplicated server-rendered feeds list was retired — and a redirect discards the body it was sent. So the walk ran to completion, said nothing was wrong, and left no feed behind.
Steps 2 and 3 showed no article to pick from. Those steps render the fetched page so you can click the part that holds the article. The controller handed the view the extractor's whole result where the article's HTML belongs, so the picker showed the word Array — and the "Array to string conversion" notice behind it is fatal wherever PHP warnings are, which on those installs blocked the wizard at step 2 outright.
Both are fixed, and both were present in 3.4.0 and 3.4.1. The manual add a feed tab and the curated-source browser never went through either path and were unaffected — that is why the wizard's state went unnoticed for two releases.
One thing worth having anyway: the fetched article is cached in the session again, as it was always meant to be. Stepping back and forth between steps 2 and 3 refetched the page from the source every time; it now costs milliseconds.
The language on a new text or feed is checked for ownership
Multi-user installs only. texts.TxLgID and news_feeds.NfLgID carry foreign keys to languages, but a foreign key proves the row exists — not that the caller owns it. The form handlers passed the submitted value straight to the facade, so a crafted request could file a text or feed under another user's language.
The API endpoints these forms now use check ownership, and the form-POST routes that skipped the check are retired. Single-user installs were never affected.
The text editor and the feed forms save through the API
Creating or editing a text now uses POST /api/v1/texts and PUT /api/v1/texts/{id}; the feed forms use POST and PUT /api/v1/feeds. Neither text endpoint existed before — TextsApi.create() had been calling a 404 since it was written.
Nothing changes for you in the browser. It matters for the mobile client: both surfaces now work against a configurable API base URL rather than the page origin, which is what a bundled client needs. Two things stay server-rendered on purpose — the editor's Check button, which asks for a parsing report rather than saving, and the wizard's URL steps, which drive a server-side session.
Upgrading is the usual docker compose pull && docker compose up -d --force-recreate. No migration, no first-boot pause. Full detail in CHANGELOG.md.