Skip to main content

better_auth_api/plugins/user_management/
callbacks.rs

1use super::UserManagementPlugin;
2use crate::plugins::{
3    email_verification::VerificationEmail,
4    endpoint_context::{EndpointContext, WithCallbacks},
5};
6use better_auth_core::{AuthPlugin, AuthResult, AuthSchema, background::BackgroundFuture};
7use std::sync::Arc;
8
9/// Confirmation sent to the current address before a verified user changes email.
10#[derive(Clone)]
11pub struct ChangeEmailConfirmation {
12    /// Current session user, before the email change.
13    pub user: better_auth_core::wire::UserView,
14    /// Requested new address.
15    pub new_email: String,
16    /// Confirmation URL.
17    pub url: String,
18    /// Signed confirmation token.
19    pub token: String,
20}
21type Sender<S, M> =
22    dyn Fn(&M, &EndpointContext<'_, S>) -> AuthResult<Option<BackgroundFuture>> + Send + Sync;
23
24/// User notification factories with the complete endpoint and original Request.
25/// Return `None` for synchronous completion or an owned future for background scheduling.
26pub struct UserManagementCallbacks<S: AuthSchema> {
27    pub(super) confirmation: Option<Arc<Sender<S, ChangeEmailConfirmation>>>,
28    pub(super) deletion: Option<Arc<Sender<S, VerificationEmail>>>,
29}
30impl<S: AuthSchema> Default for UserManagementCallbacks<S> {
31    fn default() -> Self {
32        Self {
33            confirmation: None,
34            deletion: None,
35        }
36    }
37}
38impl<S: AuthSchema> UserManagementCallbacks<S> {
39    pub(crate) fn has_confirmation_sender(&self) -> bool {
40        self.confirmation.is_some()
41    }
42
43    /// Use the existing configured senders until a factory overrides each delivery path.
44    pub fn new() -> Self {
45        Self::default()
46    }
47
48    /// Send confirmation to the current address of a verified user.
49    pub fn change_email_confirmation(
50        mut self,
51        callback: impl Fn(
52            &ChangeEmailConfirmation,
53            &EndpointContext<'_, S>,
54        ) -> AuthResult<Option<BackgroundFuture>>
55        + Send
56        + Sync
57        + 'static,
58    ) -> Self {
59        self.confirmation = Some(Arc::new(callback));
60        self
61    }
62
63    /// Send account deletion confirmation after the verification record is stored.
64    pub fn delete_account_verification(
65        mut self,
66        callback: impl Fn(
67            &VerificationEmail,
68            &EndpointContext<'_, S>,
69        ) -> AuthResult<Option<BackgroundFuture>>
70        + Send
71        + Sync
72        + 'static,
73    ) -> Self {
74        self.deletion = Some(Arc::new(callback));
75        self
76    }
77}
78impl UserManagementPlugin {
79    /// Attach typed notification factories after configuring user management.
80    pub fn callbacks<S: AuthSchema>(
81        self,
82        callbacks: UserManagementCallbacks<S>,
83    ) -> impl AuthPlugin<S> {
84        WithCallbacks {
85            plugin: self,
86            callbacks: Arc::new(callbacks),
87        }
88    }
89}