Fix the logo's pop-in with a traced vector logo

The logo was an 880 KB SVG wrapping a 1254px PNG, downloaded again on
every page load. Keep that PNG as the master (artwork/logo.png) and have
scripts/logo.py trace it with potrace into a 6 KB logo.svg (favicon,
README) and logo.js, which brand.js draws inline in the header and on the
login page so the logo arrives with the page. Remove the unused
logo-white.svg.

Static files now carry content ETags, so reloads get 304s instead of
downloading the UI again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
abrown38andClaude Opus 5.5 committed 2026-10-08 18:01:22 +00:00
1 parent cf49df0346
commit 0f04dbb4b1
15 files changed
+215 -23049

No files matched your search

+8
View File
@@ -263,6 +263,14 @@ of each token is stored, and the full token is shown once.
what the ready-made `acme` role contains.
* Administrators can do everything, including managing users and server
internals. Admin rights are never available through a restricted token.
* A token can be **rotated**: it gets a new secret but keeps its grants,
optionally with a grace period for the old secret.
On the server itself, jarld also listens on a **local unix socket**. There
the kernel says which system user is connecting, and root and the `jarl`
user are administrators without a token, so `sudo jarl` needs no setup and
nobody with root on the server can be locked out. Everyone else needs a
token there too.
Details: [permissions.md](permissions.md).
+11 -4
View File
@@ -31,6 +31,8 @@ contrib/acme.sh/ acme.sh DNS API hook
contrib/lego/ program for lego's exec DNS provider
scripts/e2e.sh end-to-end test against a real named
scripts/mkdeb.sh builds the Debian package (make deb)
scripts/logo.py traces artwork/logo.png into the web UI's logo (logo.svg, logo.js)
artwork/ the logo's master image
```
The main flow is in `internal/engine/engine.go` (`applyOps`):
@@ -112,10 +114,15 @@ to that directory's `cli.yaml` to keep using the CLI against it.
### The web UI
The UI is plain JavaScript modules under `internal/web/static/`, with no
framework and no build step. The logo is `assets/logo.svg` (a white figure on
a Nordic-blue `#2f5fb3` disc) with an all-white variant
`assets/logo-white.svg`. Both are generated by `scripts/logo.py` (shapes are
given for the left half and mirrored); edit the script, not the SVGs. The
framework and no build step. The logo's master is `artwork/logo.png` (blue
`#1d5287` and white on a transparent background). `scripts/logo.py` traces it
with potrace (needs `potrace` and ImageMagick) into `assets/logo.svg` (the
favicon and the README's logo) and `assets/logo.js` (the same paths); change
the PNG and rerun the script rather than editing those files. The header and
login page draw the logo inline from `logo.js` (`logo()` in `brand.js`), so
it appears with the page instead of popping in after a separate download.
Static files are served with `Cache-Control: no-cache` and a content ETag,
so a reload revalidates them with cheap 304 answers. The
login page's "JARL" wordmark is drawn as SVG paths in `assets/brand.js`, so
it needs no font and takes the theme's text and accent colors. The header's
"Jarl" uses a Latin subset of Cinzel Bold in `assets/fonts/` (SIL OFL; keep
+12 -2
View File
@@ -10,6 +10,9 @@
| Check the configuration | `jarl check`: full validation plus `named-checkconf -z` |
| Logs | `journalctl -u jarl` (jarld, including `msg=audit` lines), `journalctl -u named` |
| Restart / reload TLS | `systemctl restart jarl` / `systemctl reload jarl` |
| Work on the server itself | `sudo jarl ...`: root uses jarld's local socket and needs no token ([cli.md](cli.md#on-the-server-itself)) |
| Renew or replace a token | `jarl token rotate NAME --grace 1h` (same grants, new secret; [permissions.md](permissions.md#rotating-a-token)) |
| Upgrade Jarl | Debian package: build the new one and `sudo apt install ./dist/jarl_*.deb`; otherwise `make && sudo make install && sudo systemctl restart jarl`. jarld upgrades its database when it starts |
Restarting jarld doesn't affect DNS: named keeps serving the files it
loaded. jarld is only needed to make changes.
@@ -98,12 +101,17 @@ Start named, then apply again.
## Recovering access
Revoking a token never locks you out: web logins don't depend on tokens,
and root on the server can always use `sudo jarl` through the local
socket, without a token.
| Problem | Fix (on the server) |
|---------|---------------------|
| Forgot the admin password | `sudo -u jarl jarld user passwd admin` |
| Revoked or lost the CLI's token | `sudo jarl token create cli --user admin`, or Account → API tokens in the web UI |
| Forgot the admin password | `sudo jarl user update admin --password`, or (also with jarld stopped) `sudo -u jarl jarld user passwd admin` |
| Locked out by the login rate limit | wait 15 minutes, or `systemctl restart jarl` (the limiter is in memory) |
| Lost every admin account | `sudo -u jarl jarld user add --admin rescue` |
| Need a token without the web UI | `sudo -u jarl jarld user token admin cli` |
| Need a token without the web UI | `sudo jarl token create cli --user admin`, or `sudo -u jarl jarld user token admin cli` |
## A secondary server
@@ -149,6 +157,8 @@ rndc reconfig
## Monitoring
* `GET /healthz` (no authentication) reports that jarld is up.
* On the server, a check can use the local socket and needs no token:
`sudo jarl status -o json`.
* `GET /api/v1/status` with a read-only token reports named reachability,
drift and configuration problems. It is suitable for a monitoring check:
```sh