1use serde::{Deserialize, Serialize};
2use chrono::{DateTime, Utc};
3use uuid::Uuid;
4use std::collections::HashMap;
5
6
7
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
10pub struct User {
11 pub id: String,
12 pub name: Option<String>,
13 pub email: Option<String>,
14 #[serde(rename = "emailVerified")]
15 pub email_verified: bool,
16 pub image: Option<String>,
17 #[serde(rename = "createdAt")]
18 pub created_at: DateTime<Utc>,
19 #[serde(rename = "updatedAt")]
20 pub updated_at: DateTime<Utc>,
21 pub username: Option<String>,
22 #[serde(rename = "displayUsername")]
23 pub display_username: Option<String>,
24 #[serde(rename = "twoFactorEnabled")]
25 pub two_factor_enabled: bool,
26 pub role: Option<String>,
27 pub banned: bool,
28 #[serde(rename = "banReason")]
29 pub ban_reason: Option<String>,
30 #[serde(rename = "banExpires")]
31 pub ban_expires: Option<DateTime<Utc>>,
32 #[serde(skip)]
34 pub metadata: HashMap<String, serde_json::Value>,
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct Session {
40 pub id: String,
41 #[serde(rename = "expiresAt")]
42 pub expires_at: DateTime<Utc>,
43 pub token: String,
44 #[serde(rename = "createdAt")]
45 pub created_at: DateTime<Utc>,
46 #[serde(rename = "updatedAt")]
47 pub updated_at: DateTime<Utc>,
48 #[serde(rename = "ipAddress")]
49 pub ip_address: Option<String>,
50 #[serde(rename = "userAgent")]
51 pub user_agent: Option<String>,
52 #[serde(rename = "userId")]
53 pub user_id: String,
54 #[serde(rename = "impersonatedBy")]
55 pub impersonated_by: Option<String>,
56 #[serde(rename = "activeOrganizationId")]
57 pub active_organization_id: Option<String>,
58 #[serde(skip)]
60 pub active: bool,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
65pub struct Account {
66 pub id: String,
67 #[serde(rename = "accountId")]
68 pub account_id: String,
69 #[serde(rename = "providerId")]
70 pub provider_id: String,
71 #[serde(rename = "userId")]
72 pub user_id: String,
73 #[serde(rename = "accessToken")]
74 pub access_token: Option<String>,
75 #[serde(rename = "refreshToken")]
76 pub refresh_token: Option<String>,
77 #[serde(rename = "idToken")]
78 pub id_token: Option<String>,
79 #[serde(rename = "accessTokenExpiresAt")]
80 pub access_token_expires_at: Option<DateTime<Utc>>,
81 #[serde(rename = "refreshTokenExpiresAt")]
82 pub refresh_token_expires_at: Option<DateTime<Utc>>,
83 pub scope: Option<String>,
84 pub password: Option<String>,
85 #[serde(rename = "createdAt")]
86 pub created_at: DateTime<Utc>,
87 #[serde(rename = "updatedAt")]
88 pub updated_at: DateTime<Utc>,
89}
90
91#[derive(Debug, Clone, Serialize, Deserialize)]
93pub struct Verification {
94 pub id: String,
95 pub identifier: String,
96 pub value: String,
97 #[serde(rename = "expiresAt")]
98 pub expires_at: DateTime<Utc>,
99 #[serde(rename = "createdAt")]
100 pub created_at: DateTime<Utc>,
101 #[serde(rename = "updatedAt")]
102 pub updated_at: DateTime<Utc>,
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize)]
107pub struct TwoFactor {
108 pub id: String,
109 pub secret: String,
110 #[serde(rename = "backupCodes")]
111 pub backup_codes: Option<String>,
112 #[serde(rename = "userId")]
113 pub user_id: String,
114}
115
116#[derive(Debug, Clone, Serialize, Deserialize)]
118pub struct Passkey {
119 pub id: String,
120 pub name: String,
121 #[serde(rename = "publicKey")]
122 pub public_key: String,
123 #[serde(rename = "userId")]
124 pub user_id: String,
125 #[serde(rename = "credentialID")]
126 pub credential_id: String,
127 pub counter: u64,
128 #[serde(rename = "deviceType")]
129 pub device_type: String,
130 #[serde(rename = "backedUp")]
131 pub backed_up: bool,
132}
133
134#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
136pub enum HttpMethod {
137 Get,
138 Post,
139 Put,
140 Delete,
141 Patch,
142 Options,
143 Head,
144}
145
146#[derive(Debug, Clone)]
148pub struct AuthRequest {
149 pub method: HttpMethod,
150 pub path: String,
151 pub headers: HashMap<String, String>,
152 pub body: Option<Vec<u8>>,
153 pub query: HashMap<String, String>,
154}
155
156#[derive(Debug, Clone)]
158pub struct AuthResponse {
159 pub status: u16,
160 pub headers: HashMap<String, String>,
161 pub body: Vec<u8>,
162}
163
164#[derive(Debug, Clone, Serialize, Deserialize)]
166pub struct CreateUser {
167 pub id: Option<String>,
168 pub email: Option<String>,
169 pub name: Option<String>,
170 pub image: Option<String>,
171 pub email_verified: Option<bool>,
172 pub password: Option<String>,
173 pub username: Option<String>,
174 pub display_username: Option<String>,
175 pub role: Option<String>,
176 pub metadata: Option<HashMap<String, serde_json::Value>>,
177}
178
179#[derive(Debug, Clone, Serialize, Deserialize)]
181pub struct UpdateUser {
182 pub email: Option<String>,
183 pub name: Option<String>,
184 pub image: Option<String>,
185 pub email_verified: Option<bool>,
186 pub username: Option<String>,
187 pub display_username: Option<String>,
188 pub role: Option<String>,
189 pub banned: Option<bool>,
190 pub ban_reason: Option<String>,
191 pub ban_expires: Option<DateTime<Utc>>,
192 pub two_factor_enabled: Option<bool>,
193 pub metadata: Option<HashMap<String, serde_json::Value>>,
194}
195
196#[derive(Debug, Clone)]
198pub struct CreateSession {
199 pub user_id: String,
200 pub expires_at: DateTime<Utc>,
201 pub ip_address: Option<String>,
202 pub user_agent: Option<String>,
203 pub impersonated_by: Option<String>,
204 pub active_organization_id: Option<String>,
205}
206
207#[derive(Debug, Clone)]
209pub struct CreateAccount {
210 pub user_id: String,
211 pub account_id: String,
212 pub provider_id: String,
213 pub access_token: Option<String>,
214 pub refresh_token: Option<String>,
215 pub id_token: Option<String>,
216 pub access_token_expires_at: Option<DateTime<Utc>>,
217 pub refresh_token_expires_at: Option<DateTime<Utc>>,
218 pub scope: Option<String>,
219 pub password: Option<String>,
220}
221
222#[derive(Debug, Clone)]
224pub struct CreateVerification {
225 pub identifier: String,
226 pub value: String,
227 pub expires_at: DateTime<Utc>,
228}
229
230impl CreateUser {
231 pub fn new() -> Self {
232 Self {
233 id: Some(Uuid::new_v4().to_string()),
234 email: None,
235 name: None,
236 image: None,
237 email_verified: None,
238 password: None,
239 username: None,
240 display_username: None,
241 role: None,
242 metadata: None,
243 }
244 }
245
246 pub fn with_email(mut self, email: impl Into<String>) -> Self {
247 self.email = Some(email.into());
248 self
249 }
250
251 pub fn with_name(mut self, name: impl Into<String>) -> Self {
252 self.name = Some(name.into());
253 self
254 }
255
256 pub fn with_email_verified(mut self, verified: bool) -> Self {
257 self.email_verified = Some(verified);
258 self
259 }
260
261 pub fn with_password(mut self, password: impl Into<String>) -> Self {
262 self.password = Some(password.into());
263 self
264 }
265
266 pub fn with_username(mut self, username: impl Into<String>) -> Self {
267 self.username = Some(username.into());
268 self
269 }
270
271 pub fn with_role(mut self, role: impl Into<String>) -> Self {
272 self.role = Some(role.into());
273 self
274 }
275
276 pub fn with_metadata(mut self, metadata: HashMap<String, serde_json::Value>) -> Self {
277 self.metadata = Some(metadata);
278 self
279 }
280}
281
282impl Default for CreateUser {
283 fn default() -> Self {
284 Self::new()
285 }
286}
287
288impl AuthRequest {
289 pub fn new(method: HttpMethod, path: impl Into<String>) -> Self {
290 Self {
291 method,
292 path: path.into(),
293 headers: HashMap::new(),
294 body: None,
295 query: HashMap::new(),
296 }
297 }
298
299 pub fn method(&self) -> &HttpMethod {
300 &self.method
301 }
302
303 pub fn path(&self) -> &str {
304 &self.path
305 }
306
307 pub fn header(&self, name: &str) -> Option<&String> {
308 self.headers.get(name)
309 }
310
311 pub fn body_as_json<T: for<'de> Deserialize<'de>>(&self) -> Result<T, serde_json::Error> {
312 if let Some(body) = &self.body {
313 serde_json::from_slice(body)
314 } else {
315 serde_json::from_str("{}")
316 }
317 }
318}
319
320impl AuthResponse {
321 pub fn new(status: u16) -> Self {
322 Self {
323 status,
324 headers: HashMap::new(),
325 body: Vec::new(),
326 }
327 }
328
329 pub fn json<T: Serialize>(status: u16, data: &T) -> Result<Self, serde_json::Error> {
330 let body = serde_json::to_vec(data)?;
331 let mut headers = HashMap::new();
332 headers.insert("content-type".to_string(), "application/json".to_string());
333
334 Ok(Self {
335 status,
336 headers,
337 body,
338 })
339 }
340
341 pub fn text(status: u16, text: impl Into<String>) -> Self {
342 let body = text.into().into_bytes();
343 let mut headers = HashMap::new();
344 headers.insert("content-type".to_string(), "text/plain".to_string());
345
346 Self {
347 status,
348 headers,
349 body,
350 }
351 }
352
353 pub fn with_header(mut self, name: impl Into<String>, value: impl Into<String>) -> Self {
354 self.headers.insert(name.into(), value.into());
355 self
356 }
357}
358
359#[derive(Debug, Deserialize)]
361pub struct UpdateUserRequest {
362 pub name: Option<String>,
363 pub email: Option<String>,
364 pub image: Option<String>,
365 pub username: Option<String>,
366 #[serde(rename = "displayUsername")]
367 pub display_username: Option<String>,
368 pub role: Option<String>,
369 pub metadata: Option<HashMap<String, serde_json::Value>>,
370}
371
372#[derive(Debug, Serialize)]
373pub struct UpdateUserResponse {
374 pub user: User,
375}
376
377#[derive(Debug, Serialize)]
378pub struct DeleteUserResponse {
379 pub success: bool,
380 pub message: String,
381}
382
383#[cfg(feature = "sqlx-postgres")]
385mod postgres_impls {
386 use super::*;
387 use sqlx::{FromRow, Row};
388 use sqlx::postgres::PgRow;
389
390 impl FromRow<'_, PgRow> for User {
391 fn from_row(row: &PgRow) -> Result<Self, sqlx::Error> {
392 Ok(Self {
393 id: row.try_get("id")?,
394 name: row.try_get("name")?,
395 email: row.try_get("email")?,
396 email_verified: row.try_get("email_verified")?,
397 image: row.try_get("image")?,
398 created_at: row.try_get("created_at")?,
399 updated_at: row.try_get("updated_at")?,
400 username: row.try_get("username")?,
401 display_username: row.try_get("display_username")?,
402 two_factor_enabled: row.try_get("two_factor_enabled").unwrap_or(false),
403 role: row.try_get("role")?,
404 banned: row.try_get("banned").unwrap_or(false),
405 ban_reason: row.try_get("ban_reason")?,
406 ban_expires: row.try_get("ban_expires")?,
407 metadata: {
408 let json_value: sqlx::types::Json<HashMap<String, serde_json::Value>> =
409 row.try_get("metadata")?;
410 json_value.0
411 },
412 })
413 }
414 }
415
416 impl FromRow<'_, PgRow> for Session {
417 fn from_row(row: &PgRow) -> Result<Self, sqlx::Error> {
418 Ok(Self {
419 id: row.try_get("id")?,
420 expires_at: row.try_get("expires_at")?,
421 token: row.try_get("token")?,
422 created_at: row.try_get("created_at")?,
423 updated_at: row.try_get("updated_at")?,
424 ip_address: row.try_get("ip_address")?,
425 user_agent: row.try_get("user_agent")?,
426 user_id: row.try_get("user_id")?,
427 impersonated_by: row.try_get("impersonated_by")?,
428 active_organization_id: row.try_get("active_organization_id")?,
429 active: row.try_get("active").unwrap_or(true),
430 })
431 }
432 }
433
434 impl FromRow<'_, PgRow> for Account {
435 fn from_row(row: &PgRow) -> Result<Self, sqlx::Error> {
436 Ok(Self {
437 id: row.try_get("id")?,
438 account_id: row.try_get("account_id")?,
439 provider_id: row.try_get("provider_id")?,
440 user_id: row.try_get("user_id")?,
441 access_token: row.try_get("access_token")?,
442 refresh_token: row.try_get("refresh_token")?,
443 id_token: row.try_get("id_token")?,
444 access_token_expires_at: row.try_get("access_token_expires_at")?,
445 refresh_token_expires_at: row.try_get("refresh_token_expires_at")?,
446 scope: row.try_get("scope")?,
447 password: row.try_get("password")?,
448 created_at: row.try_get("created_at")?,
449 updated_at: row.try_get("updated_at")?,
450 })
451 }
452 }
453}