use super::{InvitationEmail, OrganizationConfig, OrganizationPlugin};
use crate::plugins::endpoint_context::{EndpointContext, WithCallbacks};
use better_auth_core::{AuthPlugin, AuthResult, AuthSchema, background::BackgroundFuture};
use std::sync::Arc;
type InvitationSender<S> = dyn Fn(&InvitationEmail, &EndpointContext<'_, S>) -> AuthResult<Option<BackgroundFuture>>
+ Send
+ Sync;
pub struct OrganizationCallbacks<S: AuthSchema> {
sender: Arc<InvitationSender<S>>,
}
impl<S: AuthSchema> OrganizationCallbacks<S> {
pub fn invitation_email(
sender: impl Fn(
&InvitationEmail,
&EndpointContext<'_, S>,
) -> AuthResult<Option<BackgroundFuture>>
+ Send
+ Sync
+ 'static,
) -> Self {
Self {
sender: Arc::new(sender),
}
}
}
impl OrganizationPlugin {
pub fn callbacks<S: AuthSchema>(
self,
callbacks: OrganizationCallbacks<S>,
) -> impl AuthPlugin<S> {
WithCallbacks {
plugin: self,
callbacks: Arc::new(callbacks),
}
}
}
pub(super) fn delivery<S: AuthSchema>(
config: &OrganizationConfig,
message: impl FnOnce() -> AuthResult<InvitationEmail>,
endpoint: &EndpointContext<'_, S>,
) -> AuthResult<Option<BackgroundFuture>> {
if let Some(callbacks) = endpoint
.auth
.extensions
.get::<Arc<OrganizationCallbacks<S>>>()
{
return (callbacks.sender)(&message()?, endpoint);
}
let Some(sender) = config.send_invitation_email.clone() else {
return Ok(None);
};
let message = message()?;
Ok(Some(BackgroundFuture::new(async move {
sender.send(&message).await
})))
}