diff options
Diffstat (limited to 'src/vapid')
| -rw-r--r-- | src/vapid/app.rs | 5 | ||||
| -rw-r--r-- | src/vapid/ser.rs | 30 |
2 files changed, 34 insertions, 1 deletions
diff --git a/src/vapid/app.rs b/src/vapid/app.rs index 61523d5..7d872ed 100644 --- a/src/vapid/app.rs +++ b/src/vapid/app.rs @@ -6,6 +6,7 @@ use crate::{ clock::DateTime, db::NotFound as _, event::{Broadcaster, Sequence, repo::Provider}, + push::repo::Provider as _, }; pub struct Vapid { @@ -60,6 +61,10 @@ impl Vapid { let changed_at = tx.sequence().next(ensure_at).await?; let (key, secret) = key.rotate(&changed_at); + // This will delete _all_ stored subscriptions. This is fine; they're all for the + // current VAPID key, and we won't be able to use them anyways once the key is rotated. + // We have no way to inform the push broker services of that, unfortunately. + tx.push().clear().await?; tx.vapid().clear().await?; tx.vapid().store_signing_key(&secret).await?; diff --git a/src/vapid/ser.rs b/src/vapid/ser.rs index f5372c8..02c77e1 100644 --- a/src/vapid/ser.rs +++ b/src/vapid/ser.rs @@ -1,7 +1,9 @@ pub mod key { + use std::fmt; + use base64::{Engine as _, engine::general_purpose::URL_SAFE}; use p256::ecdsa::VerifyingKey; - use serde::Serialize as _; + use serde::{Deserializer, Serialize as _, de}; // This serialization - to a URL-safe base-64-encoded string and back - is based on my best // understanding of RFC 8292 and the corresponding browser APIs. Particularly, it's based on @@ -32,4 +34,30 @@ pub mod key { let key = URL_SAFE.encode(key); key.serialize(serializer) } + + pub fn deserialize<'de, D>(deserializer: D) -> Result<VerifyingKey, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(Visitor) + } + + struct Visitor; + impl de::Visitor<'_> for Visitor { + type Value = VerifyingKey; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a string containing a VAPID key") + } + + fn visit_str<E>(self, key: &str) -> Result<Self::Value, E> + where + E: de::Error, + { + let key = URL_SAFE.decode(key).map_err(E::custom)?; + let key = VerifyingKey::from_sec1_bytes(&key).map_err(E::custom)?; + + Ok(key) + } + } } |
