diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b7f08a..cb9796d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,50 @@ This project uses calendar versioning: `YY.N-stage` (e.g. `26.0-alpha` = 2026, r ## [Unreleased] +### Security + +- **App names are validated everywhere.** `POST /api/apps/remove` with + `{"name": ".."}` or `"/"` sent `shutil.rmtree` at `/var/lib/furtka` or the + root filesystem (and wiping `users.json` reopened first-run admin setup to + the LAN). Names from URLs, JSON bodies and manifests must now match + `^[a-z][a-z0-9_-]*$`; `installer.remove`/`update_env` check it too. +- **Settings can't inject into `.env`.** Line breaks are refused; values + with `$` are single-quoted so compose doesn't expand them (`pa$word` used + to become `pa`). Validation runs before the write, so a rejected `/etc` + path is no longer saved anyway. +- **Damaged `users.json` fails closed.** An empty/corrupt file used to read + as "no admin yet" and turned `/login` into an open create-admin form. + `/login` now answers 503 with SSH recovery steps; `save_users` fsyncs. +- **API server hardening:** threaded (state changes still serialised), 1 MiB + body cap, 30 s socket timeout, cross-site POSTs refused via + `Sec-Fetch-Site`, JSON 500 instead of dropped connections. + ### Fixed +- **Installer disk picker:** SATA SSDs were labelled "HDD" and lost the + recommendation to bigger spinning disks; type now comes from lsblk + `TRAN`/`ROTA`. zram, eMMC boot/RPMB areas, read-only and 0-byte disks are + hidden; disks under 16 GB are greyed out; USB disks rank last; >2 TB disks + on BIOS machines get an MBR warning; the boot stick is also found via the + archiso kernel args when `bootmnt` is gone. Step 2 only accepts a listed disk. +- **Installer runs one install at a time** (double-click / second browser + started a second archinstall on the same disk), and a crashed archinstall + (OOM kill, signal) now shows as an error instead of a progress bar stuck + forever. Disk-probe exceptions land in the log instead of a bare 500. +- **Failed installs can be retried** from the error page without re-entering + everything. +- **No 2-minute boot stall on boards with a second NIC:** the target gets a + `systemd-networkd-wait-online --any` drop-in. +- **Self-update:** symlink flip is atomic; any error after the flip rolls + back (and restores the previous Caddyfile); health check survives read + timeouts; every failure ends in an `error` stage the settings page shows. +- **Interrupted app installs no longer block all later installs** — a stale + state with no live runner is marked failed after 60 s. +- **Catalog sync / update checks** no longer strand on socket resets or disk + full. +- **Apps page after an API restart** redirects to `/login` instead of + showing an empty app list. + - **Self-update starts newly added timers immediately and links units through `current`.** `_link_new_units()` enabled a timer a release introduced but never started it, so after the 26.19 → 26.20 update the @@ -19,6 +61,14 @@ This project uses calendar versioning: `YY.N-stage` (e.g. `26.0-alpha` = 2026, r (installer-created links use `current`). Now: link via `current`, enable, start. +### Changed + +- Wizard wording: "Server name" with a live `http://.local` preview, + "Pick a disk" with an explicit erase warning, readable confirm table, + password hint explains it's also the SSH/console password, names are + lowercased instead of rejected, system account names are refused. +- Live console banner says a network cable with internet is required. + ## [26.20-alpha] - 2026-08-25 First release shaped by a real-hardware install (old laptop mainboard, BIOS boot,