Harden session handling, add password reset/change, and firm up round polling

Session hardening: / and /admin now respond with Cache-Control: no-store, and
both pages re-derive their auth state on pageshow (event.persisted) as a
safety net against bfcache showing a stale logged-in/out view across
back/forward navigation. The user page also syncs logout across tabs via the
storage event, since localStorage is shared but in-memory JS state isn't.

Password recovery: admin gets a "Reset" button per user (POST
/admin/users/{id}/reset-password) that generates and sets a new password,
shown once — passwords are Argon2-hashed and can never be recovered, only
replaced. Users get self-service password change (POST
/users/me/change-password, requires the current password) under a new
Profilo tab, alongside read-only account info (username, address, balance,
join date).

Round display robustness: the user dashboard now refreshes immediately on
tab visibility change (background tabs get their timers throttled hard),
shows an explicit "connessione persa" state after repeated failed polls
instead of silently freezing on stale data, and polls faster both right when
the countdown hits zero and through the gap where the round is past its
deadline but still waiting for in-flight bets to confirm before the server
actually closes it.
This commit is contained in:
2026-07-22 12:00:09 +02:00
parent 162a63d04a
commit f27fe6243c
9 changed files with 471 additions and 25 deletions
+12 -2
View File
@@ -20,7 +20,7 @@ sola schermata di login.
## Sezioni della dashboard
- **Parametri** — configurazione operativa (vedi tabella sotto)
- **Utenti** — elenco utenti, saldo, accesso alla chiave privata
- **Utenti** — elenco utenti, saldo, accesso alla chiave privata, reset password
- **Round** — storico round: stato, vincitore, importi, txid di payout
- **Transazioni pendenti** — bet/payout/prelievi non ancora confermati, candidati al fee-bump RBF
- **Audit log** — eventi registrati dal sistema (config cambiata, bet, payout, accessi a chiavi private, ecc.)
@@ -126,7 +126,7 @@ curl -X PUT https://<host>/admin/config \
-d '{"fee_address": "plm1q...", "bet_amount_sats": 1000000000, "round_duration_seconds": 600}'
```
## Utenti e chiave privata
## Utenti, chiave privata e reset password
La card "Utenti" elenca id, username, indirizzo e saldo di ogni utente
registrato. Il bottone "Mostra" su ogni riga rivela la chiave privata (WIF)
@@ -137,6 +137,16 @@ falla: il server è già custodial, la chiave master da cui derivano tutte le
chiavi utente vive sul server — questo pannello espone solo qualcosa che
l'operatore può già fare via script.
Il bottone "Reset" nella colonna "Password" genera una **nuova password
casuale** per l'utente e sovrascrive quella esistente — mostrata una sola
volta nel pannello, così puoi comunicarla a chi ti ha chiesto aiuto perché
l'ha dimenticata. Non è un "recupero": le password sono salvate solo come
hash Argon2 (`app/auth/security.py`), quindi quella vecchia **non è mai
recuperabile** né per l'admin né per il codice stesso — l'unica opzione è
sempre sostituirla con una nuova. Anche questa azione è audit-loggata
(`admin_password_reset`) e non esiste alcun flusso self-service equivalente
per l'utente: solo un admin col token può farlo.
## Limiti noti
- Il token è unico e condiviso: non c'è identità per singolo admin né audit
+19 -2
View File
@@ -20,7 +20,8 @@ login ogni volta che riapri la pagina.
Dopo l'accesso vedi, in ordine:
1. **Barra account** — il tuo username e il bottone "Esci" (logout)
1. **Barra di navigazione** (fissa in alto) — il tuo username e il bottone
"Esci" (logout) nella riga superiore, e i tab delle sezioni subito sotto
2. **Card del round corrente** — sempre visibile, indipendentemente dalla
sezione che stai guardando:
- numero del round e stato (*aperto*, *in chiusura*, *estrazione in
@@ -30,7 +31,7 @@ Dopo l'accesso vedi, in ordine:
- **giocatori**: quanti hanno già piazzato una bet in questo round
- **jackpot**: il totale in PLM che verrà distribuito (70% al vincitore,
30% in fee)
3. **Menu di navigazione** con tre sezioni:
3. **Tab di navigazione** con quattro sezioni:
### Estrazione del vincitore
@@ -87,6 +88,22 @@ Form con due campi:
Il prelievo viene costruito e trasmesso sulla rete; la fee di rete viene
scalata dall'importo richiesto (non si aggiunge separatamente).
### Profilo
Due card:
- **Profilo**: le tue informazioni account — username, indirizzo di
deposito, saldo interno e data di iscrizione. Sola lettura, nessuna
modifica possibile qui.
- **Impostazioni**: form per **cambiare la password**. Serve la password
attuale (per conferma) più la nuova password (minimo 8 caratteri, digitata
due volte). Non richiede un nuovo login: la sessione attiva resta valida
anche dopo il cambio.
Se hai dimenticato la password e non riesci più ad accedere, questa sezione
non ti aiuta (serve la password attuale) — contatta l'operatore della
piattaforma, che può reimpostartene una nuova dal pannello admin.
## Notifiche
Ogni azione (registrazione, login, bet, prelievo, ecc.) mostra un breve