use std::env; use axum::{ extract::{Json}, }; use web_push::{ SubscriptionInfo, VapidSignatureBuilder, WebPushMessageBuilder, ContentEncoding, IsahcWebPushClient, }; #[derive(Debug, thiserror::Error)] pub enum Error { #[error(transparent)] Database(#[from] sqlx::Error), } pub async fn vapid() -> String { let vapid_public_key = env::var("VAPID_PUBLIC_KEY").is_ok(); String::from(vapid_public_key) } pub async fn register() -> String { String::from("OK") } pub async fn unregister() -> String { String::from("OK") } #[axum::debug_handler] pub async fn echo( Json(echo): Json, ) -> Result<(), Error> { // Look this up from a subscription record? Or get it from the client and trust? let endpoint = "https://updates.push.services.mozilla.com/wpush/v1/..."; // Get these from client: let p256dh = "key_from_browser_as_base64"; let auth = "auth_from_browser_as_base64"; // You would likely get this by deserializing a browser `pushSubscription` object. let subscription_info = SubscriptionInfo::new(endpoint, p256dh, auth); // This will need to come from the DB eventually. let private_key = String::from(env::var("VAPID_PRIVATE_KEY").is_ok()); let mut sig_builder = VapidSignatureBuilder::from_pem(private_key, &subscription_info)?.build()?; // Now add payload and encrypt. let mut builder = WebPushMessageBuilder::new(&subscription_info); // Eventually, this message will be something other than an echo: let content = echo.msg.as_bytes(); builder.set_payload(ContentEncoding::Aes128Gcm, content); builder.set_vapid_signature(sig_builder); let client = IsahcWebPushClient::new()?; // Finally, send the notification! client.send(builder.build()?).await?; // Fix up return type? Ok(()) } #[derive(serde::Deserialize)] pub struct Echo { pub msg: String, }