use async_trait::async_trait;
use crate::error::Result;
#[cfg(feature = "totp")]
pub mod totp;
#[cfg(feature = "passkey")]
pub mod passkey;
#[async_trait]
pub trait MfaVerifier: Send + Sync + 'static {
async fn verify(&self, user_id: &str, method: &str, code: &str) -> Result<bool>;
}
#[derive(Default)]
pub struct MfaRouter {
factors: Vec<(String, std::sync::Arc<dyn MfaVerifier>)>,
}
impl MfaRouter {
pub fn new() -> Self {
Self::default()
}
pub fn register(mut self, method: &str, verifier: std::sync::Arc<dyn MfaVerifier>) -> Self {
self.factors.push((method.to_owned(), verifier));
self
}
}
#[async_trait]
impl MfaVerifier for MfaRouter {
async fn verify(&self, user_id: &str, method: &str, code: &str) -> Result<bool> {
for (m, v) in &self.factors {
if m == method {
return v.verify(user_id, method, code).await;
}
}
Ok(false)
}
}