1use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct AuthUser {
10 pub id: i64,
12 pub email: String,
14 pub role: String,
16}
17
18impl AuthUser {
19 pub fn new(id: i64, email: impl Into<String>, role: impl Into<String>) -> Self {
21 Self {
22 id,
23 email: email.into(),
24 role: role.into(),
25 }
26 }
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct Session {
32 pub token: String,
34 pub user_id: i64,
36 pub expires_at: chrono::NaiveDateTime,
38}
39
40impl Session {
41 pub fn new(token: impl Into<String>, user_id: i64, expires_at: chrono::NaiveDateTime) -> Self {
43 Self {
44 token: token.into(),
45 user_id,
46 expires_at,
47 }
48 }
49
50 pub fn is_expired(&self) -> bool {
52 chrono::Utc::now().naive_utc() > self.expires_at
53 }
54
55 pub fn remaining_time(&self) -> Option<chrono::Duration> {
57 let now = chrono::Utc::now().naive_utc();
58 if now < self.expires_at {
59 Some(self.expires_at - now)
60 } else {
61 None
62 }
63 }
64}
65
66#[derive(Debug, Clone, Deserialize)]
68pub struct Credentials {
69 pub email: String,
71 pub password: String,
73}
74
75impl Credentials {
76 pub fn new(email: impl Into<String>, password: impl Into<String>) -> Self {
78 Self {
79 email: email.into(),
80 password: password.into(),
81 }
82 }
83}
84
85#[derive(Debug, Clone, Serialize)]
87pub struct LoginResponse {
88 pub token: String,
90 pub user: AuthUser,
92 pub expires_at: chrono::NaiveDateTime,
94}
95
96impl LoginResponse {
97 pub fn new(session: Session, user: AuthUser) -> Self {
99 Self {
100 token: session.token,
101 expires_at: session.expires_at,
102 user,
103 }
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110 use chrono::Duration;
111
112 #[test]
113 fn test_auth_user_creation() {
114 let user = AuthUser::new(1, "test@example.com", "admin");
115 assert_eq!(user.id, 1);
116 assert_eq!(user.email, "test@example.com");
117 assert_eq!(user.role, "admin");
118 }
119
120 #[test]
121 fn test_session_expiration() {
122 let future = chrono::Utc::now().naive_utc() + Duration::hours(1);
123 let session = Session::new("token123", 1, future);
124 assert!(!session.is_expired());
125 assert!(session.remaining_time().is_some());
126
127 let past = chrono::Utc::now().naive_utc() - Duration::hours(1);
128 let expired_session = Session::new("token456", 1, past);
129 assert!(expired_session.is_expired());
130 assert!(expired_session.remaining_time().is_none());
131 }
132
133 #[test]
134 fn test_credentials_creation() {
135 let creds = Credentials::new("user@example.com", "password123");
136 assert_eq!(creds.email, "user@example.com");
137 assert_eq!(creds.password, "password123");
138 }
139}