use cache::CacheConn; use config::redis::RedisConfig; use crate::error::InternalError; #[derive(Clone)] pub struct NonceStore { conn: CacheConn, } impl NonceStore { pub fn from_conn(conn: CacheConn) -> Self { Self { conn } } pub async fn connect(config: &RedisConfig, _prefix: &str) -> Result { let conn = CacheConn::init(config) .await .map_err(|error| InternalError::Config(format!("redis: {error}")))?; Ok(Self::from_conn(conn)) } /// `SET key 1 NX EX ttl`:第一次出现返回 true,重放返回 false。 pub async fn accept(&self, key: &str, ttl_secs: u64) -> Result { let mut conn = self.conn.clone(); let result: Option = redis::cmd("SET") .arg(key) .arg("1") .arg("NX") .arg("EX") .arg(ttl_secs.max(1)) .query_async(&mut conn) .await?; Ok(result.is_some()) } } pub fn key(audience: &str, nonce: &str) -> String { format!("event:identity:nonce:{audience}:{nonce}") }