pub mod config;
pub mod session;
pub mod sessions;
pub mod types;
pub fn user_hash(key: &str) -> String {
use sha2::{Digest, Sha256};
let mut hasher = Sha256::new();
hasher.update(key.as_bytes());
let hash_bytes = hasher.finalize();
format!(
"{:016x}",
u64::from_be_bytes(
hash_bytes[..8]
.try_into()
.expect("SHA-256 digest is ≥ 8 bytes")
)
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn user_hash_known_vector() {
assert_eq!(user_hash("test"), "9f86d081884c7d65");
}
#[test]
fn user_hash_is_deterministic() {
assert_eq!(
user_hash("farzan@example.com"),
user_hash("farzan@example.com")
);
}
#[test]
fn user_hash_is_hex16_and_input_sensitive() {
let a = user_hash("alice");
let b = user_hash("bob");
assert_eq!(a.len(), 16);
assert_eq!(b.len(), 16);
assert!(a.chars().all(|c| c.is_ascii_hexdigit()));
assert!(b.chars().all(|c| c.is_ascii_hexdigit()));
assert_ne!(a, b);
}
#[test]
fn user_hash_matches_full_sha256_prefix() {
use sha2::{Digest, Sha256};
let full = Sha256::digest("trustee");
let expected = full[..8]
.iter()
.map(|b| format!("{:02x}", b))
.collect::<String>();
assert_eq!(user_hash("trustee"), expected);
}
}