# Changelog All notable changes to Jarl are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow [Semantic Versioning](https://semver.org/). ## [Unreleased] ### Added - Two-factor login to the web UI with an authenticator app (TOTP: SHA-1, 6 digits, 30 s, as every app supports). Users turn it on under Account (password, QR code, a code to confirm) and get 10 one-time recovery codes. Logging in then asks for a code (or a recovery code) after the password; each code works once. In a session with two-factor login, creating or rotating API tokens, changing users and resetting someone's two-factor login need a code from the last 5 minutes: the web UI asks for one, API clients send `X-Jarl-TOTP`. API tokens and the local socket are not affected. - `totp.require` in jarl.yaml (`none`, `admins`, `all`) makes two-factor login compulsory; such a user who hasn't set it up can only set it up after logging in. `totp.issuer` names the server in authenticator apps (default `Jarl `). - Resetting a user's two-factor login (lost phone): Users → Reset 2FA, `jarl user totp reset NAME`, or on the server `jarld user totp reset NAME` (also with jarld stopped). - The dashboard and `jarl status` list users who must use two-factor login but haven't set it up, and suggest disabling the first `admin` account when it is still active next to personal administrator accounts. `jarl user list`/`show` and the Users page show who uses it. - API: `POST /auth/login/totp`, `/me/totp` (`setup`, `enable`, `disable`, `recovery-codes`), `DELETE /users/{id}/totp`; database migration 3. - `scripts/testenv.sh`: turns a fresh Debian/Ubuntu machine into a test bed. It installs BIND and the build tools (Go from go.dev), writes a hand-made style configuration with internal and external views, a split-horizon zone (`example.com` or `JARL_TEST_ZONE`) and a reverse zone, starts named and prints the steps to install Jarl and adopt the configuration (docs/development.md). ### Fixed - `jarld init -u` and the install guide recommend naming the first administrator after yourself (one account per person). - `jarld import` no longer warns that a zone with `allow-update { none; }` uses dynamic updates (validation already allowed it). - docs/cli.md gives the CLI configuration file's location on macOS (`~/Library/Application Support/jarl/config.yaml`) and Windows (`%AppData%\jarl\config.yaml`). It was documented only as `~/.config/jarl/config.yaml`. ## [0.1.0] - 2026-10-09 The first version. ### Added - Daily database backups: the `jarl-backup.timer` systemd timer (turned on by the Debian package) runs `jarld backup`, which writes `jarl-.db` into `backup.dir` (`/var/backups/jarl`), checks it with SQLite's integrity check before giving it that name, and deletes backups older than `backup.retention` (30d) while always keeping the newest `backup.keep_at_least` (7). Ages come from the names, and only files named like backups are ever deleted. Settings are in the new `backup:` section of jarl.yaml; the schedule is the timer's. The dashboard and `jarl status` show the newest backup, and warn when it is older than `backup.warn_after` (2d) or the last attempt failed. `backup.stats` also backs up the statistics database. - `jarld restore [FILE | latest]`: lists backups, or checks one, shows what it holds next to the current database, and after confirmation replaces the database with it, keeping the current one as `jarl.db.before-restore-