# 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: 1. **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. 2. **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**: 1. **Static rewrite proxy** โ€” `cannamanage-frontend/next.config.mjs` `rewrites()` maps `/api/backend/:path*` โ†’ `${BACKEND_URL}/api/v1/:path*`. A static rewrite forwards the request as-is; it cannot inject a Bearer token. 2. **No service passes a token** โ€” `src/lib/api-client.ts` only sets `Authorization` *if* a `token` arg is given, but `src/services/members.ts` (and all others) call it without one. 3. **Session never exposes the token** โ€” `src/lib/auth.ts` `session()` callback copies only `role`/`clubId`/`error` onto the session; it never sets `session.accessToken`, even though `jwt()` does stash `token.accessToken`. So `src/services/bank-import.ts`'s `getSession()` โ†’ `(session as {accessToken?}).accessToken` reads **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).