use chrono::{DateTime, Duration, Utc}; use uuid::Uuid; #[derive(Debug, Clone)] pub struct Session { id: Uuid, user_id: Uuid, refresh_token: String, expires_at: DateTime, ip_address: Option, user_agent: Option, created_at: DateTime, revoked: bool, } impl Session { pub fn new( user_id: Uuid, refresh_token: String, ip_address: Option, user_agent: Option, expires_in_days: i64, ) -> Self { if refresh_token.is_empty() { panic!("Session refresh_token cannot be empty"); } let now = Utc::now(); Self { id: Uuid::new_v4(), user_id, refresh_token, expires_at: now + Duration::days(expires_in_days), ip_address, user_agent, created_at: now, revoked: false, } } #[allow(clippy::too_many_arguments)] pub fn from_raw( id: Uuid, user_id: Uuid, refresh_token: String, expires_at: DateTime, ip_address: Option, user_agent: Option, created_at: DateTime, revoked: bool, ) -> Self { Self { id, user_id, refresh_token, expires_at, ip_address, user_agent, created_at, revoked, } } // Getters pub fn id(&self) -> Uuid { self.id } pub fn user_id(&self) -> Uuid { self.user_id } pub fn refresh_token(&self) -> &str { &self.refresh_token } pub fn expires_at(&self) -> DateTime { self.expires_at } pub fn ip_address(&self) -> Option<&str> { self.ip_address.as_deref() } pub fn user_agent(&self) -> Option<&str> { self.user_agent.as_deref() } pub fn created_at(&self) -> DateTime { self.created_at } pub fn is_expired(&self) -> bool { Utc::now() > self.expires_at } pub fn is_revoked(&self) -> bool { self.revoked } pub fn revoke(&mut self) { self.revoked = true; } }