1pub mod access;
2pub mod account_management;
3
4pub mod admin;
5
6pub mod anonymous;
7
8pub mod bearer;
9pub mod captcha;
10pub mod custom_session;
11pub use custom_session::{CustomSessionPlugin, SessionTransform};
12
13pub mod api_key;
14
15pub(in crate::plugins) mod authentication_helpers;
16
17pub mod device_authorization;
18
19pub mod email_otp;
20mod endpoint;
21
22pub mod email_password;
23pub mod haveibeenpwned;
24
25pub mod email_verification;
26
27pub mod helpers;
28
29pub mod jwt;
30pub mod last_login_method;
31pub use last_login_method::{LastLoginMethodConfig, LastLoginMethodPlugin};
32
33pub mod magic_link;
34
35pub mod multi_session;
36
37pub mod oauth;
38
39pub mod oauth_popup;
40pub mod oauth_proxy;
41pub use oauth_popup::OAuthPopupPlugin;
42
43pub mod one_tap;
44
45pub mod one_time_token;
46
47pub mod open_api;
48
49pub mod organization;
50
51pub mod passkey;
52
53pub mod password_management;
54
55mod passwordless_numeric;
56pub mod phone_number;
57
58pub mod session_management;
59
60pub mod siwe;
61
62pub(in crate::plugins) mod token_crypto;
63
64pub mod two_factor;
65
66pub mod user_management;
67
68#[cfg(test)]
70pub(in crate::plugins) mod test_helpers {
71
72 use alibi_core::config::AuthConfig;
73 use alibi_core::wire::{SessionView, UserView};
74 use alibi_core::{AuthContext, AuthRequest, CreateSession, CreateUser, HttpMethod};
75 use alibi_seaorm::store::__private_test_support::bundled_schema::BundledSchema;
76 use alibi_seaorm::{Database, SeaOrmStore};
77 use chrono::{Duration, Utc};
78 use std::collections::HashMap;
79 use std::sync::Arc;
80
81 pub type TestDatabase = dyn alibi_core::store::AuthStore<BundledSchema>;
82
83 pub fn create_test_config() -> AuthConfig {
84 AuthConfig::new("test-secret-key-at-least-32-chars-long")
85 }
86
87 pub async fn create_test_database() -> Arc<TestDatabase> {
88 let database = Database::connect("sqlite::memory:")
89 .await
90 .expect("sqlite test database should connect");
91 alibi_seaorm::store::__private_test_support::migrator::run_migrations(&database)
92 .await
93 .expect("sqlite test migrations should run");
94 Arc::new(SeaOrmStore::<BundledSchema>::new(
95 Arc::new(create_test_config()),
96 database,
97 ))
98 }
99
100 pub async fn create_test_context() -> AuthContext<BundledSchema> {
101 create_test_context_with_config(create_test_config()).await
102 }
103
104 pub fn create_test_context_blocking() -> AuthContext<BundledSchema> {
105 tokio::runtime::Builder::new_current_thread()
106 .enable_all()
107 .build()
108 .expect("test runtime should build")
109 .block_on(create_test_context())
110 }
111
112 pub async fn create_test_context_with_config(config: AuthConfig) -> AuthContext<BundledSchema> {
113 let config = Arc::new(config);
114 let database = create_test_database().await;
115 AuthContext::new(config, database)
116 }
117
118 pub async fn create_user(
119 ctx: &AuthContext<impl alibi_core::AuthSchema>,
120 create_user: CreateUser,
121 ) -> UserView {
122 let user = ctx.database.create_user(create_user).await.unwrap();
123 UserView::from(&user)
124 }
125
126 pub async fn create_session(
127 ctx: &AuthContext<impl alibi_core::AuthSchema>,
128 user_id: String,
129 expires_in: Duration,
130 ) -> SessionView {
131 let create_session = CreateSession {
132 additional_fields: alibi_core::field_policy::FieldValues::default(),
133 token: None,
134 active_team_id: None,
135 user_id,
136 expires_at: Utc::now() + expires_in,
137 ip_address: Some("127.0.0.1".to_owned()),
138 user_agent: Some("test-agent".to_owned()),
139 impersonated_by: None,
140 active_organization_id: None,
141 };
142 let session = ctx.database.create_session(create_session).await.unwrap();
143 SessionView::from(&session)
144 }
145
146 pub async fn create_user_and_session(
147 ctx: &AuthContext<impl alibi_core::AuthSchema>,
148 user_data: CreateUser,
149 session_expires_in: Duration,
150 ) -> (UserView, SessionView) {
151 let user = create_user(ctx, user_data).await;
152 let session = create_session(ctx, user.id.clone(), session_expires_in).await;
153 (user, session)
154 }
155
156 pub async fn create_test_context_with_user(
157 create_user: CreateUser,
158 session_expires_in: Duration,
159 ) -> (AuthContext<BundledSchema>, UserView, SessionView) {
160 let ctx = create_test_context().await;
161 let (user, session) = create_user_and_session(&ctx, create_user, session_expires_in).await;
162 (ctx, user, session)
163 }
164
165 pub fn create_auth_request(
166 method: HttpMethod,
167 path: &str,
168 token: Option<&str>,
169 body: Option<Vec<u8>>,
170 query: HashMap<String, String>,
171 ) -> AuthRequest {
172 let mut headers = HashMap::new();
173 if let Some(token) = token {
174 let config = create_test_config();
175 headers.insert(
176 "cookie".to_owned(),
177 format!(
178 "{}={}",
179 config.session.cookie_name,
180 alibi_core::utils::cookie_utils::sign_cookie_value(
181 token,
182 config.current_secret()
183 )
184 ),
185 );
186 }
187
188 AuthRequest::from_parts(method, path.to_owned(), headers, body, query)
189 }
190
191 pub fn create_auth_request_no_query(
192 method: HttpMethod,
193 path: &str,
194 token: Option<&str>,
195 body: Option<Vec<u8>>,
196 ) -> AuthRequest {
197 create_auth_request(method, path, token, body, HashMap::new())
198 }
199
200 pub fn create_auth_json_request_no_query(
201 method: HttpMethod,
202 path: &str,
203 token: Option<&str>,
204 body: Option<serde_json::Value>,
205 ) -> AuthRequest {
206 create_auth_json_request(method, path, token, body, HashMap::new())
207 }
208
209 pub fn create_auth_json_request(
210 method: HttpMethod,
211 path: &str,
212 token: Option<&str>,
213 body: Option<serde_json::Value>,
214 query: HashMap<String, String>,
215 ) -> AuthRequest {
216 let mut req = create_auth_request(
217 method,
218 path,
219 token,
220 body.map(|b| serde_json::to_vec(&b).unwrap()),
221 query,
222 );
223 req.headers
224 .insert("content-type".to_owned(), "application/json".to_owned());
225 req
226 }
227}
228pub use account_management::AccountManagementPlugin;
231pub use admin::{
232 AdminBannedUserMessage, AdminBannedUserMessageHandler, AdminConfig, AdminPlugin,
233 RolePermissions,
234};
235pub use alibi_core::PasswordHasher;
236pub use anonymous::{AnonymousConfig, AnonymousPlugin};
237pub use api_key::{ApiKeyConfig, ApiKeyPlugin};
238pub use bearer::{BearerConfig, BearerPlugin};
239pub use device_authorization::DeviceAuthorizationPlugin;
240pub use email_otp::{EmailOtpConfig, EmailOtpPlugin, SendEmailOtp};
241pub use email_password::{EmailPasswordConfig, EmailPasswordPlugin};
242pub use email_verification::{
243 EmailVerificationConfig, EmailVerificationHook, EmailVerificationPlugin, SendVerificationEmail,
244};
245pub use haveibeenpwned::{HaveIBeenPwnedConfig, HaveIBeenPwnedPlugin, PwnedPasswordClient};
246pub use magic_link::{MagicLinkConfig, MagicLinkPlugin, SendMagicLink};
247pub use organization::{
248 OrganizationConfig, OrganizationCreatePatch, OrganizationCreatedContext,
249 OrganizationCreationHooks, OrganizationDraftContext, OrganizationMemberCreatePatch,
250 OrganizationMemberDraftContext, OrganizationPlugin,
251};
252pub use passkey::{PasskeyConfig, PasskeyPlugin};
253pub use password_management::{
254 PasswordManagementConfig, PasswordManagementPlugin, SendResetPassword,
255};
256use serde::{Deserialize, Serialize};
257pub use session_management::SessionManagementPlugin;
258pub use siwe::{SiweConfig, SiwePlugin};
259pub use two_factor::{
260 SendTwoFactorOtp, TwoFactorBackupCipher, TwoFactorBackupStorage, TwoFactorConfig,
261 TwoFactorOtpCipher, TwoFactorOtpHasher, TwoFactorOtpStorage, TwoFactorPlugin,
262};
263pub use user_management::{
264 ChangeEmailConfig, DeleteUserConfig, UserManagementConfig, UserManagementPlugin,
265};
266
267#[derive(Debug, Serialize, Deserialize)]
268pub(in crate::plugins) struct StatusResponse {
269 status: bool,
270}
271
272pub mod oauth_token_conversion;