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 better_auth_core::adapters::{MemoryDatabaseAdapter, SessionOps, UserOps};
26 use better_auth_core::config::AuthConfig;
27 use better_auth_core::{
28 AuthContext, AuthRequest, CreateSession, CreateUser, HttpMethod, Session, User,
29 };
30 use chrono::{Duration, Utc};
31 use std::collections::HashMap;
32 use std::sync::Arc;
33
34 pub fn create_test_config() -> AuthConfig {
35 AuthConfig::new("test-secret-key-at-least-32-chars-long")
36 }
37
38 pub fn create_test_context() -> AuthContext<MemoryDatabaseAdapter> {
39 create_test_context_with_config(create_test_config())
40 }
41
42 pub fn create_test_context_with_config(
43 config: AuthConfig,
44 ) -> AuthContext<MemoryDatabaseAdapter> {
45 let config = Arc::new(config);
46 let database = Arc::new(MemoryDatabaseAdapter::new());
47 AuthContext::new(config, database)
48 }
49
50 pub fn create_test_context_with_trusted_origins(
54 origins: &[&str],
55 ) -> AuthContext<MemoryDatabaseAdapter> {
56 let mut config = create_test_config();
57 config.trusted_origins = origins.iter().map(|s| (*s).to_string()).collect();
58 create_test_context_with_config(config)
59 }
60
61 pub async fn create_user(
62 ctx: &AuthContext<MemoryDatabaseAdapter>,
63 create_user: CreateUser,
64 ) -> User {
65 ctx.database.create_user(create_user).await.unwrap()
66 }
67
68 pub async fn create_session(
69 ctx: &AuthContext<MemoryDatabaseAdapter>,
70 user_id: String,
71 expires_in: Duration,
72 ) -> Session {
73 let create_session = CreateSession {
74 user_id,
75 expires_at: Utc::now() + expires_in,
76 ip_address: Some("127.0.0.1".to_string()),
77 user_agent: Some("test-agent".to_string()),
78 impersonated_by: None,
79 active_organization_id: None,
80 };
81 ctx.database.create_session(create_session).await.unwrap()
82 }
83
84 pub async fn create_user_and_session(
85 ctx: &AuthContext<MemoryDatabaseAdapter>,
86 user_data: CreateUser,
87 session_expires_in: Duration,
88 ) -> (User, Session) {
89 let user = create_user(ctx, user_data).await;
90 let session = create_session(ctx, user.id.clone(), session_expires_in).await;
91 (user, session)
92 }
93
94 pub async fn create_test_context_with_user(
95 create_user: CreateUser,
96 session_expires_in: Duration,
97 ) -> (AuthContext<MemoryDatabaseAdapter>, User, Session) {
98 let ctx = create_test_context();
99 let (user, session) = create_user_and_session(&ctx, create_user, session_expires_in).await;
100 (ctx, user, session)
101 }
102
103 pub fn create_auth_request(
104 method: HttpMethod,
105 path: &str,
106 token: Option<&str>,
107 body: Option<Vec<u8>>,
108 query: HashMap<String, String>,
109 ) -> AuthRequest {
110 let mut headers = HashMap::new();
111 if let Some(token) = token {
112 headers.insert("authorization".to_string(), format!("Bearer {}", token));
113 }
114
115 AuthRequest::from_parts(method, path.to_string(), headers, body, query)
116 }
117
118 pub fn create_auth_request_no_query(
119 method: HttpMethod,
120 path: &str,
121 token: Option<&str>,
122 body: Option<Vec<u8>>,
123 ) -> AuthRequest {
124 create_auth_request(method, path, token, body, HashMap::new())
125 }
126
127 pub fn create_auth_json_request_no_query(
128 method: HttpMethod,
129 path: &str,
130 token: Option<&str>,
131 body: Option<serde_json::Value>,
132 ) -> AuthRequest {
133 create_auth_json_request(method, path, token, body, HashMap::new())
134 }
135
136 pub fn create_auth_json_request(
137 method: HttpMethod,
138 path: &str,
139 token: Option<&str>,
140 body: Option<serde_json::Value>,
141 query: HashMap<String, String>,
142 ) -> AuthRequest {
143 let mut req = create_auth_request(
144 method,
145 path,
146 token,
147 body.map(|b| serde_json::to_vec(&b).unwrap()),
148 query,
149 );
150 req.headers
151 .insert("content-type".to_string(), "application/json".to_string());
152 req
153 }
154}
155
156pub use account_management::AccountManagementPlugin;
157pub use admin::{AdminConfig, AdminPlugin};
158pub use api_key::{ApiKeyConfig, ApiKeyPlugin};
159pub use better_auth_core::PasswordHasher;
160pub use device_authorization::{DeviceAuthorizationConfig, DeviceAuthorizationPlugin};
161pub use email_password::{EmailPasswordConfig, EmailPasswordPlugin};
162pub use email_verification::{
163 EmailVerificationConfig, EmailVerificationHook, EmailVerificationPlugin, SendVerificationEmail,
164};
165pub use organization::{OrganizationConfig, OrganizationPlugin};
166pub use passkey::{PasskeyConfig, PasskeyPlugin};
167pub use password_management::{
168 PasswordManagementConfig, PasswordManagementPlugin, SendResetPassword,
169};
170pub use session_management::SessionManagementPlugin;
171pub use two_factor::{TwoFactorConfig, TwoFactorPlugin};
172pub use user_management::{
173 ChangeEmailConfig, DeleteUserConfig, UserManagementConfig, UserManagementPlugin,
174};