diff --git a/crates/daemons/pushd/src/consumers/outbound/vapid.rs b/crates/daemons/pushd/src/consumers/outbound/vapid.rs index fb735d5e..98554b07 100644 --- a/crates/daemons/pushd/src/consumers/outbound/vapid.rs +++ b/crates/daemons/pushd/src/consumers/outbound/vapid.rs @@ -55,11 +55,24 @@ impl AsyncConsumer for VapidOutboundConsumer { let config = revolt_config::config().await; + // A VAPID web push payload must carry the subscription endpoint and the + // p256dh public key in `extras`. Dropped malformed requests instead + // of panicking. + let (Some(endpoint), Some(p256dh)) = + (payload.extras.get("endpoint"), payload.extras.get("p256dh")) + else { + log::warn!( + "Dropping VAPID push for session {}: payload missing endpoint/p256dh in extras.", + payload.session_id + ); + return; + }; + let subscription = SubscriptionInfo { - endpoint: payload.extras.get("endpoint").unwrap().clone(), + endpoint: endpoint.clone(), keys: SubscriptionKeys { auth: payload.token, - p256dh: payload.extras.get("p256dh").unwrap().clone(), + p256dh: p256dh.clone(), }, };