use crate::error::Result;
use async_trait::async_trait;
use std::time::SystemTime;
#[async_trait]
pub trait UserStore: Send + Sync {
type User: Send + Sync + Clone;
async fn find_by_email(&self, email: &str) -> Result<Option<Self::User>>;
async fn find_by_id(&self, id: &str) -> Result<Option<Self::User>>;
fn user_id(&self, user: &Self::User) -> String;
fn user_email(&self, user: &Self::User) -> String;
fn user_name(&self, _user: &Self::User) -> Option<String> {
None
}
async fn get_password_hash(&self, user: &Self::User) -> Result<String>;
async fn update_password_hash(&self, user: &Self::User, hash: &str) -> Result<()>;
async fn is_verified(&self, user: &Self::User) -> Result<bool>;
async fn mark_verified(&self, user: &Self::User) -> Result<()>;
async fn is_locked(&self, user: &Self::User) -> Result<Option<SystemTime>>;
async fn record_failed_attempt(&self, user: &Self::User) -> Result<()>;
async fn record_failed_mfa_attempt(&self, user: &Self::User) -> Result<()> {
self.record_failed_attempt(user).await
}
async fn clear_failed_attempts(&self, user: &Self::User) -> Result<()>;
async fn has_mfa_enabled(&self, user: &Self::User) -> Result<bool>;
#[cfg(feature = "auth-mfa")]
async fn get_totp_secret(&self, user: &Self::User) -> Result<Option<String>>;
#[cfg(feature = "auth-mfa")]
async fn get_backup_codes(&self, user: &Self::User) -> Result<Vec<String>>;
#[cfg(feature = "auth-mfa")]
async fn remove_backup_code(&self, user: &Self::User, index: usize) -> Result<()>;
}
#[async_trait]
pub trait UserCreator: Send + Sync {
type User: Send + Sync;
fn user_id(&self, user: &Self::User) -> String;
async fn email_exists(&self, email: &str) -> Result<bool>;
async fn create_user(
&self,
email: &str,
password_hash: &str,
name: Option<&str>,
) -> Result<Self::User>;
async fn send_verification_email(&self, user: &Self::User) -> Result<()>;
}
#[async_trait]
pub trait PasswordResetStore: Send + Sync {
type User: Send + Sync;
async fn find_by_email(&self, email: &str) -> Result<Option<Self::User>>;
fn user_id(&self, user: &Self::User) -> String;
async fn store_reset_token(
&self,
user_id: &str,
token_hash: &str,
expires: SystemTime,
) -> Result<()>;
async fn consume_reset_token(&self, token_hash: &str) -> Result<Option<String>>;
async fn update_password(&self, user_id: &str, hash: &str) -> Result<()>;
async fn invalidate_sessions(&self, user_id: &str) -> Result<()>;
async fn send_reset_email(
&self,
user: &Self::User,
token: &str,
expires_in: std::time::Duration,
) -> Result<()>;
}
#[async_trait]
pub trait VerificationStore: Send + Sync {
async fn store_verification_token(
&self,
user_id: &str,
token_hash: &str,
expires: SystemTime,
) -> Result<()>;
async fn consume_verification_token(&self, token_hash: &str) -> Result<Option<String>>;
async fn mark_user_verified(&self, user_id: &str) -> Result<()>;
async fn send_verification_email(
&self,
user_id: &str,
email: &str,
token: &str,
expires_in: std::time::Duration,
) -> Result<()>;
}