use base64::engine::general_purpose::URL_SAFE_NO_PAD;
use base64::Engine;
use rand::Rng;
use sha2::{Digest, Sha256};
pub fn generate_api_key() -> (String, String) {
let mut rng = rand::thread_rng();
let mut bytes = [0u8; 32];
rng.fill(&mut bytes);
let plaintext = format!("clk_{}", URL_SAFE_NO_PAD.encode(bytes));
let hash = hash_api_key(&plaintext);
(plaintext, hash)
}
pub fn hash_api_key(key: &str) -> String {
let mut hasher = Sha256::new();
hasher.update(key.as_bytes());
format!("{:x}", hasher.finalize())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_generate_api_key_format() {
let (plaintext, hash) = generate_api_key();
assert!(plaintext.starts_with("clk_"));
assert_eq!(plaintext.len(), 47);
assert_eq!(hash.len(), 64);
}
#[test]
fn test_hash_api_key_deterministic() {
let key = "clk_test1234567890";
assert_eq!(hash_api_key(key), hash_api_key(key));
}
#[test]
fn test_generate_api_key_uniqueness() {
let (a, _) = generate_api_key();
let (b, _) = generate_api_key();
assert_ne!(a, b);
}
}