Skip to main content

better_auth_api/plugins/anonymous/
callbacks.rs

1use super::{AnonymousLink, AnonymousPlugin};
2use crate::plugins::endpoint_context::{EndpointContext, WithCallbacks};
3use better_auth_core::{AuthPlugin, AuthResult, AuthSchema};
4use std::{future::Future, pin::Pin, sync::Arc};
5
6/// A callback future that borrows the active endpoint.
7pub type AnonymousCallbackFuture<'a, T> = Pin<Box<dyn Future<Output = AuthResult<T>> + Send + 'a>>;
8type Name<S> =
9    dyn for<'a> Fn(&'a EndpointContext<'_, S>) -> AnonymousCallbackFuture<'a, String> + Send + Sync;
10type Link<S> = dyn for<'a> Fn(&'a AnonymousLink, &'a EndpointContext<'_, S>) -> AnonymousCallbackFuture<'a, ()>
11    + Send
12    + Sync;
13
14/// Anonymous identity callbacks with the complete endpoint context.
15pub struct AnonymousCallbacks<S: AuthSchema> {
16    pub(super) name: Option<Arc<Name<S>>>,
17    pub(super) link: Option<Arc<Link<S>>>,
18}
19
20impl<S: AuthSchema> Default for AnonymousCallbacks<S> {
21    fn default() -> Self {
22        Self {
23            name: None,
24            link: None,
25        }
26    }
27}
28
29impl<S: AuthSchema> AnonymousCallbacks<S> {
30    /// Generate a display name before creating the anonymous user.
31    pub fn generate_name<F>(mut self, callback: F) -> Self
32    where
33        F: for<'a> Fn(&'a EndpointContext<'_, S>) -> AnonymousCallbackFuture<'a, String>
34            + Send
35            + Sync
36            + 'static,
37    {
38        self.name = Some(Arc::new(callback));
39        self
40    }
41
42    /// Transfer application data before deleting the old anonymous user.
43    pub fn on_link_account<F>(mut self, callback: F) -> Self
44    where
45        F: for<'a> Fn(
46                &'a AnonymousLink,
47                &'a EndpointContext<'_, S>,
48            ) -> AnonymousCallbackFuture<'a, ()>
49            + Send
50            + Sync
51            + 'static,
52    {
53        self.link = Some(Arc::new(callback));
54        self
55    }
56}
57
58impl AnonymousPlugin {
59    /// Attach schema-aware callbacks after configuring plugin options.
60    pub fn callbacks<S: AuthSchema>(self, callbacks: AnonymousCallbacks<S>) -> impl AuthPlugin<S> {
61        WithCallbacks {
62            plugin: self,
63            callbacks: Arc::new(callbacks),
64        }
65    }
66}