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 operation_id: String,
76}
77
78pub struct AuthContext<DB: DatabaseAdapter> {
80 pub config: Arc<AuthConfig>,
81 pub database: Arc<DB>,
82 pub email_provider: Option<Arc<dyn EmailProvider>>,
83 pub metadata: HashMap<String, serde_json::Value>,
84}
85
86impl AuthRoute {
87 pub fn new(
88 method: HttpMethod,
89 path: impl Into<String>,
90 operation_id: impl Into<String>,
91 ) -> Self {
92 Self {
93 path: path.into(),
94 method,
95 operation_id: operation_id.into(),
96 }
97 }
98
99 pub fn get(path: impl Into<String>, operation_id: impl Into<String>) -> Self {
100 Self::new(HttpMethod::Get, path, operation_id)
101 }
102
103 pub fn post(path: impl Into<String>, operation_id: impl Into<String>) -> Self {
104 Self::new(HttpMethod::Post, path, operation_id)
105 }
106
107 pub fn put(path: impl Into<String>, operation_id: impl Into<String>) -> Self {
108 Self::new(HttpMethod::Put, path, operation_id)
109 }
110
111 pub fn delete(path: impl Into<String>, operation_id: impl Into<String>) -> Self {
112 Self::new(HttpMethod::Delete, path, operation_id)
113 }
114}
115
116impl<DB: DatabaseAdapter> AuthContext<DB> {
117 pub fn new(config: Arc<AuthConfig>, database: Arc<DB>) -> Self {
118 let email_provider = config.email_provider.clone();
119 Self {
120 config,
121 database,
122 email_provider,
123 metadata: HashMap::new(),
124 }
125 }
126
127 pub fn set_metadata(&mut self, key: impl Into<String>, value: serde_json::Value) {
128 self.metadata.insert(key.into(), value);
129 }
130
131 pub fn get_metadata(&self, key: &str) -> Option<&serde_json::Value> {
132 self.metadata.get(key)
133 }
134
135 pub fn email_provider(&self) -> AuthResult<&dyn EmailProvider> {
137 self.email_provider
138 .as_deref()
139 .ok_or_else(|| AuthError::config("No email provider configured"))
140 }
141}