Lot 12 : notifications Web Push tenues par la façade (LOKI_PUSH=rust)

La façade sert la clé VAPID et les (dés)abonnements, et pousse elle-même
les notifications « réponse prête » quand LOKI_PUSH=rust (expérimental ;
le Go reste le défaut) : chiffrement RFC 8291 (aes128gcm, enregistrement
complété à 4096 octets comme webpush-go), signature VAPID RFC 8292 (JWT
ES256), abonnements purgés sur 404/410, par ring déjà présent via rustls.
Mêmes clés en base que le Go.

Côté Go : facade_push.go remet les routes du tunnel à la façade, et
sendPushToAll (fin de tour, fin de tâche) lui délègue l'envoi.

Parité : parity_push_test.go tire du Go les durées et onze appels de route
avec la liste des abonnements en base, rejoués par tests/push.rs ; le
chiffrement reproduit l'exemple de la RFC 8291 à l'octet près, et un envoi
de bout en bout est déchiffré côté navigateur.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016tcGfJWefW5kUGoC2wL8cv
This commit is contained in:
Claude committed 2026-10-15 17:01:07 +00:00
1 parent cbd0d5e356
commit eddcf97e3b
20 files changed
+1320 -5

No files matched your search

+3 -1
View File
@@ -143,7 +143,7 @@ var facadeChatRoutes = map[string]bool{
// withFacadeChat remet la requête à la façade quand elle tient la
// conversation — ou les routes des modèles (facade_models.go), la dictée
// (facade_dictate.go), les réglages partagés (facade_settings.go), les fichiers
// de la discussion (facade_files.go).
// de la discussion (facade_files.go), les notifications (facade_push.go).
// Posé APRÈS requireWebAuth : seule une requête authentifiée ici part, avec le
// jeton interne qui en tient lieu là-bas.
func withFacadeChat(path string, h http.HandlerFunc) http.HandlerFunc {
@@ -158,6 +158,8 @@ func withFacadeChat(path string, h http.HandlerFunc) http.HandlerFunc {
held, unavailable = facadeSettings, "réglages indisponibles : "
case facadeFilesRoutes[path]:
held, unavailable = facadeFiles, "fichiers indisponibles : "
case facadePushRoutes[path]:
held, unavailable = facadePush, "notifications indisponibles : "
default:
return h
}