Skip to main content

better_auth_api/plugins/
mod.rs

1pub mod account_management;
2pub mod admin;
3pub mod api_key;
4pub mod device_authorization;
5pub mod email_password;
6pub mod email_verification;
7pub mod helpers;
8pub mod oauth;
9pub mod organization;
10pub mod passkey;
11pub mod password_management;
12pub mod session_management;
13pub mod two_factor;
14pub mod user_management;
15
16use serde::{Deserialize, Serialize};
17
18#[derive(Debug, Serialize, Deserialize)]
19pub(crate) struct StatusResponse {
20    status: bool,
21}
22
23#[cfg(test)]
24pub(crate) mod test_helpers {
25    use std::collections::HashMap;
26    use std::sync::Arc;
27
28    use better_auth_core::config::AuthConfig;
29    use better_auth_core::wire::{SessionView, UserView};
30    use better_auth_core::{AuthContext, AuthRequest, CreateSession, CreateUser, HttpMethod};
31    use better_auth_seaorm::store::__private_test_support::bundled_schema::BundledSchema;
32    use better_auth_seaorm::{Database, SeaOrmStore};
33    use chrono::{Duration, Utc};
34
35    pub type TestDatabase = dyn better_auth_core::store::AuthStore<BundledSchema>;
36
37    pub fn create_test_config() -> AuthConfig {
38        AuthConfig::new("test-secret-key-at-least-32-chars-long")
39    }
40
41    pub async fn create_test_database() -> Arc<TestDatabase> {
42        let database = Database::connect("sqlite::memory:")
43            .await
44            .expect("sqlite test database should connect");
45        better_auth_seaorm::store::__private_test_support::migrator::run_migrations(&database)
46            .await
47            .expect("sqlite test migrations should run");
48        Arc::new(SeaOrmStore::<BundledSchema>::new(
49            Arc::new(create_test_config()),
50            database,
51        ))
52    }
53
54    pub async fn create_test_context() -> AuthContext<BundledSchema> {
55        create_test_context_with_config(create_test_config()).await
56    }
57
58    pub fn create_test_context_blocking() -> AuthContext<BundledSchema> {
59        tokio::runtime::Builder::new_current_thread()
60            .enable_all()
61            .build()
62            .expect("test runtime should build")
63            .block_on(create_test_context())
64    }
65
66    pub async fn create_test_context_with_config(config: AuthConfig) -> AuthContext<BundledSchema> {
67        let config = Arc::new(config);
68        let database = create_test_database().await;
69        AuthContext::new(config, database)
70    }
71
72    pub async fn create_user(
73        ctx: &AuthContext<impl better_auth_core::AuthSchema>,
74        create_user: CreateUser,
75    ) -> UserView {
76        let user = ctx.database.create_user(create_user).await.unwrap();
77        UserView::from(&user)
78    }
79
80    pub async fn create_session(
81        ctx: &AuthContext<impl better_auth_core::AuthSchema>,
82        user_id: String,
83        expires_in: Duration,
84    ) -> SessionView {
85        let create_session = CreateSession {
86            user_id,
87            expires_at: Utc::now() + expires_in,
88            ip_address: Some("127.0.0.1".to_string()),
89            user_agent: Some("test-agent".to_string()),
90            impersonated_by: None,
91            active_organization_id: None,
92        };
93        let session = ctx.database.create_session(create_session).await.unwrap();
94        SessionView::from(&session)
95    }
96
97    pub async fn create_user_and_session(
98        ctx: &AuthContext<impl better_auth_core::AuthSchema>,
99        user_data: CreateUser,
100        session_expires_in: Duration,
101    ) -> (UserView, SessionView) {
102        let user = create_user(ctx, user_data).await;
103        let session = create_session(ctx, user.id.clone(), session_expires_in).await;
104        (user, session)
105    }
106
107    pub async fn create_test_context_with_user(
108        create_user: CreateUser,
109        session_expires_in: Duration,
110    ) -> (AuthContext<BundledSchema>, UserView, SessionView) {
111        let ctx = create_test_context().await;
112        let (user, session) = create_user_and_session(&ctx, create_user, session_expires_in).await;
113        (ctx, user, session)
114    }
115
116    pub fn create_auth_request(
117        method: HttpMethod,
118        path: &str,
119        token: Option<&str>,
120        body: Option<Vec<u8>>,
121        query: HashMap<String, String>,
122    ) -> AuthRequest {
123        let mut headers = HashMap::new();
124        if let Some(token) = token {
125            headers.insert("authorization".to_string(), format!("Bearer {}", token));
126        }
127
128        AuthRequest::from_parts(method, path.to_string(), headers, body, query)
129    }
130
131    pub fn create_auth_request_no_query(
132        method: HttpMethod,
133        path: &str,
134        token: Option<&str>,
135        body: Option<Vec<u8>>,
136    ) -> AuthRequest {
137        create_auth_request(method, path, token, body, HashMap::new())
138    }
139
140    pub fn create_auth_json_request_no_query(
141        method: HttpMethod,
142        path: &str,
143        token: Option<&str>,
144        body: Option<serde_json::Value>,
145    ) -> AuthRequest {
146        create_auth_json_request(method, path, token, body, HashMap::new())
147    }
148
149    pub fn create_auth_json_request(
150        method: HttpMethod,
151        path: &str,
152        token: Option<&str>,
153        body: Option<serde_json::Value>,
154        query: HashMap<String, String>,
155    ) -> AuthRequest {
156        let mut req = create_auth_request(
157            method,
158            path,
159            token,
160            body.map(|b| serde_json::to_vec(&b).unwrap()),
161            query,
162        );
163        req.headers
164            .insert("content-type".to_string(), "application/json".to_string());
165        req
166    }
167}
168
169pub use account_management::AccountManagementPlugin;
170pub use admin::{AdminConfig, AdminPlugin, RolePermissions};
171pub use api_key::{ApiKeyConfig, ApiKeyPlugin};
172pub use better_auth_core::PasswordHasher;
173pub use device_authorization::DeviceAuthorizationPlugin;
174pub use email_password::{EmailPasswordConfig, EmailPasswordPlugin};
175pub use email_verification::{
176    EmailVerificationConfig, EmailVerificationHook, EmailVerificationPlugin, SendVerificationEmail,
177};
178pub use organization::{OrganizationConfig, OrganizationPlugin};
179pub use passkey::{PasskeyConfig, PasskeyPlugin};
180pub use password_management::{
181    PasswordManagementConfig, PasswordManagementPlugin, SendResetPassword,
182};
183pub use session_management::SessionManagementPlugin;
184pub use two_factor::{SendTwoFactorOtp, TwoFactorConfig, TwoFactorPlugin};
185pub use user_management::{
186    ChangeEmailConfig, DeleteUserConfig, UserManagementConfig, UserManagementPlugin,
187};