koprogo_api/domain/entities/
refresh_token.rs1use chrono::{DateTime, Duration, Utc};
2use serde::{Deserialize, Serialize};
3use uuid::Uuid;
4
5#[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 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 pub fn is_expired(&self) -> bool {
36 Utc::now() > self.expires_at
37 }
38
39 pub fn is_valid(&self) -> bool {
41 !self.is_expired() && !self.revoked
42 }
43
44 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 token.expires_at = Utc::now() - Duration::hours(1);
88
89 assert!(token.is_expired());
90 assert!(!token.is_valid());
91 }
92}