Files
pi_mcps/lumen-exchange/from-homelab/2026-06-18-cannamanage-public-hosting-and-auth-blocker.md
T

83 lines
4.3 KiB
Markdown

# 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).