//! # User tokens management use crate::connections::redis_connection; use crate::models::{User, UserID}; use crate::utils::string_utils; use crate::utils::time_utils::time; use std::time::Duration; #[derive(serde::Serialize, serde::Deserialize, Debug, Clone)] struct LoginToken { expire: u64, hb: u64, user_id: UserID, } impl LoginToken { pub fn new(user: &User) -> (String, Self) { let key = format!("tok-{}-{}", user.id().0, string_utils::rand_str(40)); ( key, Self { expire: time() + 3600 * 24, hb: time(), user_id: user.id(), }, ) } pub fn is_valid(&self) -> bool { self.expire > time() && self.hb + 3600 > time() } pub fn refresh_hb(&self) -> Option { if self.hb + 60 * 5 < time() { let mut new = self.clone(); new.hb = time(); Some(new) } else { None } } pub fn lifetime(&self) -> Duration { Duration::from_secs(if self.expire <= time() { 0 } else { self.expire - time() }) } } /// Generate a new login token pub async fn gen_new_token(user: &User) -> anyhow::Result { let (key, token) = LoginToken::new(user); redis_connection::set_value(&key, &token, token.lifetime()).await?; Ok(key) }