All checks were successful
release-tag / release-image (push) Successful in 1m41s
131 lines
4.0 KiB
Markdown
131 lines
4.0 KiB
Markdown
# Go HTMX Chat
|
|
|
|
Ein kleiner webbasierter Chat-Server mit Go, HTMX, Server-Sent Events, Datei-Persistenz und optionalem Pocket-ID/OIDC-Login.
|
|
|
|
## Features
|
|
|
|
- mehrere Chaträume
|
|
- neue Räume über das UI erstellen
|
|
- Rollen: `user`, `moderator`, `admin`
|
|
- Raumrechte getrennt für Lesen und Schreiben
|
|
- private Räume über Mitgliederlisten
|
|
- Admin-Seite für Rollen, Raumrechte und Nachrichten-Aufräumen
|
|
- lokaler Entwicklungslogin oder echter Login via Pocket ID / OpenID Connect
|
|
- signierte HttpOnly-Session-Cookies
|
|
- Nachrichten senden per HTMX POST
|
|
- Live-Updates per Server-Sent Events
|
|
- persistente Speicherung in `data/chat.json`
|
|
- keine Node-/Frontend-Build-Toolchain
|
|
- responsives Dark-UI
|
|
|
|
## Start im lokalen Entwicklungsmodus
|
|
|
|
```bash
|
|
go run ./cmd/server
|
|
```
|
|
|
|
Dann öffnen:
|
|
|
|
```text
|
|
http://localhost:8080
|
|
```
|
|
|
|
Optional:
|
|
|
|
```bash
|
|
go run ./cmd/server -addr :3000 -db data/dev-chat.json
|
|
```
|
|
|
|
## Pocket ID / OIDC Login aktivieren
|
|
|
|
Lege in Pocket ID einen OIDC Client an und trage als Callback URL ein:
|
|
|
|
```text
|
|
http://localhost:8080/auth/callback
|
|
```
|
|
|
|
Für produktiven Betrieb mit Reverse Proxy entsprechend:
|
|
|
|
```text
|
|
https://chat.example.com/auth/callback
|
|
```
|
|
|
|
Dann den Chat mit diesen Umgebungsvariablen starten:
|
|
|
|
```bash
|
|
export AUTH_MODE=oidc
|
|
export OIDC_ISSUER=https://id.example.com
|
|
export OIDC_CLIENT_ID=<client-id-aus-pocket-id>
|
|
export OIDC_CLIENT_SECRET=<client-secret-aus-pocket-id>
|
|
export OIDC_REDIRECT_URL=http://localhost:8080/auth/callback
|
|
export OIDC_SCOPES="openid profile email"
|
|
export SESSION_SECRET=$(openssl rand -base64 32)
|
|
export CHAT_ADMINS=j.bergner.hilden@gmail.com
|
|
export ROOM_CREATE_ROLES=admin,moderator
|
|
|
|
go run ./cmd/server
|
|
```
|
|
|
|
Hinweise:
|
|
|
|
- `OIDC_ISSUER` ist die Basis-URL deiner Pocket-ID-Instanz, zum Beispiel `https://id.example.com`.
|
|
- Die App liest automatisch `/.well-known/openid-configuration` und verwendet daraus Authorization-, Token- und UserInfo-Endpunkte.
|
|
- Als Anzeigename wird bevorzugt `preferred_username` genutzt, danach `name`, `email` und zuletzt `sub`.
|
|
- Hinter einem HTTPS-Reverse-Proxy sollte `X-Forwarded-Proto: https` gesetzt werden, damit Cookies als `Secure` markiert werden.
|
|
|
|
|
|
## Berechtigungssystem
|
|
|
|
Die App kennt drei globale Rollen:
|
|
|
|
- `user`: normaler Nutzer
|
|
- `moderator`: kann standardmäßig Räume erstellen und darf member-Räume betreten
|
|
- `admin`: darf alles verwalten
|
|
|
|
Der erste bekannte Benutzer wird automatisch Admin. Zusätzlich kannst du feste Admins über `CHAT_ADMINS` setzen. Der Wert ist eine kommaseparierte Liste aus Benutzernamen, E-Mail-Adressen oder OIDC-Subjects:
|
|
|
|
```bash
|
|
export CHAT_ADMINS="jan,j.bergner.hilden@gmail.com"
|
|
```
|
|
|
|
Wer Räume erstellen darf, steuerst du über:
|
|
|
|
```bash
|
|
export ROOM_CREATE_ROLES="admin,moderator"
|
|
```
|
|
|
|
Pro Raum gibt es getrennte Regeln für Lesen und Schreiben:
|
|
|
|
- `everyone`: alle eingeloggten Benutzer
|
|
- `members`: nur eingetragene Mitglieder, Moderatoren und Admins
|
|
- `moderators`: Moderatoren und Admins
|
|
- `admins`: nur Admins
|
|
|
|
Admins finden die Verwaltung unter `/admin`. Dort können sie Benutzerrollen ändern, Raumrechte setzen und alte Nachrichten löschen.
|
|
|
|
## Alte Nachrichten aufräumen
|
|
|
|
Unter `/admin` gibt es eine Retention-Aktion. Beispiel: `90` löscht alle Nachrichten, die älter als 90 Tage sind. Die Löschung ist dauerhaft, weil die aktuelle Persistenz in `data/chat.json` direkt überschrieben wird.
|
|
|
|
## Projektstruktur
|
|
|
|
```text
|
|
cmd/server/main.go Einstiegspunkt
|
|
internal/chat/hub.go SSE-Broadcast pro Raum
|
|
internal/store/store.go einfache JSON-Persistenz
|
|
internal/web/auth.go lokaler Login + OIDC/OAuth2 Flow
|
|
templates/ HTML Templates
|
|
static/app.css Styling
|
|
```
|
|
|
|
## Hinweise zur Sicherheit
|
|
|
|
Diese Version ist gut als Basis für einen privaten oder internen Chat geeignet. Für öffentlich produktiven Betrieb wären zusätzlich sinnvoll:
|
|
|
|
- CSRF-Schutz für schreibende POST-Routen
|
|
- Rate-Limits für Login, Raum-Erstellung und Nachrichten
|
|
- SQLite oder PostgreSQL als Store
|
|
- SQLite oder PostgreSQL als Store mit Migrationen
|
|
- vollständige ID-Token/JWKS-Prüfung mit einer OIDC-Library
|
|
- sichere Reverse-Proxy-Konfiguration mit HTTPS
|