use hex; use rand_core::{OsRng, RngCore}; use crate::crypto::signed; use crate::model::config::Config; const TOKEN_BYTES: usize = 20; pub fn login(config: &Config, token: &str) -> Result { let signed_token = signed::sign(&config.auth_secret, token)?; Ok(cookie(config, &signed_token, 24 * 60 * 60)) } pub fn logout(config: &Config) -> String { cookie(config, "", 0) } pub fn extract_token(config: &Config, cookie: &str) -> Result { let mut xs = cookie.split('='); xs.next(); let signed_cookie = xs.next().ok_or("Error extracting cookie")?; signed::verify(&config.auth_secret, signed_cookie) } pub fn generate_token() -> String { let mut token = [0u8; TOKEN_BYTES]; OsRng.fill_bytes(&mut token); hex::encode(token) } fn cookie(config: &Config, token: &str, max_age_seconds: i32) -> String { let mut xs = vec![ format!("TOKEN={token}"), "SameSite=Strict".to_string(), "HttpOnly".to_string(), format!("Max-Age={}", max_age_seconds), ]; if config.secure_cookies { xs.push("Secure".to_string()) } xs.join(";") }