diff --git a/CHANGELOG.md b/CHANGELOG.md index ea6227b..dea93c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,56 @@ This project uses calendar versioning: `YY.N-stage` (e.g. `26.0-alpha` = 2026, r ## [Unreleased] +## [26.16-alpha] - 2026-05-10 + +### Added + +- **Failed-login rate limit on `/login`.** A new in-memory + `LoginAttempts` store in `furtka/auth.py` blocks brute-force attempts + after 10 failures in 15 minutes from the same (username, IP) pair, + with a 15-minute lockout. Successful logins clear the counter; a + `systemctl restart furtka` clears any stuck lockout — fine for an + alpha single-user box. Tuple-keying means a flood from one source IP + can't lock the admin out from elsewhere; an attacker can rotate IPs + to keep probing forever, but each attempt still eats the PBKDF2 cost. + Locked attempts get a `Retry-After` header so the UI can render the + cooldown. +- **Live-ISO boot USB is filtered out of the install drive picker.** On + bare-metal installs, `lsblk` reports the USB stick the live ISO + booted from as `TYPE=disk`, so it showed up in the picker alongside + the real install target — a user could in theory pick the USB they + had just booted from. `webinstaller/drives.py` now resolves + `/run/archiso/bootmnt` via `findmnt`, walks it up to its parent disk + via `lsblk -no PKNAME`, and drops that disk before scoring. On a + normal (non-live) box `/run/archiso/bootmnt` does not exist and the + picker is unchanged. + +### Changed + +- **furtka.org homepage rebuild.** Adopted the visual feel of Pascal's + prototype while keeping Furtka's voice, brand palette, and bilingual + structure: Three.js wireframe torus-knot behind the hero (color + + opacity tied to the existing `--accent` CSS var so light and dark + modes share one scene), scroll-driven camera zoom + tilt, GSAP + + ScrollTrigger card reveals, Lenis smooth scroll, gradient wordmark, + drop-shadow glow in dark mode, and a pulsing CTA pointing at + `/releases`. "What works today" / "What's coming next" lists moved + from markdown bullets into front-matter arrays and now render as + scroll-reveal cards. All vendor JS (Three.js r128, GSAP 3.12.2 + + ScrollTrigger, Lenis 1.0.33) is vendored locally under + `website/assets/js/vendor/`, fingerprinted with SRI, gated to the + homepage only, deferred so first paint isn't blocked, and + early-returned on `prefers-reduced-motion`. +- **Static-asset gzip on the furtka.org nginx (config only — needs a + deploy on forge-runner-01).** Default nginx only gzips `text/html`, + so the homepage HTML was the only asset coming back compressed. The + ~600 KB `three.min.js` bundle (and the hashed CSS) were being shipped + uncompressed across the public openresty proxy. `gzip_types` in + `ops/nginx/furtka.org.conf` now covers css/js/json/xml/svg/woff2. + Needs `sudo ops/nginx/setup-vm.sh` on forge-runner-01 to take effect + — the site-deploy workflow only rebuilds Hugo, it doesn't touch the + nginx config. + ## [26.15-alpha] - 2026-04-21 ### Fixed @@ -354,7 +404,8 @@ First tagged snapshot. Pre-alpha — the installer does not yet boot, but the de - **Containers:** Docker + Compose - **License:** AGPL-3.0 -[Unreleased]: https://forgejo.sourcegate.online/daniel/furtka/compare/26.15-alpha...HEAD +[Unreleased]: https://forgejo.sourcegate.online/daniel/furtka/compare/26.16-alpha...HEAD +[26.16-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.16-alpha [26.15-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.15-alpha [26.14-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.14-alpha [26.13-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.13-alpha diff --git a/pyproject.toml b/pyproject.toml index 2344472..5ddfb71 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "furtka" -version = "26.15-alpha" +version = "26.16-alpha" description = "Open-source home server OS — simple enough for everyone." requires-python = ">=3.11" readme = "README.md" diff --git a/website/content/_index.de.md b/website/content/_index.de.md index f879976..09469d5 100644 --- a/website/content/_index.de.md +++ b/website/content/_index.de.md @@ -1,7 +1,7 @@ --- title: "Furtka" description: "Offenes Heimserver-Betriebssystem — einfach genug für alle." -status: "26.15-alpha — in Arbeit" +status: "26.16-alpha — in Arbeit" # features_today / features_next müssen index-parallel zu content/_index.md bleiben. intro: | **Furtka** ist ein offenes Heimserver-Betriebssystem. diff --git a/website/content/_index.md b/website/content/_index.md index 98041f0..decc35a 100644 --- a/website/content/_index.md +++ b/website/content/_index.md @@ -1,7 +1,7 @@ --- title: "Furtka" description: "Open-source home server OS — simple enough for everyone." -status: "26.15-alpha — work in progress" +status: "26.16-alpha — work in progress" # Keep features_today / features_next index-aligned with content/_index.de.md. intro: | **Furtka** is an open-source home server OS. diff --git a/website/hugo.toml b/website/hugo.toml index 7c91d66..612a880 100644 --- a/website/hugo.toml +++ b/website/hugo.toml @@ -6,7 +6,7 @@ enableRobotsTXT = true [params] description = "Open-source home server OS — simple enough for everyone." - version = "26.15-alpha" + version = "26.16-alpha" contactEmail = "hallo@furtka.org" [markup.goldmark.renderer]