The OLD_SNIPPET had wrong indentation (8 spaces vs 6) and was missing the
method guard line added in the fork:
if (req.method !== "GET" && req.method !== "HEAD") return next();
Without this fix the patch silently skips patching and webfinger continues
to return 302 → 401 on fediverse delivery.
https://claude.ai/code/session_0124D41vdLYE3DkJxhPqYthX
The Gitea conflict resolution kept main's prom-client/metrics-shim/microsub
changes but dropped our two new AP patch registrations. Re-add them to both
postinstall and serve.
https://claude.ai/code/session_0124D41vdLYE3DkJxhPqYthX
- Add scripts/patch-ap-og-image.mjs to both postinstall and serve so OG
preview images are included in ActivityPub activities (flat URL slug
extraction instead of date-based regex).
- Add scripts/patch-ap-webfinger-before-auth.mjs (new file) to both
postinstall and serve. Extends contentNegotiationRoutes Fedify delegation
to also forward /.well-known/* paths, ensuring webfinger is served by
Fedify before indiekit auth middleware can issue a 302 redirect. Fixes
401 Unauthorized errors from remote fediverse instances.
https://claude.ai/code/session_0124D41vdLYE3DkJxhPqYthX
Preloads metrics-shim.cjs via `node --require` into the Indiekit process
so heap, GC, event loop lag, CPU and handle metrics are exposed at
:9209/metrics for Prometheus scraping. Uses prom-client collectDefaultMetrics.
- Add metrics-shim.cjs (prom-client HTTP server, port 9209)
- Add prom-client ^15.1.3 to dependencies
- Wire --require ./metrics-shim.cjs into start.example.sh and npm serve script
- Grafana: NodeJS Application Dashboard (11159) at console.giersig.eu
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
nginx HTTP/80 returns 301 → HTTPS; pf has no hairpin NAT for jail traffic,
so following the redirect causes UND_ERR_SOCKET on every internal POST.
Correct value: http://10.100.0.20:3000 (direct to node jail).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
`getEndpointUrls()` resolved relative endpoint paths (e.g. `/media`) using
`getUrl(request)`, which returns `http://` because Express sees HTTP from nginx
without trust proxy. This produced `http://blog.giersig.eu/media` as the
endpoint attribute in the file-input component, causing Safari to block the
fetch as mixed content ('Load failed').
Fix: prefer `application.url` (the configured HTTPS base URL) over
`getUrl(request)` when resolving relative endpoint paths.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
nginx port 80 returns 444 (no response) for requests with an unrecognised
Host header. The poller's curl sends Host: 10.100.0.10 (the IP) which
doesn't match any server_name, causing the 180s readiness timeout and
"empty reply from server" on every poll.
Since livefetch v6 builds synthetic HTML from stored properties and no
longer fetches live pages, the poller no longer needs to go through nginx.
It now connects directly to Indiekit on INDIEKIT_BIND_HOST:PORT.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Trap previously only killed the webmention poller, leaving the node process
orphaned on service stop. On restart, the new node instance would fail to bind
port 3000 (EADDRINUSE) causing 502s with clean logs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The patch now recognises chore: and refactor: commit prefixes as their
own categories instead of lumping them into "other".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
package-lock.json was pinned to 7b838ea, meaning all fixes since
(favourite 404, resolveAuthor timeout, avatar cache, created_at
normalisation) were never installed on the server.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>