fix(files): general.host must be a bare hostname, not a URL

The SPA computes its redirect origin as (force_ssl ? "https://" : "http://")
+ general.host. With host set to "https://files.${BASE_DOMAIN}" that produced
"http://https://files.ulicraft.net", so every client-side redirect broke and
the page never routed anywhere.

Server-side this was invisible: SecureOrigin strips the scheme before the
Host check, so `curl /` returned 200, the API answered, and the uptime
monitor stayed green — only real browsers failed. The tell is a
`POST /report?...msg=Redirecting to http://https://...` line in the log.

Set host to the bare hostname and force_ssl=true (which the origin needs to
build https://, and which only emits an HSTS header — it does not redirect,
so it can't loop behind the plain-http nginx→caddy hop).

Verified: origin is now "https://files.ulicraft.net"; login + ls still work.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-14 18:27:42 +02:00
parent cd79b0e540
commit 10b86ae23e
3 changed files with 38 additions and 7 deletions

View File

@@ -34,6 +34,13 @@ render nmsr/config.toml.tmpl nmsr/config.toml
# admin console writes it back at runtime. We render it and mount it read-only,
# so git stays authoritative (the console renders but cannot save — by design).
#
# general.host in the template is a BARE HOSTNAME (files.$BASE_DOMAIN, no
# scheme) and general.force_ssl is true. The SPA builds its redirect origin as
# (force_ssl ? "https://" : "http://") + host, so a scheme in `host` produces
# "http://https://files..." and every client-side redirect breaks. The
# server-side Host check strips the scheme first, so curl/monitors see a healthy
# 200 and ONLY browsers fail. Don't "fix" it by putting the URL back.
#
# FILES_AUTH picks the identity_provider block. The params fields are JSON
# *strings* holding escaped JSON (that's Filestash's schema, not a typo) —
# built here rather than in the template because the shape differs per mode.