better_auth/core/
plugin.rs

1use async_trait::async_trait;
2use std::sync::Arc;
3use std::collections::HashMap;
4
5use crate::types::{AuthRequest, AuthResponse, User, Session, HttpMethod};
6use crate::error::{AuthError, AuthResult};
7use crate::adapters::DatabaseAdapter;
8use crate::core::config::AuthConfig;
9
10/// Plugin trait that all authentication plugins must implement
11#[async_trait]
12pub trait AuthPlugin: Send + Sync {
13    /// Plugin name - should be unique
14    fn name(&self) -> &'static str;
15    
16    /// Routes that this plugin handles
17    fn routes(&self) -> Vec<AuthRoute>;
18    
19    /// Called when the plugin is initialized
20    async fn on_init(&self, ctx: &mut AuthContext) -> AuthResult<()> {
21        let _ = ctx;
22        Ok(())
23    }
24    
25    /// Called for each request - return Some(response) to handle, None to pass through
26    async fn on_request(&self, req: &AuthRequest, ctx: &AuthContext) -> AuthResult<Option<AuthResponse>>;
27    
28    /// Called after a user is created
29    async fn on_user_created(&self, user: &User, ctx: &AuthContext) -> AuthResult<()> {
30        let _ = (user, ctx);
31        Ok(())
32    }
33    
34    /// Called after a session is created
35    async fn on_session_created(&self, session: &Session, ctx: &AuthContext) -> AuthResult<()> {
36        let _ = (session, ctx);
37        Ok(())
38    }
39    
40    /// Called before a user is deleted
41    async fn on_user_deleted(&self, user_id: &str, ctx: &AuthContext) -> AuthResult<()> {
42        let _ = (user_id, ctx);
43        Ok(())
44    }
45    
46    /// Called before a session is deleted
47    async fn on_session_deleted(&self, session_token: &str, ctx: &AuthContext) -> AuthResult<()> {
48        let _ = (session_token, ctx);
49        Ok(())
50    }
51}
52
53/// Route definition for plugins
54#[derive(Debug, Clone)]
55pub struct AuthRoute {
56    pub path: String,
57    pub method: HttpMethod,
58    pub handler: String,
59}
60
61/// Context passed to plugin methods
62pub struct AuthContext {
63    pub config: Arc<AuthConfig>,
64    pub database: Arc<dyn DatabaseAdapter>,
65    pub metadata: HashMap<String, serde_json::Value>,
66}
67
68impl AuthRoute {
69    pub fn new(method: HttpMethod, path: impl Into<String>, handler: impl Into<String>) -> Self {
70        Self {
71            path: path.into(),
72            method,
73            handler: handler.into(),
74        }
75    }
76    
77    pub fn get(path: impl Into<String>, handler: impl Into<String>) -> Self {
78        Self::new(HttpMethod::Get, path, handler)
79    }
80    
81    pub fn post(path: impl Into<String>, handler: impl Into<String>) -> Self {
82        Self::new(HttpMethod::Post, path, handler)
83    }
84    
85    pub fn put(path: impl Into<String>, handler: impl Into<String>) -> Self {
86        Self::new(HttpMethod::Put, path, handler)
87    }
88    
89    pub fn delete(path: impl Into<String>, handler: impl Into<String>) -> Self {
90        Self::new(HttpMethod::Delete, path, handler)
91    }
92}
93
94impl AuthContext {
95    pub fn new(config: Arc<AuthConfig>, database: Arc<dyn DatabaseAdapter>) -> Self {
96        Self {
97            config,
98            database,
99            metadata: HashMap::new(),
100        }
101    }
102    
103    pub fn set_metadata(&mut self, key: impl Into<String>, value: serde_json::Value) {
104        self.metadata.insert(key.into(), value);
105    }
106    
107    pub fn get_metadata(&self, key: &str) -> Option<&serde_json::Value> {
108        self.metadata.get(key)
109    }
110}