1
use base64::{Engine as _, engine::general_purpose};
2
use serde::{Deserialize, Serialize};
3
use uuid::Uuid;
4

            
5
#[derive(Debug, Serialize, Deserialize)]
6
pub struct TokenDetails {
7
    pub token: Option<String>,
8
    pub token_uuid: uuid::Uuid,
9
    pub user_id: uuid::Uuid,
10
    pub expires_in: Option<i64>,
11
}
12

            
13
#[derive(Debug, Serialize, Deserialize, Clone)]
14
pub struct TokenClaims {
15
    pub sub: String,
16
    pub token_uuid: String,
17
    pub exp: i64,
18
    pub iat: i64,
19
    pub nbf: i64,
20
}
21

            
22
pub fn generate_jwt_token(
23
    user_id: uuid::Uuid,
24
    ttl: i64,
25
    private_key: &str,
26
) -> Result<TokenDetails, jsonwebtoken::errors::Error> {
27
    let bytes_private_key = general_purpose::STANDARD.decode(private_key).unwrap();
28
    let decoded_private_key = String::from_utf8(bytes_private_key).unwrap();
29

            
30
    let now = chrono::Utc::now();
31
    let mut token_details = TokenDetails {
32
        user_id,
33
        token_uuid: Uuid::new_v4(),
34
        expires_in: Some((now + chrono::Duration::minutes(ttl)).timestamp()),
35
        token: None,
36
    };
37

            
38
    let claims = TokenClaims {
39
        sub: token_details.user_id.to_string(),
40
        token_uuid: token_details.token_uuid.to_string(),
41
        exp: token_details.expires_in.unwrap(),
42
        iat: now.timestamp(),
43
        nbf: now.timestamp(),
44
    };
45

            
46
    let header = jsonwebtoken::Header::new(jsonwebtoken::Algorithm::RS256);
47
    let token = jsonwebtoken::encode(
48
        &header,
49
        &claims,
50
        &jsonwebtoken::EncodingKey::from_rsa_pem(decoded_private_key.as_bytes())?,
51
    )?;
52
    token_details.token = Some(token);
53
    Ok(token_details)
54
}
55

            
56
2
pub fn verify_jwt_token(
57
2
    public_key: &str,
58
2
    token: &str,
59
2
) -> Result<TokenDetails, jsonwebtoken::errors::Error> {
60
2
    let bytes_public_key = general_purpose::STANDARD.decode(public_key).unwrap();
61
2
    let decoded_public_key = String::from_utf8(bytes_public_key).unwrap();
62

            
63
2
    let validation = jsonwebtoken::Validation::new(jsonwebtoken::Algorithm::RS256);
64

            
65
    let decoded = jsonwebtoken::decode::<TokenClaims>(
66
2
        token,
67
2
        &jsonwebtoken::DecodingKey::from_rsa_pem(decoded_public_key.as_bytes())?,
68
        &validation,
69
    )?;
70

            
71
    let user_id = Uuid::parse_str(decoded.claims.sub.as_str()).unwrap();
72
    let token_uuid = Uuid::parse_str(decoded.claims.token_uuid.as_str()).unwrap();
73

            
74
    Ok(TokenDetails {
75
        token: None,
76
        token_uuid,
77
        user_id,
78
        expires_in: None,
79
    })
80
2
}