4.3 KiB
CannaManage — public hosting readiness + the auth blocker (2026-06-18)
From: Homelab Lumen
To: Work Lumen
Re: Patrick asked whether CannaManage can go live on a public .de subdomain via the frp tunnel.
TL;DR
🔴 Not yet — keep it LAN-only. Two independent reasons:
- The systemic missing-token auth bug is STILL OPEN on
main(re-verified today, 5 days after the 2026-06-13 finding). The app holds real member PII, so it must not be publicly reachable until this is fixed and reviewed. - The public plumbing isn't wired yet (no frp proxy for the app, DNS record missing, no IONOS vhost, no TLS cert). Even if we wanted to, it can't serve traffic yet.
1. The auth bug — confirmed against current code
The token chain is broken in three places. Together they guarantee no Authorization
header ever reaches the backend from the browser:
- Static rewrite proxy —
cannamanage-frontend/next.config.mjsrewrites()maps/api/backend/:path*→${BACKEND_URL}/api/v1/:path*. A static rewrite forwards the request as-is; it cannot inject a Bearer token. - No service passes a token —
src/lib/api-client.tsonly setsAuthorizationif atokenarg is given, butsrc/services/members.ts(and all others) call it without one. - Session never exposes the token —
src/lib/auth.tssession()callback copies onlyrole/clubId/erroronto the session; it never setssession.accessToken, even thoughjwt()does stashtoken.accessToken. Sosrc/services/bank-import.ts'sgetSession()→(session as {accessToken?}).accessTokenreads undefined and also sends nothing.
Net: login works (server-side Credentials provider hits the unauthenticated /auth/login),
but every authenticated browser fetch hits the backend with no auth → 401/500. Pages only
render because they fall back to mock data.
Recommended fix (unchanged from 2026-06-13)
Replace the static rewrite with a server-side proxy Route Handler at
app/api/backend/[...path]/route.ts that reads auth() and forwards the Bearer token.
(Alternative: expose accessToken in the session() callback + attach it in apiClient
via getSession() — but the route-handler approach is cleaner and keeps the token server-side.)
Note on the regulatory framing
The PII risk is governed by DSGVO/GDPR, not §6 CanG. §6 CanG is the advertising/sponsoring prohibition. Doesn't change the conclusion — just cite the right law.
2. Public-hosting plumbing — current state
The stack is live & healthy on TrueNAS (frontend :3000, backend :8081→8080, db :5432),
auto-deployed by Gitea Actions on push to main. But it is not exposed publicly:
| Step | State |
|---|---|
| frp tunnel for the app | ❌ frpc.toml on TrueNAS only tunnels Gitea :30008 |
DNS cannamanage.plate-software.de |
❌ No record at authoritative NS (ns1057.ui-dns.de) as of 21:46 CEST |
| IONOS Apache vhost | ❌ none (template = git.plate-software.de.conf) |
| TLS cert | ❌ none (acme.sh on IONOS) |
NEXTAUTH_URL/AUTH_URL |
⚠️ hardcoded to http://192.168.188.119:3000 in docker-compose.truenas.yml — must flip to the public HTTPS origin |
| prod secrets | ⚠️ deploy/.env.production.example all CHANGE_ME |
DNS surprise worth flagging
inspectflow.plate-software.de now does resolve — but to 217.160.0.176
(217-160-0-176.elastic-ssl.ui-r.com, an IONOS elastic-SSL/shared host), NOT the
82.165.206.45 IONOS Apache box that fronts git.plate-software.de. That means inspectflow's
record was pointed at IONOS shared/managed hosting, not at our reverse-proxy chain. If the
intended topology is "IONOS Apache → VPS frp → TrueNAS" (the Gitea pattern), that A record is
on the wrong target and the frp path won't work. Worth confirming with Patrick which host
should terminate these.
cannamanage.plate-software.de simply isn't created yet. (Patrick is reserving cannamanage.de
for launch — do not probe it.)
What Work Lumen should pick up
The auth route-handler fix is the real unblocker and a code change — that's your lane. Once it's in and reviewed, the homelab side can wire the tunnel/DNS/TLS quickly (it's the same proven Gitea chain). I've logged both findings in BigMind (facts 219, 221).