Skip to main content

better_auth_api/plugins/two_factor/
callbacks.rs

1use std::sync::Arc;
2
3use better_auth_core::{
4    AuthPlugin, AuthResult, AuthSchema, background::BackgroundFuture, wire::UserView,
5};
6
7use super::TwoFactorPlugin;
8use crate::plugins::endpoint_context::{EndpointContext, WithCallbacks};
9
10type Sender<S> = dyn Fn(&UserView, &str, &EndpointContext<'_, S>) -> AuthResult<Option<BackgroundFuture>>
11    + Send
12    + Sync;
13
14/// Two-factor callbacks with validated input and the active typed runtime.
15pub struct TwoFactorCallbacks<S: AuthSchema> {
16    pub(super) sender: Option<Arc<Sender<S>>>,
17}
18
19impl<S: AuthSchema> Default for TwoFactorCallbacks<S> {
20    fn default() -> Self {
21        Self { sender: None }
22    }
23}
24
25impl<S: AuthSchema> TwoFactorCallbacks<S> {
26    /// Construct delivery work after persisting the OTP. Factory errors propagate immediately.
27    /// Retain the endpoint with `to_owned` when delivery needs its active runtime.
28    pub fn send<F>(mut self, callback: F) -> Self
29    where
30        F: Fn(&UserView, &str, &EndpointContext<'_, S>) -> AuthResult<Option<BackgroundFuture>>
31            + Send
32            + Sync
33            + 'static,
34    {
35        self.sender = Some(Arc::new(callback));
36        self
37    }
38}
39
40impl TwoFactorPlugin {
41    /// Attach schema-aware callbacks after configuring the plugin options.
42    pub fn callbacks<S: AuthSchema>(self, callbacks: TwoFactorCallbacks<S>) -> impl AuthPlugin<S> {
43        WithCallbacks {
44            plugin: self,
45            callbacks: Arc::new(callbacks),
46        }
47    }
48}