pub mod memory;
#[cfg(feature = "redis")]
pub mod redis;
use async_trait::async_trait;
use chrono::{DateTime, Utc};
use crate::error::AuthError;
#[async_trait]
pub trait JtiCache: Send + Sync + 'static {
async fn check_and_store(
&self,
jti: &str,
expires_at: DateTime<Utc>,
) -> Result<bool, AuthError>;
}
#[derive(Debug, Clone, Copy, Default)]
pub struct DisabledJtiCache;
#[async_trait]
impl JtiCache for DisabledJtiCache {
async fn check_and_store(
&self,
_jti: &str,
_expires_at: DateTime<Utc>,
) -> Result<bool, AuthError> {
Ok(false)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn disabled_cache_never_reports_replay() {
let cache = DisabledJtiCache;
let expires = Utc::now();
assert!(!cache.check_and_store("same-jti", expires).await.unwrap());
assert!(!cache.check_and_store("same-jti", expires).await.unwrap());
}
}