SendSecret: Erstimport und Umstellung auf Tag-Deployment

Wrapper-Frontend vor cryptgeon: der Browser verschluesselt lokal, per Mail
geht nur der Link raus.

Fuer das Deployment nach den Konventionen aus DEPLOY.md hergerichtet:

- docker-compose.yml mit festem Projekt- und Container-Namen, kein
  ports-Mapping, Healthcheck als Deploy-Gate. cryptgeon und redis liegen
  im internen Netz, nur app haengt im Web-Netz.
- cryptgeon von latest auf 2.9.3 gepinnt. Das ist derselbe Stand, den
  latest bisher geliefert hat; 2.6.2 existiert nicht.
- /healthz in server.js, vor dem Catch-all-Proxy registriert.
- Dockerfile auf npm ci mit Lockfile und non-root umgestellt.
- .gitea/workflows/deploy.yml: Build und Syntaxpruefung vor dem Deploy,
  .env aus dem Repo-Secret DOTENV.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Lucas Orth
2026-08-25 07:26:15 +02:00
commit 681fc1649a
19 changed files with 3096 additions and 0 deletions

95
README.md Normal file
View File

@@ -0,0 +1,95 @@
# SendSecret
Sichere Passwort-Uebergabe fuer Kunden. Eigenes Frontend vor
[cryptgeon](https://github.com/cupcakearmy/cryptgeon): das Passwort wird im
Browser verschluesselt, landet als einmalig abrufbare Notiz in cryptgeon,
und per Mail geht nur der Link raus. Der Schluessel steht im
URL-Fragment und erreicht den Server nie.
Zwei Einstiege:
- `/` - Kundenformular. Verschickt den Link automatisch an `RECIPIENT_EMAIL`.
- `/link` - erzeugt nur den Link zum selbst Weitergeben.
## Aufbau
```
Browser --https--> Nginx Proxy Manager --> sendsecret (app)
| / statische Seite
| /api/send Mailversand
| /healthz Deploy-Gate
+--> cryptgeon --> redis
```
`cryptgeon` und `redis` haengen nur im internen Netz `sendsecret-internal`
und sind von aussen nicht erreichbar.
## Lokal entwickeln
```bash
cd app && npm ci && npm run build && npm start
```
Braucht ein laufendes cryptgeon unter `http://cryptgeon:8000` sowie die
Variablen aus `.env.example`. Einfacher ist der komplette Stack:
```bash
cp .env.example .env && docker compose up --build
```
## Konfiguration
`.env` im Repo-Root, Vorlage in [.env.example](.env.example):
| Variable | Bedeutung |
|---|---|
| `SMTP_HOST` / `SMTP_PORT` | Mailserver, Port 465 schaltet auf TLS |
| `SMTP_USER` / `SMTP_PASS` | Zugangsdaten |
| `SMTP_FROM` | Absender im Format `Name <adresse>` |
| `RECIPIENT_EMAIL` | Empfaenger der Kundenmails |
| `APP_URL` | Oeffentliche Basis-URL, prueft die eingereichten Links |
Auf dem Server kommt der Inhalt nicht aus einer Datei, sondern aus dem
Gitea-Repo-Secret `DOTENV`.
## Deployment
Per Tag-Push, Konventionen in [DEPLOY.md](DEPLOY.md).
Einmalig einzurichten:
1. Repo-Secret `DOTENV` anlegen (Repo -> Einstellungen -> Actions ->
Secrets) mit dem kompletten `.env`-Inhalt, mehrzeilig. Kanonische
Fassung in den Passwortmanager - Gitea gibt den Wert nicht mehr heraus.
2. Pruefen, ob auf dem Server schon Container mit den festen Namen laufen:
`docker ps -a --filter name=sendsecret`. Falls ja, im alten Verzeichnis
einmal `docker compose down`, sonst kollidieren die Namen.
3. Proxy Host im Nginx Proxy Manager:
| Feld | Wert |
|---|---|
| Domain Names | `secret.lucas-orth.de` |
| Scheme | `http` |
| Forward Hostname / IP | `sendsecret` |
| Forward Port | `3000` |
Danach Let's-Encrypt-Zertifikat ausstellen und "Force SSL" aktivieren.
4. Deployen:
```bash
git tag v1.0.0 && git push origin v1.0.0
```
Danach pruefen:
```bash
docker ps --filter name=sendsecret --format '{{.Names}}\t{{.Status}}'
```
`sendsecret` muss `healthy` zeigen, nicht `Restarting`.
## Versionen
`cupcakearmy/cryptgeon` ist auf **2.9.3** gepinnt - das ist derselbe Stand,
den `latest` bisher geliefert hat. Die Frontend-Bundles verschluesseln mit
`occulto` 2.0.6 gegen dieses API-Format; ein Upgrade betrifft beide Seiten.