1use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey, Header, Validation};
2use serde::{Deserialize, Serialize, de::DeserializeOwned};
3
4#[derive(Deserialize, Serialize)]
5pub struct BasePayload {
6 #[serde(rename = "iss")]
7 pub issuer: String,
8 #[serde(rename = "sub")]
9 pub subject: Option<String>,
10 #[serde(rename = "aud")]
11 pub audience: Vec<String>,
12 #[serde(rename = "exp")]
13 pub expiration_time: Option<i64>,
14 #[serde(rename = "nbf")]
15 pub not_before: Option<i64>,
16 #[serde(rename = "iat")]
17 pub issued_at: Option<i64>,
18 #[serde(rename = "jti")]
19 pub jwt_id: String,
20}
21
22impl BasePayload {
23 pub fn validate(&self) -> bool {
24 let now = chrono::Utc::now().timestamp();
25 if let Some(exp) = self.expiration_time {
26 if exp < now {
27 return false;
28 }
29 } else {
30 return false;
31 }
32 if let Some(nbf) = self.not_before
33 && nbf > now
34 {
35 return false;
36 }
37 if let Some(iat) = self.issued_at {
38 if iat > now {
39 return false;
40 }
41 } else {
42 return false;
43 }
44 true
45 }
46}
47
48pub struct Jwt {
49 encoding_key: EncodingKey,
50 decoding_key: DecodingKey,
51}
52
53impl Jwt {
54 pub fn new(env: &crate::env::Env) -> Self {
55 let secret = env.app_encryption_key.as_bytes();
56 Self {
57 encoding_key: EncodingKey::from_secret(secret),
58 decoding_key: DecodingKey::from_secret(secret),
59 }
60 }
61
62 #[inline]
63 pub fn verify<T: DeserializeOwned>(
64 &self,
65 token: &str,
66 ) -> Result<T, jsonwebtoken::errors::Error> {
67 let mut validation = Validation::new(Algorithm::HS256);
68 validation.validate_exp = false;
69 validation.validate_aud = false;
70 validation.required_spec_claims.clear();
71 let data = jsonwebtoken::decode::<T>(token, &self.decoding_key, &validation)?;
72 Ok(data.claims)
73 }
74
75 #[inline]
76 pub fn create<T: Serialize>(&self, payload: &T) -> Result<String, jsonwebtoken::errors::Error> {
77 jsonwebtoken::encode(&Header::new(Algorithm::HS256), payload, &self.encoding_key)
78 }
79
80 #[inline]
81 pub fn create_custom<T: Serialize>(
82 &self,
83 key: &[u8],
84 payload: &T,
85 ) -> Result<String, jsonwebtoken::errors::Error> {
86 let encoding_key = EncodingKey::from_secret(key);
87 jsonwebtoken::encode(&Header::new(Algorithm::HS256), payload, &encoding_key)
88 }
89}