diff options
| author | Owen Jacobson <owen@grimoire.ca> | 2025-07-24 22:32:27 -0400 |
|---|---|---|
| committer | Owen Jacobson <owen@grimoire.ca> | 2025-07-24 22:32:27 -0400 |
| commit | b63380b251d04dd92f06aa5bbc22a72ca3e4bf8e (patch) | |
| tree | 3956ec457131ce049fd91f2f53309bc0620fffe2 /src/push/handlers | |
| parent | 2e42057694851b82574e0a406ded429fb95a07fa (diff) | |
wip: 83B78D40-D7CB-4419-9FE7-E7D858909443
Diffstat (limited to 'src/push/handlers')
| -rw-r--r-- | src/push/handlers/echo.rs | 20 | ||||
| -rw-r--r-- | src/push/handlers/mod.rs | 79 | ||||
| -rw-r--r-- | src/push/handlers/register.rs | 40 | ||||
| -rw-r--r-- | src/push/handlers/unregister.rs | 16 |
4 files changed, 86 insertions, 69 deletions
diff --git a/src/push/handlers/echo.rs b/src/push/handlers/echo.rs new file mode 100644 index 0000000..4b4de57 --- /dev/null +++ b/src/push/handlers/echo.rs @@ -0,0 +1,20 @@ +use axum::extract::{Json, State}; + +use crate::{app::App, push::Id, token::extract::Identity}; + +#[derive(serde::Deserialize)] +pub struct Request { + subscription: Id, + msg: String, +} + +pub async fn handler( + State(app): State<App>, + identity: Identity, + Json(request): Json<Request>, +) -> Result<(), crate::error::Internal> { + let Request { subscription, msg } = request; + app.push().echo(&identity.user, &subscription, &msg).await?; + + Ok(()) +} diff --git a/src/push/handlers/mod.rs b/src/push/handlers/mod.rs index e4a531b..90edaa7 100644 --- a/src/push/handlers/mod.rs +++ b/src/push/handlers/mod.rs @@ -1,74 +1,15 @@ -use std::env; +use axum::extract::State; -use axum::{ - extract::{Json}, -}; +use crate::app::App; -use web_push::{ - SubscriptionInfo, - VapidSignatureBuilder, - WebPushMessageBuilder, - ContentEncoding, - WebPushClient, - IsahcWebPushClient, -}; +mod echo; +mod register; +mod unregister; +pub use echo::handler as echo; +pub use register::handler as register; +pub use unregister::handler as unregister; -pub async fn vapid() -> String { - let vapid_public_key = env::var("VAPID_PUBLIC_KEY").unwrap_or_default(); - String::from(vapid_public_key) -} - - -pub async fn register() -> String { - String::from("OK") -} - - -pub async fn unregister() -> String { - String::from("OK") -} - -async fn push_message( - endpoint: String, - keys: Keys, - message: &String, -) -> Result<(), crate::error::Internal> { - let content = message.as_bytes(); - - let subscription_info = SubscriptionInfo::new(endpoint, keys.p256dh, keys.auth); - // This will need to come from the DB eventually: - let private_key = String::from(env::var("VAPID_PRIVATE_KEY").unwrap_or_default()); - let sig_builder = VapidSignatureBuilder::from_base64(&private_key, &subscription_info)?.build()?; - let mut builder = WebPushMessageBuilder::new(&subscription_info); - builder.set_payload(ContentEncoding::Aes128Gcm, content); - builder.set_vapid_signature(sig_builder); - let client = IsahcWebPushClient::new()?; - client.send(builder.build()?).await?; - - Ok(()) -} - - -#[axum::debug_handler] -pub async fn echo( - Json(payload): Json<PushPayload>, -) -> Result<(), crate::error::Internal> { - push_message(payload.endpoint, payload.keys, &payload.msg).await?; - - Ok(()) -} - - -#[derive(serde::Deserialize)] -pub struct Keys { - pub p256dh: String, - pub auth: String, -} - -#[derive(serde::Deserialize)] -pub struct PushPayload { - pub msg: String, - pub endpoint: String, - pub keys: Keys, +pub async fn vapid(State(app): State<App>) -> String { + app.push().public_key().to_owned() } diff --git a/src/push/handlers/register.rs b/src/push/handlers/register.rs new file mode 100644 index 0000000..201928b --- /dev/null +++ b/src/push/handlers/register.rs @@ -0,0 +1,40 @@ +use axum::extract::{Json, State}; +use web_push::SubscriptionInfo; + +use crate::{app::App, error::Internal, push::Id, token::extract::Identity}; + +#[derive(serde::Deserialize)] +pub struct Request { + endpoint: String, + p256dh: String, + auth: String, +} + +#[derive(serde::Serialize)] +pub struct Response { + id: Id, +} + +pub async fn handler( + State(app): State<App>, + identity: Identity, + Json(request): Json<Request>, +) -> Result<Json<Response>, Internal> { + let subscription = request.into(); + + let id = app.push().register(&identity.user, &subscription).await?; + + Ok(Json(Response { id })) +} + +impl From<Request> for SubscriptionInfo { + fn from(request: Request) -> Self { + let Request { + endpoint, + p256dh, + auth, + } = request; + let info = Self::new(endpoint, p256dh, auth); + info + } +} diff --git a/src/push/handlers/unregister.rs b/src/push/handlers/unregister.rs new file mode 100644 index 0000000..a00ee92 --- /dev/null +++ b/src/push/handlers/unregister.rs @@ -0,0 +1,16 @@ +use axum::{ + extract::{Path, State}, + http::StatusCode, +}; + +use crate::{app::App, error::Internal, push::Id, token::extract::Identity}; + +pub async fn handler( + State(app): State<App>, + identity: Identity, + Path(subscription): Path<Id>, +) -> Result<StatusCode, Internal> { + app.push().unregister(&identity.user, &subscription).await?; + + Ok(StatusCode::NO_CONTENT) +} |
