Contesto non sicuro – per questo la pagina non funziona. La crittografia E2EE richiede HTTPS o localhost. Stai aprendo la pagina in HTTP: generazione chiavi, notifiche push e altre funzioni sono disattivate.
Test push con crittografia end-to-end. Stesso payload di push-test (titolo, corpo, URL, icona, badge, immagine, tag): il contenuto è cifrato e solo il tuo browser può decifrarlo.
Dominio: —(gestito lato server dall'appId — non inviato dal client)
Inserisci il token API, salvalo per questa sessione, configuralo sul server (solo demo) e verifica che Firebase sia OK. Senza questi passaggi non puoi attivare le notifiche né inviare push.
Non sai cos’è il token? È una password che scegli tu e che metti nel server. Dove: copia api-push/config/config.local.example.php in config.local.php, aprilo e sostituisci METTI_QUI_IL_TUO_TOKEN con una tua frase segreta (puoi usare la stessa per entrambi i token). Poi incolla quella frase qui sopra. Vedi api-push/config/LEGGIMI_TOKEN.txt per i dettagli.
Se compare «Accesso non consentito» anche con il token inserito, il server non ha quel valore in config: crea config.local.php e imposta WILLY_ADMIN_TOKEN e WILLY_API_TOKEN uguali al token che usi qui.
Imposta Token API (solo demo) – riassunto veloce
Questa sezione è la versione riassunta di Imposta Token API (solo demo) che vedi in fondo alla pagina. In debug viene mostrata qui in alto perché senza configurare il token il resto della demo non funziona.
Cosa fa il token: il Token API è la password che il server si aspetta nell’intestazione X-API-TOKEN. Ogni richiesta protetta (Verifica config Firebase, lista dispositivi cifrati, invio push, rimozione dispositivo) viene accettata solo se il token inviato coincide con quello configurato sul server (WILLY_API_TOKEN o WILLY_ADMIN_TOKEN in api-push/config).
Multi-tenant (produzione): in produzione non usi un solo token per tutti, ma molti token diversi, uno per ogni cliente/sito. La mappa token → tenant_id → domains_allowed sta in api-push/config/tenants.php: lo stesso engine gestisce 10, 100 o 10.000 domini, ciascuno con il proprio token. Questa pagina demo usa un solo token condiviso per semplificare i test.
Cosa simula questa pagina: questa pagina è il sito del cliente nella demo: qui inserisci il token che hai configurato sul server Willy e vedi subito se è corretto tramite «Verifica config Firebase».
Salva per questa sessione: prende il valore del campo Token API e lo salva in questo browser (sessionStorage). Da quel momento tutte le richieste della demo usano quel token. In produzione questo passo avviene lato backend (il sito non espone il token in pagina).
Configura token sul server (solo demo): chiama una API che scrive config.local.php sul server Willy con il token attuale. Serve solo per la demo: in produzione il file viene configurato a mano o via strumenti di deploy. Se il server risponde che la configurazione esiste già, la demo considera comunque il passo completato (non serve sovrascrivere).
Verifica config Firebase (server): fa una richiesta protetta usando il token salvato. Se il token è corretto e la config Firebase è valida, il passo 4 diventa «Fatto». In produzione questa verifica la fa di solito un pannello admin o un test tecnico, non il sito cliente.
Diagnostica token / Mostra audit (in fondo pagina): pulsanti di debug che spiegano se il token che stai usando corrisponde a quello configurato sul server e dove vengono scritti i log. Servono solo in fase di test/integrazione, non vengono esposti agli utenti finali.
Passo 5: Attiva notifiche cifrate
Genera una coppia di chiavi (ECDH P-256). La chiave privata resta nel browser (IndexedDB); la chiave pubblica viene inviata al server con il token FCM. Da questo momento le push cifrate saranno decifrabili solo da questo dispositivo. Ogni dispositivo ha la propria coppia di chiavi; con molti clienti il server memorizza solo le chiavi pubbliche (una per dispositivo).
Passo 6: Tutti i dispositivi destinatari
La push cifrata viene inviata a ognuno dei dispositivi in elenco. Se in elenco c’è 1 dispositivo ma la notifica arriva 2 volte, significa che ci sono 2 destinatari (es. stessa finestra registrata due volte, o due tab). Qui sotto vedi l’elenco completo numerato. Puoi rimuovere un dispositivo con «Rimuovi». L’elenco si aggiorna dopo il passo 5.
Caricamento…
Passo 7: Invia push cifrata di test
Compila i campi come in push-test. Il messaggio viene cifrato qui nel browser con la chiave pubblica di ogni destinatario e inviato al server già cifrato; il server inoltra solo enc e ephem. Il service worker decifra e mostra la notifica con titolo, corpo, icona, badge, immagine e URL.
Se la notifica non arriva: chiudi questa scheda o mettila in secondo piano (la push viene consegnata al service worker quando l’app è in background). Se arriva il messaggio «Decifratura non riuscita», apri questa pagina e clicca di nuovo «Genera chiavi e attiva notifiche».
Come funziona e come usarlo
Le notifiche push cifrate end-to-end (E2EE) funzionano così: il dispositivo destinatario genera una coppia di chiavi, invia la chiave pubblica al server e tiene la privata solo in locale. Il pannello mittente (questa pagina) chiede le chiavi pubbliche dei destinatari, cifra il messaggio qui nel browser e invia al server solo i dati già cifrati. Il server salva e inoltra solo il ciphertext: non conosce il contenuto. Solo il dispositivo destinatario decifra e mostra la notifica.
Scalabilità: non si usa una sola chiave condivisa. Ogni dispositivo ha la propria coppia di chiavi; il server memorizza solo le chiavi pubbliche (una per dispositivo). Con 10.000 clienti ci sono 10.000 chiavi pubbliche: ogni messaggio viene cifrato una volta per ogni destinatario con la sua chiave. Il server non decifra mai e non vede il contenuto.
Requisiti: apri questa pagina in HTTPS o da http://localhost (crypto.subtle è disponibile solo in contesto sicuro). Stesso dominio e stessa config Firebase di api-push.
Passi: (1) Token e verifica server (sopra). (2) Clicca «Genera chiavi e attiva notifiche»: il browser genera una coppia di chiavi, tiene la privata in IndexedDB e invia la pubblica al server. (3) Compila il form e clicca «Invia push cifrata» — il messaggio viene cifrato qui con la chiave pubblica di ogni destinatario e inviato al server già cifrato.
Il payload inviato (dopo la cifratura) è lo stesso formato usato in push-test: il service worker decifra e mostra la notifica con icona, badge, immagine e click su URL.
Cosa succede: chiavi, payload e flusso
Qui vedi in modo chiaro le chiavi, il payload in chiaro che inserisci, quello che viene davvero inviato a FCM (cifrato) e i passi del flusso.
Stato chiavi (questo dispositivo)
Controllo in corso…
Payload in chiaro (quello che inserisci nel form)
Compila il form sopra e invia una push: qui apparirà il JSON che il server cifrerà.
Payload inviato a FCM (cifrato – quello che vede il server e Firebase)
Dopo aver inviato una push cifrata, qui vedrai un'anteprima di enc e ephem (dati illeggibili).
Flusso passo per passo
Browser: generi una coppia di chiavi (ECDH P-256). La chiave privata resta solo qui, in IndexedDB. La chiave pubblica viene inviata al server insieme al token FCM.
Server: quando invii una push, il server prende il payload (titolo, corpo, URL, icona, …), lo cifra con la tua chiave pubblica e ottiene enc (dati cifrati) e ephem (chiave effimera pubblica).
FCM: il server invia a Firebase solo data: { enc, ephem, e2ee: "1" }. Nessun titolo/corpo in chiaro. FCM e il sistema operativo vedono solo caratteri senza senso.
Dispositivo: il service worker riceve il messaggio, legge la chiave privata da IndexedDB, decifra enc con ephem e ottiene titolo, corpo, URL, ecc.
Notifica: il service worker chiama showNotification() con i dati decifrati. Solo tu vedi il contenuto reale.
Imposta Token API (solo demo)
Cosa fa il token
Il Token API è la password che il server si aspetta nell’intestazione X-API-TOKEN. Ogni richiesta protetta (Verifica config Firebase, lista dispositivi cifrati, invio push, rimozione dispositivo) viene accettata solo se il token inviato coincide con quello configurato sul server (WILLY_API_TOKEN o WILLY_ADMIN_TOKEN in api-push/config). Se manca o è sbagliato, il server risponde 403 – Accesso non consentito e scrive comunque una riga nel file di audit (senza mai registrare il token).
Multi-tenant (produzione): in un’installazione reale non usi un solo token per tutti, ma molti token diversi, uno per ogni cliente/sito. La mappa token → tenant_id → domains_allowed sta in api-push/config/tenants.php: lo stesso engine gestisce 10, 100 o 10.000 domini, ciascuno con il proprio token. Questa pagina demo usa un solo token condiviso per semplificare i test; il modello reale è descritto in dettaglio in api-push/SECURITY.md e nelle pagine di integrazione.
Cosa simula questa pagina
Questa pagina (https://willypush.it/push-test-cifrato) è il sito del cliente nella demo: qui simuli il pannello da cui si inviano le push. Il token non sta nei file del cliente: sta sul server Willy (api-push). In produzione lo configura Willy; in demo puoi crearlo in automatico con il pulsante sotto: l'API scrive config.local.php sul server Willy, così la demo funziona senza toccare file a mano.
In produzione il token esiste solo sul server (file config.local.php o variabili d’ambiente): i client (siti, app) non hanno un “campo token” in pagina, perché il token è usato solo lato server quando il backend fa chiamate alle API push. Qui nella demo con ?debug=1 puoi inserire il token in un form per simulare un client autorizzato: così provi Verifica Firebase, invio, lista dispositivi e vedi nei log dove il server registra gli accessi. È solo a scopo di test e comprensione del flusso.
Modalità Demo / Debug – Log tecnici
In modalità debug puoi verificare che il payload cifrato viene inviato e che la decifratura avviene sul dispositivo con la chiave locale (Key ID). I log mostrano [SENT] (anteprima del payload cifrato inviato al server) e [RECEIVED] (decifratura con la chiave privata salvata in IndexedDB su questo dispositivo).
Token: —
Quando inserisci il token e fai una richiesta (es. Verifica config Firebase), il server scrive una riga nel file di audit. Il token non viene mai scritto nei log.