Skip to main content

alibi_core/plugin/
mod.rs

1mod context;
2mod contracts;
3mod extensions;
4mod initialization;
5mod routes;
6
7pub use context::AuthContext;
8pub use contracts::{
9    AuthPlugin, BeforeRequestAction, HttpEndpointResponse, HttpRequestAction,
10    VerificationEmailOverride, VerificationEmailOverrideHandle,
11};
12pub use extensions::ContextExtensions;
13pub use initialization::{AuthInitContext, AuthInitParts};
14pub use routes::{AuthRoute, ResolvedEndpoint};
15use std::collections::HashMap;
16
17type MetadataMap = HashMap<String, serde_json::Value>;
18
19// LCOV_EXCL_START
20#[cfg(test)]
21mod tests {
22    use super::*;
23    use crate::AuthConfig;
24    use crate::AuthRequest;
25    use crate::HttpMethod;
26    use crate::SessionManager;
27    use crate::entity::AuthSession;
28    use crate::entity::AuthUser;
29    use crate::test_store::test_database;
30    use std::sync::Arc;
31
32    // Rust-specific surface: plugin infrastructure helpers and request-dispatch helpers in `crates/core::plugin` are Rust library APIs with no direct TS analogue.
33    #[test]
34    fn auth_route_constructors() {
35        let get = AuthRoute::get("/test", "getTest");
36        assert_eq!(get.method, HttpMethod::Get);
37        assert_eq!(get.path, "/test");
38        assert_eq!(get.operation_id, "getTest");
39
40        let post = AuthRoute::post("/create", "createItem");
41        assert_eq!(post.method, HttpMethod::Post);
42
43        let put = AuthRoute::put("/update", "updateItem");
44        assert_eq!(put.method, HttpMethod::Put);
45
46        let delete = AuthRoute::delete("/remove", "deleteItem");
47        assert_eq!(delete.method, HttpMethod::Delete);
48    }
49
50    // Rust-specific surface: plugin infrastructure helpers and request-dispatch helpers in `crates/core::plugin` are Rust library APIs with no direct TS analogue.
51    #[test]
52    fn auth_route_new() {
53        let route = AuthRoute::new(HttpMethod::Patch, "/patch", "patchIt");
54        assert_eq!(route.method, HttpMethod::Patch);
55        assert_eq!(route.path, "/patch");
56    }
57
58    // Rust-specific surface: plugin infrastructure helpers and request-dispatch helpers in `crates/core::plugin` are Rust library APIs with no direct TS analogue.
59    #[test]
60    fn auth_context_new() {
61        let config = Arc::new(AuthConfig::new("test-secret-min-32-chars-1234567"));
62        let runtime = tokio::runtime::Runtime::new().expect("runtime should build");
63        let db = runtime.block_on(test_database());
64        let ctx = AuthContext::new(config, db);
65        assert!(ctx.email_provider.is_none());
66        assert!(ctx.metadata.is_empty());
67    }
68
69    // Rust-specific surface: plugin infrastructure helpers and request-dispatch helpers in `crates/core::plugin` are Rust library APIs with no direct TS analogue.
70    #[test]
71    fn auth_context_metadata() {
72        let config = Arc::new(AuthConfig::new("test-secret-min-32-chars-1234567"));
73        let runtime = tokio::runtime::Runtime::new().expect("runtime should build");
74        let db = runtime.block_on(test_database());
75        let mut ctx = AuthContext::new(config, db);
76
77        ctx.set_metadata("key", serde_json::json!("value"));
78        assert_eq!(ctx.get_metadata("key"), Some(&serde_json::json!("value")));
79        assert!(ctx.get_metadata("missing").is_none());
80    }
81
82    // Rust-specific surface: plugin infrastructure helpers and request-dispatch helpers in `crates/core::plugin` are Rust library APIs with no direct TS analogue.
83    #[test]
84    fn auth_context_email_provider_error_when_none() {
85        let config = Arc::new(AuthConfig::new("test-secret-min-32-chars-1234567"));
86        let runtime = tokio::runtime::Runtime::new().expect("runtime should build");
87        let db = runtime.block_on(test_database());
88        let ctx = AuthContext::new(config, db);
89        assert!(ctx.email_provider().is_err());
90    }
91
92    // Rust-specific surface: plugin infrastructure helpers and request-dispatch helpers in `crates/core::plugin` are Rust library APIs with no direct TS analogue.
93    #[tokio::test]
94    async fn auth_context_require_session_unauthenticated() {
95        let config = Arc::new(AuthConfig::new("test-secret-min-32-chars-1234567"));
96        let db = test_database().await;
97        let ctx = AuthContext::new(config, db);
98        let req = AuthRequest::new(HttpMethod::Get, "/test");
99        let result = ctx.require_session(&req).await;
100        assert!(result.is_err());
101    }
102
103    // Rust-specific surface: plugin infrastructure helpers and request-dispatch helpers in `crates/core::plugin` are Rust library APIs with no direct TS analogue.
104    #[tokio::test]
105    async fn auth_context_require_session_with_valid_session() {
106        let config = Arc::new(AuthConfig::new("test-secret-min-32-chars-1234567"));
107        let db = test_database().await;
108
109        // Create a user
110        let user = db
111            .create_user(crate::types::CreateUser::new().with_email("test@test.com"))
112            .await
113            .unwrap();
114
115        // Create a session
116        let sm = SessionManager::new(Arc::clone(&config), Arc::clone(&db));
117        let session = sm.create_session(&user, None, None).await.unwrap();
118
119        // Build request with the session token
120        let ctx = AuthContext::new(Arc::clone(&config), db);
121        let mut req = AuthRequest::new(HttpMethod::Get, "/test");
122        _ = req.headers.insert(
123            "cookie".into(),
124            format!(
125                "better-auth.session_token={}",
126                crate::utils::cookie_utils::sign_cookie_value(session.token(), &config.secret)
127            ),
128        );
129
130        let (found_user, _found_session) = ctx.require_session(&req).await.unwrap();
131        assert_eq!(found_user.id(), user.id());
132    }
133}
134// LCOV_EXCL_STOP