Skip to main content

shared/domain/auth/
claims.rs

1use chrono::{Duration, Local};
2use serde::{Deserialize, Serialize};
3use validator::Validate;
4
5use super::validation::validate_objectid;
6use crate::config::JwtConfig;
7
8#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
9pub enum TokenType {
10    #[default]
11    AccessToken,
12    RefreshToken,
13}
14
15#[derive(Debug, Default, Clone, Serialize, Deserialize, Validate)]
16pub struct Claims {
17    #[validate(length(equal = 24), custom(function = "validate_objectid"))]
18    pub sub: String,
19    pub exp: usize,
20    pub iat: usize,
21    pub iss: String,
22    pub aud: String,
23    pub jti: uuid::Uuid,
24    pub roles: Vec<String>,
25    pub permissions: Vec<String>,
26    pub token_type: TokenType,
27}
28
29impl Claims {
30    pub fn new(user_id: &str, role: &str) -> Self {
31        Claims {
32            sub: user_id.into(),
33            roles: vec![role.into()],
34            iat: Local::now().timestamp() as usize,
35            jti: uuid::Uuid::new_v4(),
36            ..Default::default()
37        }
38    }
39}
40
41impl Claims {
42    pub fn with_issuer(mut self, issuer: &str) -> Self {
43        self.iss = issuer.into();
44        self
45    }
46    pub fn with_audience(mut self, audience: &str) -> Self {
47        self.aud = audience.into();
48        self
49    }
50    pub fn with_permissions(mut self, permissions: Vec<String>) -> Self {
51        self.permissions = permissions;
52        self
53    }
54    fn with_expiry(mut self, expires_in: i64) -> Self {
55        self.exp = (Local::now() + Duration::seconds(expires_in)).timestamp() as usize;
56        self
57    }
58    fn with_token_type(mut self, token_type: TokenType) -> Self {
59        self.token_type = token_type;
60        self
61    }
62}
63impl Claims {
64    pub fn into_token_pair(self, jwt_config: &JwtConfig) -> (Claims, Claims) {
65        let access = self
66            .clone()
67            .with_expiry(jwt_config.access_token_expires_in)
68            .with_token_type(TokenType::AccessToken);
69
70        let refresh = self
71            .with_expiry(jwt_config.refresh_token_expires_in)
72            .with_token_type(TokenType::RefreshToken);
73        (access, refresh)
74    }
75}