# Projekthinweise ## Was das ist SendSecret ist ein eigenes Frontend vor [cryptgeon](https://github.com/cupcakearmy/cryptgeon). Kunden geben ein Passwort ein, der Browser verschluesselt es lokal (`occulto`), legt es als Notiz in cryptgeon ab und schickt nur den Link per Mail an `RECIPIENT_EMAIL`. Der Schluessel steht im URL-Fragment und erreicht den Server nie. Drei Container: `app` (Express-Wrapper, Mail, Proxy), `cryptgeon`, `redis`. Nur `app` haengt im Web-Netz, die anderen beiden im internen Netz. ## Wo was liegt | Pfad | Inhalt | |---|---| | `app/server.js` | Express: statische Seiten, `/api/send` (Mail), `/healthz`, Catch-all-Proxy auf `http://cryptgeon:8000` | | `app/src/` | Frontend-Quellen, werden von `build.js` (esbuild) nach `app/public/` gebundelt | | `app/public/` | `index.html`, `link.html`, `style.css` (Quellen) + generierte Bundles (nicht im Git) | | `docker-compose.yml` | Stack, Konventionen aus DEPLOY.md | | `.gitea/workflows/deploy.yml` | Tag-Deploy | ## Beim Aendern beachten - **`express.json()` nicht global setzen.** Es wuerde den Body-Stream aufbrauchen, bevor der Proxy ihn an cryptgeon weiterreichen kann. Nur an `/api/send` haengen. - **Neue Routen vor dem Catch-all-Proxy registrieren**, sonst gehen sie an cryptgeon. Betrifft insbesondere `/healthz` - das ist das Deploy-Gate. - **cryptgeon-Version ist gepinnt** (`2.9.3`). Die Bundles verschluesseln mit `occulto` 2.0.6 gegen dieses API-Format (`POST /api/notes/` mit `contents` / `meta` / `views`). Vor einem Upgrade beide Seiten pruefen. - **Redis hat bewusst keine Persistenz** (`--save "" --appendonly no`) und deshalb kein Volume. Notizen sollen einen Neustart nicht ueberleben. ## Deployment Diese App wird per Tag-Push deployt, nicht manuell hochgeladen. Die verbindlichen Konventionen stehen in **DEPLOY.md**. Vor Aenderungen an `Dockerfile`, `docker-compose.yml` oder `.gitea/workflows/` dort nachsehen. Kurzfassung der Regeln, die man leicht bricht: - Kein `ports:` im Compose. Der Proxy erreicht den Container ueber das Netz `nginx-proxy-manager_default` unter seinem `container_name` (`sendsecret`). - `name:` im Compose ist Pflicht (fester Projektname), sonst legt der CI-Job einen zweiten Stack an. - Keine relativen Bind-Mounts. Compose laeuft im Job-Container, der Pfad zeigt auf dem Host ins Leere. - Healthcheck ist Pflicht, der Deploy nutzt ihn als Gate. - Secrets kommen aus dem Repo-Secret `DOTENV`, nie in die Compose-Datei.