Skip to main content

better_auth_core/adapters/
traits.rs

1use async_trait::async_trait;
2use chrono::{DateTime, Utc};
3
4use crate::entity::{
5    AuthAccount, AuthApiKey, AuthInvitation, AuthMember, AuthOrganization, AuthPasskey,
6    AuthSession, AuthTwoFactor, AuthUser, AuthVerification,
7};
8use crate::error::AuthResult;
9use crate::types::{
10    CreateAccount, CreateApiKey, CreateInvitation, CreateMember, CreateOrganization, CreatePasskey,
11    CreateSession, CreateTwoFactor, CreateUser, CreateVerification, InvitationStatus,
12    ListUsersParams, UpdateAccount, UpdateApiKey, UpdateOrganization, UpdateUser,
13};
14
15/// User persistence operations.
16#[async_trait]
17pub trait UserOps: Send + Sync + 'static {
18    type User: AuthUser;
19
20    async fn create_user(&self, user: CreateUser) -> AuthResult<Self::User>;
21    async fn get_user_by_id(&self, id: &str) -> AuthResult<Option<Self::User>>;
22    async fn get_user_by_email(&self, email: &str) -> AuthResult<Option<Self::User>>;
23    async fn get_user_by_username(&self, username: &str) -> AuthResult<Option<Self::User>>;
24    async fn update_user(&self, id: &str, update: UpdateUser) -> AuthResult<Self::User>;
25    async fn delete_user(&self, id: &str) -> AuthResult<()>;
26    /// List users with optional filtering, sorting, and pagination.
27    /// Returns `(users, total_count)`.
28    async fn list_users(&self, params: ListUsersParams) -> AuthResult<(Vec<Self::User>, usize)>;
29}
30
31/// Session persistence operations.
32#[async_trait]
33pub trait SessionOps: Send + Sync + 'static {
34    type Session: AuthSession;
35
36    async fn create_session(&self, session: CreateSession) -> AuthResult<Self::Session>;
37    async fn get_session(&self, token: &str) -> AuthResult<Option<Self::Session>>;
38    async fn get_user_sessions(&self, user_id: &str) -> AuthResult<Vec<Self::Session>>;
39    async fn update_session_expiry(&self, token: &str, expires_at: DateTime<Utc>)
40    -> AuthResult<()>;
41    async fn delete_session(&self, token: &str) -> AuthResult<()>;
42    async fn delete_user_sessions(&self, user_id: &str) -> AuthResult<()>;
43    async fn delete_expired_sessions(&self) -> AuthResult<usize>;
44    async fn update_session_active_organization(
45        &self,
46        token: &str,
47        organization_id: Option<&str>,
48    ) -> AuthResult<Self::Session>;
49}
50
51/// Account (OAuth provider linking) persistence operations.
52#[async_trait]
53pub trait AccountOps: Send + Sync + 'static {
54    type Account: AuthAccount;
55
56    async fn create_account(&self, account: CreateAccount) -> AuthResult<Self::Account>;
57    async fn get_account(
58        &self,
59        provider: &str,
60        provider_account_id: &str,
61    ) -> AuthResult<Option<Self::Account>>;
62    async fn get_user_accounts(&self, user_id: &str) -> AuthResult<Vec<Self::Account>>;
63    async fn update_account(&self, id: &str, update: UpdateAccount) -> AuthResult<Self::Account>;
64    async fn delete_account(&self, id: &str) -> AuthResult<()>;
65}
66
67/// Verification token persistence operations.
68#[async_trait]
69pub trait VerificationOps: Send + Sync + 'static {
70    type Verification: AuthVerification;
71
72    async fn create_verification(
73        &self,
74        verification: CreateVerification,
75    ) -> AuthResult<Self::Verification>;
76    async fn get_verification(
77        &self,
78        identifier: &str,
79        value: &str,
80    ) -> AuthResult<Option<Self::Verification>>;
81    async fn get_verification_by_value(
82        &self,
83        value: &str,
84    ) -> AuthResult<Option<Self::Verification>>;
85    async fn get_verification_by_identifier(
86        &self,
87        identifier: &str,
88    ) -> AuthResult<Option<Self::Verification>> {
89        let _ = identifier;
90        Ok(None)
91    }
92    /// Atomically consume a verification token identified by `(identifier, value)`.
93    ///
94    /// Implementations should remove the token if it exists and is valid, then
95    /// return the removed record. This prevents replay and race windows from
96    /// split read-then-delete flows.
97    async fn consume_verification(
98        &self,
99        identifier: &str,
100        value: &str,
101    ) -> AuthResult<Option<Self::Verification>>;
102    async fn delete_verification(&self, id: &str) -> AuthResult<()>;
103    async fn delete_expired_verifications(&self) -> AuthResult<usize>;
104}
105
106/// Organization persistence operations.
107#[async_trait]
108pub trait OrganizationOps: Send + Sync + 'static {
109    type Organization: AuthOrganization;
110
111    async fn create_organization(&self, org: CreateOrganization) -> AuthResult<Self::Organization>;
112    async fn get_organization_by_id(&self, id: &str) -> AuthResult<Option<Self::Organization>>;
113    async fn get_organization_by_slug(&self, slug: &str) -> AuthResult<Option<Self::Organization>>;
114    async fn update_organization(
115        &self,
116        id: &str,
117        update: UpdateOrganization,
118    ) -> AuthResult<Self::Organization>;
119    async fn delete_organization(&self, id: &str) -> AuthResult<()>;
120    async fn list_user_organizations(&self, user_id: &str) -> AuthResult<Vec<Self::Organization>>;
121}
122
123/// Organization member persistence operations.
124#[async_trait]
125pub trait MemberOps: Send + Sync + 'static {
126    type Member: AuthMember;
127
128    async fn create_member(&self, member: CreateMember) -> AuthResult<Self::Member>;
129    async fn get_member(
130        &self,
131        organization_id: &str,
132        user_id: &str,
133    ) -> AuthResult<Option<Self::Member>>;
134    async fn get_member_by_id(&self, id: &str) -> AuthResult<Option<Self::Member>>;
135    async fn update_member_role(&self, member_id: &str, role: &str) -> AuthResult<Self::Member>;
136    async fn delete_member(&self, member_id: &str) -> AuthResult<()>;
137    async fn list_organization_members(
138        &self,
139        organization_id: &str,
140    ) -> AuthResult<Vec<Self::Member>>;
141    async fn count_organization_members(&self, organization_id: &str) -> AuthResult<usize>;
142    async fn count_organization_owners(&self, organization_id: &str) -> AuthResult<usize>;
143}
144
145/// Invitation persistence operations.
146#[async_trait]
147pub trait InvitationOps: Send + Sync + 'static {
148    type Invitation: AuthInvitation;
149
150    async fn create_invitation(&self, invitation: CreateInvitation)
151    -> AuthResult<Self::Invitation>;
152    async fn get_invitation_by_id(&self, id: &str) -> AuthResult<Option<Self::Invitation>>;
153    async fn get_pending_invitation(
154        &self,
155        organization_id: &str,
156        email: &str,
157    ) -> AuthResult<Option<Self::Invitation>>;
158    async fn update_invitation_status(
159        &self,
160        id: &str,
161        status: InvitationStatus,
162    ) -> AuthResult<Self::Invitation>;
163    async fn list_organization_invitations(
164        &self,
165        organization_id: &str,
166    ) -> AuthResult<Vec<Self::Invitation>>;
167    async fn list_user_invitations(&self, email: &str) -> AuthResult<Vec<Self::Invitation>>;
168}
169
170/// Two-factor authentication persistence operations.
171#[async_trait]
172pub trait TwoFactorOps: Send + Sync + 'static {
173    type TwoFactor: AuthTwoFactor;
174
175    async fn create_two_factor(&self, two_factor: CreateTwoFactor) -> AuthResult<Self::TwoFactor>;
176    async fn get_two_factor_by_user_id(&self, user_id: &str)
177    -> AuthResult<Option<Self::TwoFactor>>;
178    async fn update_two_factor_backup_codes(
179        &self,
180        user_id: &str,
181        backup_codes: &str,
182    ) -> AuthResult<Self::TwoFactor>;
183    async fn delete_two_factor(&self, user_id: &str) -> AuthResult<()>;
184}
185
186/// API key persistence operations.
187#[async_trait]
188pub trait ApiKeyOps: Send + Sync + 'static {
189    type ApiKey: AuthApiKey;
190
191    async fn create_api_key(&self, input: CreateApiKey) -> AuthResult<Self::ApiKey>;
192    async fn get_api_key_by_id(&self, id: &str) -> AuthResult<Option<Self::ApiKey>>;
193    async fn get_api_key_by_hash(&self, hash: &str) -> AuthResult<Option<Self::ApiKey>>;
194    async fn list_api_keys_by_user(&self, user_id: &str) -> AuthResult<Vec<Self::ApiKey>>;
195    async fn update_api_key(&self, id: &str, update: UpdateApiKey) -> AuthResult<Self::ApiKey>;
196    async fn delete_api_key(&self, id: &str) -> AuthResult<()>;
197    /// Delete all API keys whose `expires_at` is in the past. Returns the count of deleted keys.
198    async fn delete_expired_api_keys(&self) -> AuthResult<usize>;
199}
200
201/// Passkey persistence operations.
202#[async_trait]
203pub trait PasskeyOps: Send + Sync + 'static {
204    type Passkey: AuthPasskey;
205
206    async fn create_passkey(&self, input: CreatePasskey) -> AuthResult<Self::Passkey>;
207    async fn get_passkey_by_id(&self, id: &str) -> AuthResult<Option<Self::Passkey>>;
208    async fn get_passkey_by_credential_id(
209        &self,
210        credential_id: &str,
211    ) -> AuthResult<Option<Self::Passkey>>;
212    async fn list_passkeys_by_user(&self, user_id: &str) -> AuthResult<Vec<Self::Passkey>>;
213    async fn update_passkey_counter(&self, id: &str, counter: u64) -> AuthResult<Self::Passkey>;
214    async fn update_passkey_name(&self, id: &str, name: &str) -> AuthResult<Self::Passkey>;
215    async fn delete_passkey(&self, id: &str) -> AuthResult<()>;
216}