use super::*;
pub struct AuthInitParts {
pub metadata: MetadataMap,
pub email_provider: Option<Arc<dyn EmailProvider>>,
pub extensions: ContextExtensions,
}
pub struct AuthInitContext<S: AuthSchema> {
pub config: Arc<AuthConfig>,
pub database: Arc<dyn AuthStore<S>>,
pub email_provider: Option<Arc<dyn EmailProvider>>,
pub metadata: MetadataMap,
pub extensions: ContextExtensions,
}
impl<S: AuthSchema> AuthInitContext<S> {
#[must_use]
pub fn new(config: Arc<AuthConfig>, database: Arc<dyn AuthStore<S>>) -> Self {
let email_provider = config.email_provider.clone();
Self {
config,
database,
email_provider,
metadata: MetadataMap::new(),
extensions: ContextExtensions::default(),
}
}
pub fn set_metadata(&mut self, key: impl Into<String>, value: serde_json::Value) {
drop(self.metadata.insert(key.into(), value));
}
pub fn register_password_hash_hook(
&mut self,
hook: Arc<dyn crate::utils::password::PasswordHashHook>,
) {
let mut hooks = self
.extensions
.get::<crate::utils::password::PasswordHashHooks>()
.map(|value| (*value).clone())
.unwrap_or_default();
hooks.0.push(hook);
self.extensions.insert(hooks);
}
#[must_use]
pub fn get_metadata(&self, key: &str) -> Option<&serde_json::Value> {
self.metadata.get(key)
}
pub fn register_user_create_transform<F>(&mut self, transform: F)
where
F: Fn(crate::types::CreateUser) -> AuthResult<crate::types::CreateUser>
+ Send
+ Sync
+ 'static,
{
let mut transforms = self
.extensions
.get::<crate::store::UserTransforms>()
.map(|value| (*value).clone())
.unwrap_or_default();
transforms.creates.push(Arc::new(transform));
self.extensions.insert(transforms);
}
pub fn register_user_creation_adapter_default<F>(&mut self, default: F)
where
F: Fn(crate::types::CreateUser) -> AuthResult<crate::types::CreateUser>
+ Send
+ Sync
+ 'static,
{
let mut transforms = self
.extensions
.get::<crate::store::UserTransforms>()
.map(|value| (*value).clone())
.unwrap_or_default();
transforms.adapter_defaults.0.push(Arc::new(default));
self.extensions.insert(transforms);
}
pub fn register_user_update_transform<F>(&mut self, transform: F)
where
F: Fn(&str, crate::types::UpdateUser) -> AuthResult<crate::types::UpdateUser>
+ Send
+ Sync
+ 'static,
{
let mut transforms = self
.extensions
.get::<crate::store::UserTransforms>()
.map(|value| (*value).clone())
.unwrap_or_default();
transforms.updates.push(Arc::new(transform));
self.extensions.insert(transforms);
}
pub fn register_session_created_hook(
&mut self,
callback: Arc<dyn crate::store::SessionCreatedHook<S>>,
) {
let mut callbacks = self
.extensions
.get::<crate::store::SessionCreatedCallbacks<S>>()
.map(|value| (*value).clone())
.unwrap_or_default();
callbacks.callbacks.push(callback);
self.extensions.insert(callbacks);
}
pub fn register_adapter_after_hook(
&mut self,
callback: Arc<dyn crate::store::AdapterAfterHook<S>>,
) {
let mut callbacks = self
.extensions
.get::<crate::store::AdapterCallbacks<S>>()
.map(|callbacks| (*callbacks).clone())
.unwrap_or_default();
callbacks.0.push(callback);
self.extensions.insert(callbacks);
}
#[must_use]
pub fn database_with_registered_transforms(&self) -> Arc<dyn AuthStore<S>> {
let transforms = self
.extensions
.get::<crate::store::UserTransforms>()
.map(|value| (*value).clone())
.unwrap_or_default();
let session_callbacks = self
.extensions
.get::<crate::store::SessionCreatedCallbacks<S>>()
.map(|value| (*value).clone())
.unwrap_or_default();
let fields = self.extensions.get::<crate::field_policy::SessionFields>();
if self.config.session.secondary_storage.is_none()
&& transforms.creates.is_empty()
&& transforms.updates.is_empty()
&& session_callbacks.callbacks.is_empty()
&& fields.is_none()
&& self.config.user.additional_fields.is_empty()
&& self.config.session.additional_fields.is_empty()
&& self.config.account.additional_fields.is_empty()
&& self
.extensions
.get::<crate::store::AdapterCallbacks<S>>()
.is_none_or(|callbacks| callbacks.0.is_empty())
&& self.config.user_validation.is_none()
{
return Arc::clone(&self.database);
}
Arc::new(crate::store::PluginStore::new(
Arc::clone(&self.database),
Arc::clone(&self.config),
transforms,
session_callbacks,
fields.map_or_else(
|| {
crate::field_policy::SessionFields(
self.config.session.additional_fields.clone(),
)
},
|fields| (*fields).clone(),
),
self.extensions
.get::<crate::field_policy::SessionAdapterFields>()
.map(|fields_2| (*fields_2).clone())
.unwrap_or_else(|| {
crate::field_policy::SessionAdapterFields(Arc::new(
self.config.session.additional_fields.clone(),
))
}),
AuthContext::with_metadata(
Arc::clone(&self.config),
Arc::clone(&self.database),
self.metadata.clone(),
)
.with_extensions(self.extensions.clone()),
))
}
pub fn set_email_verification_override(
&mut self,
sender: Arc<dyn VerificationEmailOverride<S>>,
) {
self.extensions
.insert(VerificationEmailOverrideHandle(sender));
}
#[must_use]
pub fn into_parts(self) -> AuthInitParts {
AuthInitParts {
metadata: self.metadata,
email_provider: self.email_provider,
extensions: self.extensions,
}
}
}
impl std::fmt::Debug for AuthInitParts {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AuthInitParts").finish_non_exhaustive()
}
}
impl<S: AuthSchema> std::fmt::Debug for AuthInitContext<S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AuthInitContext").finish_non_exhaustive()
}
}