feat(discord-bridge): dashboard fara token (DASHBOARD_AUTH=off)

Cerut explicit: tokenul nu se retine. Cu DASHBOARD_AUTH=off nu mai exista login,
/login.html duce inapoi la panou, iar butonul "Iesi" dispare.

Se sprijina pe doua lucruri si nu are sens fara ele: serviciul e legat de
127.0.0.1, deci din retea ajunge la el doar tailscaled; iar tailscale serve il
publica tainet only, unde accesul e deja autentificat de Tailscale.

Compensatie partiala pentru ce se pierde: fiecare start/stop/restart se scrie in
logs/dashboard.log cu identitatea din antetul Tailscale-User-Login pus de
tailscale serve (verificat: ajunge pana la noi). Antetul e DOAR pentru jurnal —
nu decide accesul, fiindca un proces local l-ar putea fabrica.

Implicitul ramane cu token: doar off/none/0/false scot login-ul, orice alta
valoare il pastreaza (are test).

Sase teste noi, 41 pe dashboard.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B29CApsP1JkSdjYaGaHpE7
This commit is contained in:
Claude Agent
2026-08-30 14:16:20 +00:00
parent e203ee021d
commit b14e7bc50a
6 changed files with 126 additions and 11 deletions

View File

@@ -82,7 +82,8 @@ urmatorul poll (test: `test_state_corupt_nu_arunca`).
## Endpoint-uri
Toate cer cookie-ul de sesiune, obtinut cu `POST /api/auth/login`.
Toate cer cookie-ul de sesiune, obtinut cu `POST /api/auth/login` — sau nimic,
cand `DASHBOARD_AUTH=off` (vezi mai jos).
| Metoda | Ruta | Ce face |
|---|---|---|
@@ -94,12 +95,34 @@ Toate cer cookie-ul de sesiune, obtinut cu `POST /api/auth/login`.
| POST | `/api/service` | `{"action": "start\|stop\|restart", "force": bool}` |
| POST | `/api/approvals/decide` | `{"request_id": "...", "decision": "allow\|deny"}` |
| POST | `/api/restart-self` | reporneste dashboard-ul |
| POST | `/api/auth/login` / `/api/auth/logout` | `{"token": "..."}` / sterge cookie-ul |
| POST | `/api/auth/login` / `/api/auth/logout` | `{"token": "..."}` / sterge cookie-ul (inutile cu `DASHBOARD_AUTH=off`) |
Autentificarea e un token din `~/.claude-discord/env` schimbat pe un cookie
`HttpOnly; SameSite=Strict` valabil 30 de zile, comparat cu `secrets.compare_digest`.
Fara `DASHBOARD_TOKEN` in env, procesul isi genereaza unul aleator si il scrie in
`logs/dashboard.log` — **nu** ramane deschis.
`logs/dashboard.log` — **nu** ramane deschis din neatentie.
### Fara token (`DASHBOARD_AUTH=off`)
Configuratia curenta pe LXC 171. Nu mai exista login: `/login.html` duce inapoi la
panou, iar butonul „Ieși" dispare.
Se sprijina pe doua lucruri, si **nu are sens fara ele**:
- serviciul e legat de `127.0.0.1`, deci din retea ajunge la el doar `tailscaled`;
- `tailscale serve` publica panoul `tainet only`, iar accesul in tailnet e deja
autentificat de Tailscale.
Ce se pierde: orice dispozitiv din tailnet, si orice proces din container care
ajunge la port, poate opri sau reporni puntea. Ce ramane: fiecare start/stop/restart
se scrie in `logs/dashboard.log` cu identitatea din antetul `Tailscale-User-Login`
pus de `tailscale serve` (`local` cand cererea vine de pe 127.0.0.1). Antetul e
**doar pentru jurnal** — nu decide accesul, fiindca un proces local l-ar putea
fabrica.
Inapoi la token: scoate `DASHBOARD_AUTH=off` din `~/.claude-discord/env` si
reporneste serviciul. Doar `off`, `none`, `0` si `false` scot login-ul; orice alta
valoare il pastreaza.
## Instalare
@@ -116,7 +139,7 @@ systemctl --user enable --now claude-discord-dashboard
Setari optionale in `~/.claude-discord/env`: `DASHBOARD_BIND` (implicit `127.0.0.1`),
`DASHBOARD_PORT` (implicit `18790`), `DASHBOARD_PREFIX` (implicit gol; `/claude` cand e
publicat prin `tailscale serve --set-path`).
publicat prin `tailscale serve --set-path`), `DASHBOARD_AUTH` (`off` scoate login-ul).
## Acces
@@ -160,7 +183,8 @@ ssh -L 18790:127.0.0.1:18790 -N claude@10.0.20.171 &
# apoi http://localhost:18790
```
Tokenul se citeste cu `grep DASHBOARD_TOKEN ~/.claude-discord/env`.
Cu `DASHBOARD_AUTH=off` (configuratia curenta) nu se cere nimic la intrare. Daca
tokenul e reactivat, se citeste cu `grep DASHBOARD_TOKEN ~/.claude-discord/env`.
## Teste
@@ -169,7 +193,7 @@ cd proxmox/lxc171-claude-agent/discord-bridge
python3 -m pytest tests/test_dashboard.py -q
```
35 de teste, fara retea si fara `systemctl` real (dublura inregistreaza apelurile).
41 de teste, fara retea si fara `systemctl` real (dublura inregistreaza apelurile).
Acopera autentificarea, faptul ca unitatea nu poate fi aleasa din cerere, blocajul pe
tur in zbor si trecerea cu `force`, traversarea de cale in `request_id`, `state.json`
corupt, montarea sub prefix (cu si fara slash final) si verificarea de regresie