1use async_trait::async_trait;
2use chrono::{DateTime, Utc};
3use std::collections::HashMap;
4use std::sync::{Arc, Mutex};
5use uuid::Uuid;
6
7use crate::entity::{
8 AuthAccount, AuthInvitation, AuthMember, AuthOrganization, AuthSession, AuthUser,
9 AuthVerification,
10};
11use crate::error::{AuthError, AuthResult};
12use crate::types::{
13 Account, CreateAccount, CreateInvitation, CreateMember, CreateOrganization, CreateSession,
14 CreateUser, CreateVerification, Invitation, InvitationStatus, Member, Organization, Session,
15 UpdateOrganization, UpdateUser, User, Verification,
16};
17
18use super::DatabaseAdapter;
19
20pub trait MemoryUser: AuthUser {
28 fn from_create(id: String, create: &CreateUser, now: DateTime<Utc>) -> Self;
30 fn apply_update(&mut self, update: &UpdateUser);
32}
33
34pub trait MemorySession: AuthSession {
36 fn from_create(id: String, token: String, create: &CreateSession, now: DateTime<Utc>) -> Self;
38 fn set_expires_at(&mut self, at: DateTime<Utc>);
39 fn set_active_organization_id(&mut self, org_id: Option<String>);
40 fn set_updated_at(&mut self, at: DateTime<Utc>);
41}
42
43pub trait MemoryAccount: AuthAccount {
45 fn from_create(id: String, create: &CreateAccount, now: DateTime<Utc>) -> Self;
46}
47
48pub trait MemoryVerification: AuthVerification {
50 fn from_create(id: String, create: &CreateVerification, now: DateTime<Utc>) -> Self;
51}
52
53pub trait MemoryOrganization: AuthOrganization {
55 fn from_create(id: String, create: &CreateOrganization, now: DateTime<Utc>) -> Self;
56 fn apply_update(&mut self, update: &UpdateOrganization);
57}
58
59pub trait MemoryMember: AuthMember {
61 fn from_create(id: String, create: &CreateMember, now: DateTime<Utc>) -> Self;
62 fn set_role(&mut self, role: String);
63}
64
65pub trait MemoryInvitation: AuthInvitation {
67 fn from_create(id: String, create: &CreateInvitation, now: DateTime<Utc>) -> Self;
68 fn set_status(&mut self, status: InvitationStatus);
69}
70
71impl MemoryUser for User {
74 fn from_create(id: String, create: &CreateUser, now: DateTime<Utc>) -> Self {
75 User {
76 id,
77 name: create.name.clone(),
78 email: create.email.clone(),
79 email_verified: create.email_verified.unwrap_or(false),
80 image: create.image.clone(),
81 created_at: now,
82 updated_at: now,
83 username: create.username.clone(),
84 display_username: create.display_username.clone(),
85 two_factor_enabled: false,
86 role: create.role.clone(),
87 banned: false,
88 ban_reason: None,
89 ban_expires: None,
90 metadata: create.metadata.clone().unwrap_or_default(),
91 }
92 }
93
94 fn apply_update(&mut self, update: &UpdateUser) {
95 if let Some(email) = &update.email {
96 self.email = Some(email.clone());
97 }
98 if let Some(name) = &update.name {
99 self.name = Some(name.clone());
100 }
101 if let Some(image) = &update.image {
102 self.image = Some(image.clone());
103 }
104 if let Some(email_verified) = update.email_verified {
105 self.email_verified = email_verified;
106 }
107 if let Some(username) = &update.username {
108 self.username = Some(username.clone());
109 }
110 if let Some(display_username) = &update.display_username {
111 self.display_username = Some(display_username.clone());
112 }
113 if let Some(role) = &update.role {
114 self.role = Some(role.clone());
115 }
116 if let Some(banned) = update.banned {
117 self.banned = banned;
118 }
119 if let Some(ban_reason) = &update.ban_reason {
120 self.ban_reason = Some(ban_reason.clone());
121 }
122 if let Some(ban_expires) = update.ban_expires {
123 self.ban_expires = Some(ban_expires);
124 }
125 if let Some(two_factor_enabled) = update.two_factor_enabled {
126 self.two_factor_enabled = two_factor_enabled;
127 }
128 if let Some(metadata) = &update.metadata {
129 self.metadata = metadata.clone();
130 }
131 self.updated_at = Utc::now();
132 }
133}
134
135impl MemorySession for Session {
136 fn from_create(id: String, token: String, create: &CreateSession, now: DateTime<Utc>) -> Self {
137 Session {
138 id,
139 token,
140 expires_at: create.expires_at,
141 created_at: now,
142 updated_at: now,
143 ip_address: create.ip_address.clone(),
144 user_agent: create.user_agent.clone(),
145 user_id: create.user_id.clone(),
146 impersonated_by: create.impersonated_by.clone(),
147 active_organization_id: create.active_organization_id.clone(),
148 active: true,
149 }
150 }
151
152 fn set_expires_at(&mut self, at: DateTime<Utc>) {
153 self.expires_at = at;
154 }
155
156 fn set_active_organization_id(&mut self, org_id: Option<String>) {
157 self.active_organization_id = org_id;
158 }
159
160 fn set_updated_at(&mut self, at: DateTime<Utc>) {
161 self.updated_at = at;
162 }
163}
164
165impl MemoryAccount for Account {
166 fn from_create(id: String, create: &CreateAccount, now: DateTime<Utc>) -> Self {
167 Account {
168 id,
169 account_id: create.account_id.clone(),
170 provider_id: create.provider_id.clone(),
171 user_id: create.user_id.clone(),
172 access_token: create.access_token.clone(),
173 refresh_token: create.refresh_token.clone(),
174 id_token: create.id_token.clone(),
175 access_token_expires_at: create.access_token_expires_at,
176 refresh_token_expires_at: create.refresh_token_expires_at,
177 scope: create.scope.clone(),
178 password: create.password.clone(),
179 created_at: now,
180 updated_at: now,
181 }
182 }
183}
184
185impl MemoryVerification for Verification {
186 fn from_create(id: String, create: &CreateVerification, now: DateTime<Utc>) -> Self {
187 Verification {
188 id,
189 identifier: create.identifier.clone(),
190 value: create.value.clone(),
191 expires_at: create.expires_at,
192 created_at: now,
193 updated_at: now,
194 }
195 }
196}
197
198impl MemoryOrganization for Organization {
199 fn from_create(id: String, create: &CreateOrganization, now: DateTime<Utc>) -> Self {
200 Organization {
201 id,
202 name: create.name.clone(),
203 slug: create.slug.clone(),
204 logo: create.logo.clone(),
205 metadata: create.metadata.clone(),
206 created_at: now,
207 updated_at: now,
208 }
209 }
210
211 fn apply_update(&mut self, update: &UpdateOrganization) {
212 if let Some(name) = &update.name {
213 self.name = name.clone();
214 }
215 if let Some(slug) = &update.slug {
216 self.slug = slug.clone();
217 }
218 if let Some(logo) = &update.logo {
219 self.logo = Some(logo.clone());
220 }
221 if let Some(metadata) = &update.metadata {
222 self.metadata = Some(metadata.clone());
223 }
224 self.updated_at = Utc::now();
225 }
226}
227
228impl MemoryMember for Member {
229 fn from_create(id: String, create: &CreateMember, now: DateTime<Utc>) -> Self {
230 Member {
231 id,
232 organization_id: create.organization_id.clone(),
233 user_id: create.user_id.clone(),
234 role: create.role.clone(),
235 created_at: now,
236 }
237 }
238
239 fn set_role(&mut self, role: String) {
240 self.role = role;
241 }
242}
243
244impl MemoryInvitation for Invitation {
245 fn from_create(id: String, create: &CreateInvitation, now: DateTime<Utc>) -> Self {
246 Invitation {
247 id,
248 organization_id: create.organization_id.clone(),
249 email: create.email.clone(),
250 role: create.role.clone(),
251 status: InvitationStatus::Pending,
252 inviter_id: create.inviter_id.clone(),
253 expires_at: create.expires_at,
254 created_at: now,
255 }
256 }
257
258 fn set_status(&mut self, status: InvitationStatus) {
259 self.status = status;
260 }
261}
262
263pub struct MemoryDatabaseAdapter<
280 U = User,
281 S = Session,
282 A = Account,
283 O = Organization,
284 M = Member,
285 I = Invitation,
286 V = Verification,
287> {
288 users: Arc<Mutex<HashMap<String, U>>>,
289 sessions: Arc<Mutex<HashMap<String, S>>>,
290 accounts: Arc<Mutex<HashMap<String, A>>>,
291 verifications: Arc<Mutex<HashMap<String, V>>>,
292 email_index: Arc<Mutex<HashMap<String, String>>>,
293 username_index: Arc<Mutex<HashMap<String, String>>>,
294 organizations: Arc<Mutex<HashMap<String, O>>>,
295 members: Arc<Mutex<HashMap<String, M>>>,
296 invitations: Arc<Mutex<HashMap<String, I>>>,
297 slug_index: Arc<Mutex<HashMap<String, String>>>,
298}
299
300impl MemoryDatabaseAdapter {
303 pub fn new() -> Self {
304 Self::default()
305 }
306}
307
308impl<U, S, A, O, M, I, V> Default for MemoryDatabaseAdapter<U, S, A, O, M, I, V> {
309 fn default() -> Self {
310 Self {
311 users: Arc::new(Mutex::new(HashMap::new())),
312 sessions: Arc::new(Mutex::new(HashMap::new())),
313 accounts: Arc::new(Mutex::new(HashMap::new())),
314 verifications: Arc::new(Mutex::new(HashMap::new())),
315 email_index: Arc::new(Mutex::new(HashMap::new())),
316 username_index: Arc::new(Mutex::new(HashMap::new())),
317 organizations: Arc::new(Mutex::new(HashMap::new())),
318 members: Arc::new(Mutex::new(HashMap::new())),
319 invitations: Arc::new(Mutex::new(HashMap::new())),
320 slug_index: Arc::new(Mutex::new(HashMap::new())),
321 }
322 }
323}
324
325#[async_trait]
326impl<U, S, A, O, M, I, V> DatabaseAdapter for MemoryDatabaseAdapter<U, S, A, O, M, I, V>
327where
328 U: MemoryUser,
329 S: MemorySession,
330 A: MemoryAccount,
331 O: MemoryOrganization,
332 M: MemoryMember,
333 I: MemoryInvitation,
334 V: MemoryVerification,
335{
336 type User = U;
337 type Session = S;
338 type Account = A;
339 type Organization = O;
340 type Member = M;
341 type Invitation = I;
342 type Verification = V;
343
344 async fn create_user(&self, create_user: CreateUser) -> AuthResult<U> {
347 let mut users = self.users.lock().unwrap();
348 let mut email_index = self.email_index.lock().unwrap();
349 let mut username_index = self.username_index.lock().unwrap();
350
351 let id = create_user
352 .id
353 .clone()
354 .unwrap_or_else(|| Uuid::new_v4().to_string());
355
356 if let Some(email) = &create_user.email
357 && email_index.contains_key(email)
358 {
359 return Err(AuthError::config("Email already exists"));
360 }
361
362 if let Some(username) = &create_user.username
363 && username_index.contains_key(username)
364 {
365 return Err(AuthError::conflict(
366 "A user with this username already exists",
367 ));
368 }
369
370 let now = Utc::now();
371 let user = U::from_create(id.clone(), &create_user, now);
372
373 users.insert(id.clone(), user.clone());
374
375 if let Some(email) = &create_user.email {
376 email_index.insert(email.clone(), id.clone());
377 }
378 if let Some(username) = &create_user.username {
379 username_index.insert(username.clone(), id);
380 }
381
382 Ok(user)
383 }
384
385 async fn get_user_by_id(&self, id: &str) -> AuthResult<Option<U>> {
386 let users = self.users.lock().unwrap();
387 Ok(users.get(id).cloned())
388 }
389
390 async fn get_user_by_email(&self, email: &str) -> AuthResult<Option<U>> {
391 let email_index = self.email_index.lock().unwrap();
392 let users = self.users.lock().unwrap();
393
394 if let Some(user_id) = email_index.get(email) {
395 Ok(users.get(user_id).cloned())
396 } else {
397 Ok(None)
398 }
399 }
400
401 async fn get_user_by_username(&self, username: &str) -> AuthResult<Option<U>> {
402 let username_index = self.username_index.lock().unwrap();
403 let users = self.users.lock().unwrap();
404
405 if let Some(user_id) = username_index.get(username) {
406 Ok(users.get(user_id).cloned())
407 } else {
408 Ok(None)
409 }
410 }
411
412 async fn update_user(&self, id: &str, update: UpdateUser) -> AuthResult<U> {
413 let mut users = self.users.lock().unwrap();
414 let mut email_index = self.email_index.lock().unwrap();
415 let mut username_index = self.username_index.lock().unwrap();
416
417 let user = users.get_mut(id).ok_or(AuthError::UserNotFound)?;
418
419 if let Some(new_email) = &update.email {
421 if let Some(old_email) = user.email() {
422 email_index.remove(old_email);
423 }
424 email_index.insert(new_email.clone(), id.to_string());
425 }
426
427 if let Some(ref new_username) = update.username {
428 if let Some(old_username) = user.username() {
429 username_index.remove(old_username);
430 }
431 username_index.insert(new_username.clone(), id.to_string());
432 }
433
434 user.apply_update(&update);
435 Ok(user.clone())
436 }
437
438 async fn delete_user(&self, id: &str) -> AuthResult<()> {
439 let mut users = self.users.lock().unwrap();
440 let mut email_index = self.email_index.lock().unwrap();
441 let mut username_index = self.username_index.lock().unwrap();
442
443 if let Some(user) = users.remove(id) {
444 if let Some(email) = user.email() {
445 email_index.remove(email);
446 }
447 if let Some(username) = user.username() {
448 username_index.remove(username);
449 }
450 }
451
452 Ok(())
453 }
454
455 async fn create_session(&self, create_session: CreateSession) -> AuthResult<S> {
458 let mut sessions = self.sessions.lock().unwrap();
459
460 let id = Uuid::new_v4().to_string();
461 let token = format!("session_{}", Uuid::new_v4());
462 let now = Utc::now();
463 let session = S::from_create(id, token.clone(), &create_session, now);
464
465 sessions.insert(token, session.clone());
466 Ok(session)
467 }
468
469 async fn get_session(&self, token: &str) -> AuthResult<Option<S>> {
470 let sessions = self.sessions.lock().unwrap();
471 Ok(sessions.get(token).cloned())
472 }
473
474 async fn get_user_sessions(&self, user_id: &str) -> AuthResult<Vec<S>> {
475 let sessions = self.sessions.lock().unwrap();
476 Ok(sessions
477 .values()
478 .filter(|s| s.user_id() == user_id && s.active())
479 .cloned()
480 .collect())
481 }
482
483 async fn update_session_expiry(
484 &self,
485 token: &str,
486 expires_at: DateTime<Utc>,
487 ) -> AuthResult<()> {
488 let mut sessions = self.sessions.lock().unwrap();
489 if let Some(session) = sessions.get_mut(token) {
490 session.set_expires_at(expires_at);
491 }
492 Ok(())
493 }
494
495 async fn delete_session(&self, token: &str) -> AuthResult<()> {
496 let mut sessions = self.sessions.lock().unwrap();
497 sessions.remove(token);
498 Ok(())
499 }
500
501 async fn delete_user_sessions(&self, user_id: &str) -> AuthResult<()> {
502 let mut sessions = self.sessions.lock().unwrap();
503 sessions.retain(|_, s| s.user_id() != user_id);
504 Ok(())
505 }
506
507 async fn delete_expired_sessions(&self) -> AuthResult<usize> {
508 let mut sessions = self.sessions.lock().unwrap();
509 let now = Utc::now();
510 let initial_count = sessions.len();
511 sessions.retain(|_, s| s.expires_at() > now && s.active());
512 Ok(initial_count - sessions.len())
513 }
514
515 async fn create_account(&self, create_account: CreateAccount) -> AuthResult<A> {
518 let mut accounts = self.accounts.lock().unwrap();
519
520 let id = Uuid::new_v4().to_string();
521 let now = Utc::now();
522 let account = A::from_create(id.clone(), &create_account, now);
523
524 accounts.insert(id, account.clone());
525 Ok(account)
526 }
527
528 async fn get_account(
529 &self,
530 provider: &str,
531 provider_account_id: &str,
532 ) -> AuthResult<Option<A>> {
533 let accounts = self.accounts.lock().unwrap();
534 Ok(accounts
535 .values()
536 .find(|acc| acc.provider_id() == provider && acc.account_id() == provider_account_id)
537 .cloned())
538 }
539
540 async fn get_user_accounts(&self, user_id: &str) -> AuthResult<Vec<A>> {
541 let accounts = self.accounts.lock().unwrap();
542 Ok(accounts
543 .values()
544 .filter(|acc| acc.user_id() == user_id)
545 .cloned()
546 .collect())
547 }
548
549 async fn delete_account(&self, id: &str) -> AuthResult<()> {
550 let mut accounts = self.accounts.lock().unwrap();
551 accounts.remove(id);
552 Ok(())
553 }
554
555 async fn create_verification(&self, create_verification: CreateVerification) -> AuthResult<V> {
558 let mut verifications = self.verifications.lock().unwrap();
559
560 let id = Uuid::new_v4().to_string();
561 let now = Utc::now();
562 let verification = V::from_create(id.clone(), &create_verification, now);
563
564 verifications.insert(id, verification.clone());
565 Ok(verification)
566 }
567
568 async fn get_verification(&self, identifier: &str, value: &str) -> AuthResult<Option<V>> {
569 let verifications = self.verifications.lock().unwrap();
570 let now = Utc::now();
571 Ok(verifications
572 .values()
573 .find(|v| v.identifier() == identifier && v.value() == value && v.expires_at() > now)
574 .cloned())
575 }
576
577 async fn get_verification_by_value(&self, value: &str) -> AuthResult<Option<V>> {
578 let verifications = self.verifications.lock().unwrap();
579 let now = Utc::now();
580 Ok(verifications
581 .values()
582 .find(|v| v.value() == value && v.expires_at() > now)
583 .cloned())
584 }
585
586 async fn delete_verification(&self, id: &str) -> AuthResult<()> {
587 let mut verifications = self.verifications.lock().unwrap();
588 verifications.remove(id);
589 Ok(())
590 }
591
592 async fn delete_expired_verifications(&self) -> AuthResult<usize> {
593 let mut verifications = self.verifications.lock().unwrap();
594 let now = Utc::now();
595 let initial_count = verifications.len();
596 verifications.retain(|_, v| v.expires_at() > now);
597 Ok(initial_count - verifications.len())
598 }
599
600 async fn create_organization(&self, create_org: CreateOrganization) -> AuthResult<O> {
603 let mut organizations = self.organizations.lock().unwrap();
604 let mut slug_index = self.slug_index.lock().unwrap();
605
606 if slug_index.contains_key(&create_org.slug) {
607 return Err(AuthError::conflict("Organization slug already exists"));
608 }
609
610 let id = create_org
611 .id
612 .clone()
613 .unwrap_or_else(|| Uuid::new_v4().to_string());
614 let now = Utc::now();
615 let organization = O::from_create(id.clone(), &create_org, now);
616
617 organizations.insert(id.clone(), organization.clone());
618 slug_index.insert(create_org.slug.clone(), id);
619
620 Ok(organization)
621 }
622
623 async fn get_organization_by_id(&self, id: &str) -> AuthResult<Option<O>> {
624 let organizations = self.organizations.lock().unwrap();
625 Ok(organizations.get(id).cloned())
626 }
627
628 async fn get_organization_by_slug(&self, slug: &str) -> AuthResult<Option<O>> {
629 let slug_index = self.slug_index.lock().unwrap();
630 let organizations = self.organizations.lock().unwrap();
631
632 if let Some(org_id) = slug_index.get(slug) {
633 Ok(organizations.get(org_id).cloned())
634 } else {
635 Ok(None)
636 }
637 }
638
639 async fn update_organization(&self, id: &str, update: UpdateOrganization) -> AuthResult<O> {
640 let mut organizations = self.organizations.lock().unwrap();
641 let mut slug_index = self.slug_index.lock().unwrap();
642
643 let org = organizations
644 .get_mut(id)
645 .ok_or_else(|| AuthError::not_found("Organization not found"))?;
646
647 if let Some(new_slug) = &update.slug {
649 let current_slug = org.slug().to_string();
650 if *new_slug != current_slug {
651 if slug_index.contains_key(new_slug.as_str()) {
652 return Err(AuthError::conflict("Organization slug already exists"));
653 }
654 slug_index.remove(¤t_slug);
655 slug_index.insert(new_slug.clone(), id.to_string());
656 }
657 }
658
659 org.apply_update(&update);
660 Ok(org.clone())
661 }
662
663 async fn delete_organization(&self, id: &str) -> AuthResult<()> {
664 let mut organizations = self.organizations.lock().unwrap();
665 let mut slug_index = self.slug_index.lock().unwrap();
666 let mut members = self.members.lock().unwrap();
667 let mut invitations = self.invitations.lock().unwrap();
668
669 if let Some(org) = organizations.remove(id) {
670 slug_index.remove(org.slug());
671 }
672
673 members.retain(|_, m| m.organization_id() != id);
674 invitations.retain(|_, i| i.organization_id() != id);
675
676 Ok(())
677 }
678
679 async fn list_user_organizations(&self, user_id: &str) -> AuthResult<Vec<O>> {
680 let members = self.members.lock().unwrap();
681 let organizations = self.organizations.lock().unwrap();
682
683 let org_ids: Vec<String> = members
684 .values()
685 .filter(|m| m.user_id() == user_id)
686 .map(|m| m.organization_id().to_string())
687 .collect();
688
689 let orgs = org_ids
690 .iter()
691 .filter_map(|id| organizations.get(id).cloned())
692 .collect();
693
694 Ok(orgs)
695 }
696
697 async fn create_member(&self, create_member: CreateMember) -> AuthResult<M> {
700 let mut members = self.members.lock().unwrap();
701
702 let exists = members.values().any(|m| {
703 m.organization_id() == create_member.organization_id
704 && m.user_id() == create_member.user_id
705 });
706
707 if exists {
708 return Err(AuthError::conflict(
709 "User is already a member of this organization",
710 ));
711 }
712
713 let id = Uuid::new_v4().to_string();
714 let now = Utc::now();
715 let member = M::from_create(id.clone(), &create_member, now);
716
717 members.insert(id, member.clone());
718 Ok(member)
719 }
720
721 async fn get_member(&self, organization_id: &str, user_id: &str) -> AuthResult<Option<M>> {
722 let members = self.members.lock().unwrap();
723 Ok(members
724 .values()
725 .find(|m| m.organization_id() == organization_id && m.user_id() == user_id)
726 .cloned())
727 }
728
729 async fn get_member_by_id(&self, id: &str) -> AuthResult<Option<M>> {
730 let members = self.members.lock().unwrap();
731 Ok(members.get(id).cloned())
732 }
733
734 async fn update_member_role(&self, member_id: &str, role: &str) -> AuthResult<M> {
735 let mut members = self.members.lock().unwrap();
736 let member = members
737 .get_mut(member_id)
738 .ok_or_else(|| AuthError::not_found("Member not found"))?;
739 member.set_role(role.to_string());
740 Ok(member.clone())
741 }
742
743 async fn delete_member(&self, member_id: &str) -> AuthResult<()> {
744 let mut members = self.members.lock().unwrap();
745 members.remove(member_id);
746 Ok(())
747 }
748
749 async fn list_organization_members(&self, organization_id: &str) -> AuthResult<Vec<M>> {
750 let members = self.members.lock().unwrap();
751 Ok(members
752 .values()
753 .filter(|m| m.organization_id() == organization_id)
754 .cloned()
755 .collect())
756 }
757
758 async fn count_organization_members(&self, organization_id: &str) -> AuthResult<usize> {
759 let members = self.members.lock().unwrap();
760 Ok(members
761 .values()
762 .filter(|m| m.organization_id() == organization_id)
763 .count())
764 }
765
766 async fn count_organization_owners(&self, organization_id: &str) -> AuthResult<usize> {
767 let members = self.members.lock().unwrap();
768 Ok(members
769 .values()
770 .filter(|m| m.organization_id() == organization_id && m.role() == "owner")
771 .count())
772 }
773
774 async fn create_invitation(&self, create_inv: CreateInvitation) -> AuthResult<I> {
777 let mut invitations = self.invitations.lock().unwrap();
778
779 let id = Uuid::new_v4().to_string();
780 let now = Utc::now();
781 let invitation = I::from_create(id.clone(), &create_inv, now);
782
783 invitations.insert(id, invitation.clone());
784 Ok(invitation)
785 }
786
787 async fn get_invitation_by_id(&self, id: &str) -> AuthResult<Option<I>> {
788 let invitations = self.invitations.lock().unwrap();
789 Ok(invitations.get(id).cloned())
790 }
791
792 async fn get_pending_invitation(
793 &self,
794 organization_id: &str,
795 email: &str,
796 ) -> AuthResult<Option<I>> {
797 let invitations = self.invitations.lock().unwrap();
798 Ok(invitations
799 .values()
800 .find(|i| {
801 i.organization_id() == organization_id
802 && i.email().to_lowercase() == email.to_lowercase()
803 && *i.status() == InvitationStatus::Pending
804 })
805 .cloned())
806 }
807
808 async fn update_invitation_status(&self, id: &str, status: InvitationStatus) -> AuthResult<I> {
809 let mut invitations = self.invitations.lock().unwrap();
810 let invitation = invitations
811 .get_mut(id)
812 .ok_or_else(|| AuthError::not_found("Invitation not found"))?;
813 invitation.set_status(status);
814 Ok(invitation.clone())
815 }
816
817 async fn list_organization_invitations(&self, organization_id: &str) -> AuthResult<Vec<I>> {
818 let invitations = self.invitations.lock().unwrap();
819 Ok(invitations
820 .values()
821 .filter(|i| i.organization_id() == organization_id)
822 .cloned()
823 .collect())
824 }
825
826 async fn list_user_invitations(&self, email: &str) -> AuthResult<Vec<I>> {
827 let invitations = self.invitations.lock().unwrap();
828 let now = Utc::now();
829 Ok(invitations
830 .values()
831 .filter(|i| {
832 i.email().to_lowercase() == email.to_lowercase()
833 && *i.status() == InvitationStatus::Pending
834 && i.expires_at() > now
835 })
836 .cloned()
837 .collect())
838 }
839
840 async fn update_session_active_organization(
843 &self,
844 token: &str,
845 organization_id: Option<&str>,
846 ) -> AuthResult<S> {
847 let mut sessions = self.sessions.lock().unwrap();
848 let session = sessions.get_mut(token).ok_or(AuthError::SessionNotFound)?;
849 session.set_active_organization_id(organization_id.map(|s| s.to_string()));
850 session.set_updated_at(Utc::now());
851 Ok(session.clone())
852 }
853}