1use crate::{config, AuthResult};
2use jsonwebtoken::{decode, encode, get_current_timestamp, DecodingKey, EncodingKey, Header, TokenData, Validation};
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6#[derive(Debug, Serialize, Deserialize, Clone)]
7pub struct UserClaims {
8 uid: String,
9 exp: usize,
10 claims: Option<Value>,
11}
12
13#[derive(Debug)]
14pub struct Jwt {
15 config: config::Jwt,
16}
17
18impl Jwt {
19 pub fn new(config: config::Jwt) -> Self {
20 Self { config }
21 }
22
23 pub fn token(&self, uid: String, claims: Option<Value>) -> AuthResult<String> {
24 let exp = (get_current_timestamp() + self.config.expiration) as usize;
25
26 let claims = UserClaims { uid, exp, claims };
27
28 let token = encode(
29 &Header::new(self.config.algorithm),
30 &claims,
31 &EncodingKey::from_base64_secret(&self.config.secret)?,
32 )?;
33
34 Ok(token)
35 }
36
37 pub fn validate(&self, token: &str) -> AuthResult<TokenData<UserClaims>> {
38 let mut validate = Validation::new(self.config.algorithm);
39 validate.leeway = 0;
40
41 Ok(decode::<UserClaims>(
42 token,
43 &DecodingKey::from_base64_secret(&self.config.secret)?,
44 &validate,
45 )?)
46 }
47}