//! Auth token management in Redis. //! //! Refresh tokens //! ────────────── //! `refresh:{token}` → user_id, TTL 30 days //! //! Password-reset tokens //! ───────────────────── //! `reset:{token}` → user_id, TTL 1 hour use redis::AsyncCommands; use crate::RedisPool; const REFRESH_TTL: u64 = 30 * 24 * 3_600; // 30 days in seconds const RESET_TTL: u64 = 3_600; // 1 hour // ── Refresh tokens ──────────────────────────────────────────────────────────── pub async fn store_refresh( redis: &mut RedisPool, token: &str, user_id: &str, ) -> Result<(), redis::RedisError> { let key = format!("refresh:{token}"); redis.set_ex(key, user_id, REFRESH_TTL).await } /// Returns the user_id string associated with this token, or `None` if expired/invalid. pub async fn get_refresh( redis: &mut RedisPool, token: &str, ) -> Result, redis::RedisError> { let key = format!("refresh:{token}"); redis.get(key).await } /// Delete refresh token (logout / rotation). pub async fn revoke_refresh( redis: &mut RedisPool, token: &str, ) -> Result<(), redis::RedisError> { let key = format!("refresh:{token}"); redis.del(key).await } // ── Password-reset tokens ───────────────────────────────────────────────────── pub async fn store_reset( redis: &mut RedisPool, token: &str, user_id: &str, ) -> Result<(), redis::RedisError> { let key = format!("reset:{token}"); redis.set_ex(key, user_id, RESET_TTL).await } /// Atomically fetch and delete the reset token (single-use). pub async fn consume_reset( redis: &mut RedisPool, token: &str, ) -> Result, redis::RedisError> { let key = format!("reset:{token}"); redis.get_del(key).await }