6 Commits

Author SHA1 Message Date
Julien Calixte
2aa10b1711 fix(auth): front CouchDB with nginx to mark AuthSession cookie Secure
CouchDB 3.5 derives the Set-Cookie Secure flag from the raw mochiweb
socket scheme and ignores X-Forwarded-Proto/Ssl for cookie attribution.
Behind a TLS-terminating proxy the cookie was emitted without Secure,
so browsers dropped the SameSite=None AuthSession cookie on cross-origin
requests — POST /_session returned 200 but the next GET /_session showed
userCtx.name: null and PouchDB stayed unauthenticated.

Add an nginx sidecar that adds Secure via proxy_cookie_flags, route the
public domain through it, and make couchdb internal. Also persist
same_site=none in couchdb-init so the setting survives container
recreation (local.d/ is not in the data volume).
2026-06-02 22:05:47 +02:00
Julien Calixte
c3c75787f4 feat(signup): add Gleam signup service gated by shared invite code
A small Gleam HTTP server in signup/ exposes POST /signup that validates
a shared INVITE_CODE env var, then PUTs a user document to CouchDB's
_users database using the existing admin credentials. The frontend gets
back 201 + the username and is expected to call /_session itself to
obtain the AuthSession cookie (chosen over server-side cookie forwarding
because vaquant.at and couch.apoena.dev are different sites and the
cross-site cookie path is fragile under modern browser privacy modes).

Wired into docker-compose as a second service, reachable on
signup-couch.apoena.dev with its own Traefik labels and the same
hardcoded UUID network attachment as couchdb. Reuses COUCHDB_USER /
COUCHDB_PASSWORD for the admin call. INVITE_CODE must be set in Coolify
env vars.
2026-06-01 22:16:29 +02:00
Julien Calixte
67787bdf31 fix(cors): enable credentials, enumerate origins for PouchDB sessions
PouchDB-style apps call fetch with credentials: 'include' to maintain
the CouchDB _session cookie. Without Access-Control-Allow-Credentials:
true in the preflight response, the browser silently blocks the
mutating request (Firefox HAR shows status 0, _securityState insecure).
Switching cors/credentials to true forces enumerating allowed origins
(wildcard + credentials is forbidden by the CORS spec). Listed are the
common Vite/Next/etc. local dev ports plus the vaquant.at frontend.
2026-06-01 21:55:13 +02:00
Julien Calixte
0ac46ecadb docs: explain hardcoded host and Coolify network UUID
Coolify does not interpolate ${...} inside the labels: block, so the
two strings tying this template to its specific Coolify resource cannot
currently be variables. Document where they appear and how to swap
them when redeploying as a new resource.
2026-06-01 21:27:19 +02:00
Julien Calixte
cff802bd3f fix: drop curl healthcheck and cors.ini mount; configure CORS via API
The couchdb:3 image purges curl after the build, so the curl-based
healthcheck could never succeed. The cors.ini bind-mount also looks
like the cause of the ~600ms container exit observed in the first two
Coolify deploys. Both pieces are removed; CORS is now applied by the
init sidecar via PUTs against /_node/_local/_config/..., which is
idempotent on redeploy.
2026-06-01 20:45:32 +02:00
Julien Calixte
38089ef269 init 2026-06-01 20:37:14 +02:00