1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use std::collections::BTreeMap;
use http::uri::Uri;
use jwt_simple::prelude::*;
use serde_json::Value;
use crate::{error::WebPushError, vapid::VapidKey};
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct VapidSignature {
pub auth_t: String,
pub auth_k: Vec<u8>,
}
pub type Claims = JWTClaims<BTreeMap<String , Value>>;
pub struct VapidSigner {}
impl VapidSigner {
pub fn sign(key: VapidKey, endpoint: &Uri, mut claims: Claims) -> Result<VapidSignature, WebPushError> {
if !claims.custom.contains_key("aud") {
let audience = format!("{}://{}", endpoint.scheme_str().unwrap(), endpoint.host().unwrap());
claims = claims.with_audience(audience);
} else {
let aud = claims.custom.get("aud").unwrap().clone();
claims = claims.with_audience(aud);
claims.custom.remove("aud");
}
if claims.custom.contains_key("exp") {
let exp = claims.custom.get("exp").unwrap().clone();
claims.expires_at = Some(Duration::from_secs(exp.as_u64().ok_or(WebPushError::InvalidClaims)?));
claims.custom.remove("exp");
}
let auth_k = key.public_key();
let auth_t = key.0.sign(claims).map_err(|_| WebPushError::InvalidClaims)?;
Ok(VapidSignature { auth_t, auth_k })
}
}
#[cfg(test)]
mod tests {}