koprogo_api/domain/entities/
refresh_token.rs

1use chrono::{DateTime, Duration, Utc};
2use serde::{Deserialize, Serialize};
3use uuid::Uuid;
4
5/// Represents a JWT refresh token
6#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
7pub struct RefreshToken {
8    pub id: Uuid,
9    pub user_id: Uuid,
10    pub token: String,
11    pub expires_at: DateTime<Utc>,
12    pub revoked: bool,
13    pub created_at: DateTime<Utc>,
14    pub updated_at: DateTime<Utc>,
15}
16
17impl RefreshToken {
18    /// Create a new refresh token with 7 days expiration
19    pub fn new(user_id: Uuid, token: String) -> Self {
20        let now = Utc::now();
21        let expires_at = now + Duration::days(7);
22
23        Self {
24            id: Uuid::new_v4(),
25            user_id,
26            token,
27            expires_at,
28            revoked: false,
29            created_at: now,
30            updated_at: now,
31        }
32    }
33
34    /// Check if token is expired
35    pub fn is_expired(&self) -> bool {
36        Utc::now() > self.expires_at
37    }
38
39    /// Check if token is valid (not expired and not revoked)
40    pub fn is_valid(&self) -> bool {
41        !self.is_expired() && !self.revoked
42    }
43
44    /// Revoke the token
45    pub fn revoke(&mut self) {
46        self.revoked = true;
47        self.updated_at = Utc::now();
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    #[test]
56    fn test_create_refresh_token() {
57        let user_id = Uuid::new_v4();
58        let token_string = "test_refresh_token".to_string();
59
60        let token = RefreshToken::new(user_id, token_string.clone());
61
62        assert_eq!(token.user_id, user_id);
63        assert_eq!(token.token, token_string);
64        assert!(!token.revoked);
65        assert!(token.is_valid());
66    }
67
68    #[test]
69    fn test_revoke_token() {
70        let user_id = Uuid::new_v4();
71        let mut token = RefreshToken::new(user_id, "test_token".to_string());
72
73        assert!(token.is_valid());
74
75        token.revoke();
76
77        assert!(token.revoked);
78        assert!(!token.is_valid());
79    }
80
81    #[test]
82    fn test_expired_token_is_invalid() {
83        let user_id = Uuid::new_v4();
84        let mut token = RefreshToken::new(user_id, "test_token".to_string());
85
86        // Set expiration to past
87        token.expires_at = Utc::now() - Duration::hours(1);
88
89        assert!(token.is_expired());
90        assert!(!token.is_valid());
91    }
92}