From 8ea6486dfca40aec4064ec3012c07f2d9df86e97 Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 21 Sep 2026 14:12:38 -0700 Subject: [PATCH] homepage: revalidate assets so deploys never serve stale CSS/JS The board rendered vertically for a user whose browser had cached the pre-sectioning style.css: deploys overwrite /srv/homepage in place, and nothing told the browser to revalidate. The @home handler on the post-auth listener now sends Cache-Control: no-cache, so every load is an ETag round-trip (a cheap 304 when unchanged) and a deploy is always visible on the next navigation. --- dankclaw/Caddyfile | 4 ++++ tests/homepage_caddy.bats | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/dankclaw/Caddyfile b/dankclaw/Caddyfile index d27850c..46bf45a 100644 --- a/dankclaw/Caddyfile +++ b/dankclaw/Caddyfile @@ -309,6 +309,10 @@ http://:8017 { @home host www.franksdank.cloud handle @home { root * /srv/homepage + # Deploys overwrite /srv/homepage in place; without revalidation a + # browser keeps serving the pre-deploy CSS/JS/HTML. no-cache forces an + # ETag round-trip on every load (a cheap 304 when unchanged). + header Cache-Control "no-cache" # RBAC (2026-09-01): /admin requires membership in the homepage-admins # authentik group. In proxy-provider mode the outpost injects # X-Authentik-Groups on its upstream request to this listener and strips diff --git a/tests/homepage_caddy.bats b/tests/homepage_caddy.bats index c5f791b..57e58be 100644 --- a/tests/homepage_caddy.bats +++ b/tests/homepage_caddy.bats @@ -33,6 +33,14 @@ setup() { grep -qE "handle[[:space:]]+@data" "$CADDY" } +@test "the homepage revalidates its assets (no stale cache after deploys)" { + # Deploys overwrite /srv/homepage in place; without a revalidation header + # a browser keeps serving the pre-deploy CSS/JS/HTML from cache. + local block + block=$(awk '/handle @home \{/,/^\t\}$/' "$CADDY") + echo "$block" | grep -q 'header Cache-Control "no-cache"' +} + @test "the homepage vhost chains Anubis (public) before Authentik SSO (internal listener)" { # Public listener: www proxies everything through Anubis; the naked # domain never enters the chain (it redirects at the TLS edge first).