better_auth_core/
plugin.rs1use async_trait::async_trait;
2use std::collections::HashMap;
3use std::sync::Arc;
4
5use crate::adapters::DatabaseAdapter;
6use crate::config::AuthConfig;
7use crate::email::EmailProvider;
8use crate::error::{AuthError, AuthResult};
9use crate::types::{AuthRequest, AuthResponse, HttpMethod, Session, User};
10
11#[async_trait]
13pub trait AuthPlugin: Send + Sync {
14 fn name(&self) -> &'static str;
16
17 fn routes(&self) -> Vec<AuthRoute>;
19
20 async fn on_init(&self, ctx: &mut AuthContext) -> AuthResult<()> {
22 let _ = ctx;
23 Ok(())
24 }
25
26 async fn on_request(
28 &self,
29 req: &AuthRequest,
30 ctx: &AuthContext,
31 ) -> AuthResult<Option<AuthResponse>>;
32
33 async fn on_user_created(&self, user: &User, ctx: &AuthContext) -> AuthResult<()> {
35 let _ = (user, ctx);
36 Ok(())
37 }
38
39 async fn on_session_created(&self, session: &Session, ctx: &AuthContext) -> AuthResult<()> {
41 let _ = (session, ctx);
42 Ok(())
43 }
44
45 async fn on_user_deleted(&self, user_id: &str, ctx: &AuthContext) -> AuthResult<()> {
47 let _ = (user_id, ctx);
48 Ok(())
49 }
50
51 async fn on_session_deleted(&self, session_token: &str, ctx: &AuthContext) -> AuthResult<()> {
53 let _ = (session_token, ctx);
54 Ok(())
55 }
56}
57
58#[derive(Debug, Clone)]
60pub struct AuthRoute {
61 pub path: String,
62 pub method: HttpMethod,
63 pub handler: String,
64}
65
66pub struct AuthContext {
68 pub config: Arc<AuthConfig>,
69 pub database: Arc<dyn DatabaseAdapter>,
70 pub email_provider: Option<Arc<dyn EmailProvider>>,
71 pub metadata: HashMap<String, serde_json::Value>,
72}
73
74impl AuthRoute {
75 pub fn new(method: HttpMethod, path: impl Into<String>, handler: impl Into<String>) -> Self {
76 Self {
77 path: path.into(),
78 method,
79 handler: handler.into(),
80 }
81 }
82
83 pub fn get(path: impl Into<String>, handler: impl Into<String>) -> Self {
84 Self::new(HttpMethod::Get, path, handler)
85 }
86
87 pub fn post(path: impl Into<String>, handler: impl Into<String>) -> Self {
88 Self::new(HttpMethod::Post, path, handler)
89 }
90
91 pub fn put(path: impl Into<String>, handler: impl Into<String>) -> Self {
92 Self::new(HttpMethod::Put, path, handler)
93 }
94
95 pub fn delete(path: impl Into<String>, handler: impl Into<String>) -> Self {
96 Self::new(HttpMethod::Delete, path, handler)
97 }
98}
99
100impl AuthContext {
101 pub fn new(config: Arc<AuthConfig>, database: Arc<dyn DatabaseAdapter>) -> Self {
102 let email_provider = config.email_provider.clone();
103 Self {
104 config,
105 database,
106 email_provider,
107 metadata: HashMap::new(),
108 }
109 }
110
111 pub fn set_metadata(&mut self, key: impl Into<String>, value: serde_json::Value) {
112 self.metadata.insert(key.into(), value);
113 }
114
115 pub fn get_metadata(&self, key: &str) -> Option<&serde_json::Value> {
116 self.metadata.get(key)
117 }
118
119 pub fn email_provider(&self) -> AuthResult<&dyn EmailProvider> {
121 self.email_provider
122 .as_deref()
123 .ok_or_else(|| AuthError::config("No email provider configured"))
124 }
125}