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