better_auth_api/plugins/organization/
callbacks.rs1use super::{InvitationEmail, OrganizationConfig, OrganizationPlugin};
2use crate::plugins::endpoint_context::{EndpointContext, WithCallbacks};
3use better_auth_core::{AuthPlugin, AuthResult, AuthSchema, background::BackgroundFuture};
4use std::sync::Arc;
5
6type InvitationSender<S> = dyn Fn(&InvitationEmail, &EndpointContext<'_, S>) -> AuthResult<Option<BackgroundFuture>>
7 + Send
8 + Sync;
9
10pub struct OrganizationCallbacks<S: AuthSchema> {
12 sender: Arc<InvitationSender<S>>,
13}
14impl<S: AuthSchema> OrganizationCallbacks<S> {
15 pub fn invitation_email(
17 sender: impl Fn(
18 &InvitationEmail,
19 &EndpointContext<'_, S>,
20 ) -> AuthResult<Option<BackgroundFuture>>
21 + Send
22 + Sync
23 + 'static,
24 ) -> Self {
25 Self {
26 sender: Arc::new(sender),
27 }
28 }
29}
30impl OrganizationPlugin {
31 pub fn callbacks<S: AuthSchema>(
33 self,
34 callbacks: OrganizationCallbacks<S>,
35 ) -> impl AuthPlugin<S> {
36 WithCallbacks {
37 plugin: self,
38 callbacks: Arc::new(callbacks),
39 }
40 }
41}
42pub(super) fn delivery<S: AuthSchema>(
43 config: &OrganizationConfig,
44 message: InvitationEmail,
45 endpoint: &EndpointContext<'_, S>,
46) -> AuthResult<Option<BackgroundFuture>> {
47 if let Some(callbacks) = endpoint
48 .auth
49 .extensions
50 .get::<Arc<OrganizationCallbacks<S>>>()
51 {
52 return (callbacks.sender)(&message, endpoint);
53 }
54 let Some(sender) = config.send_invitation_email.clone() else {
55 return Ok(None);
56 };
57 Ok(Some(Box::pin(async move { sender.send(&message).await })))
58}