use anyhow::{Context, Result}; use rand::{Rng, RngExt}; use sha2::{Digest, Sha256}; use url::Url; pub fn loopback_redirect_uri(port: u16) -> Result { Url::parse(&format!("http://127.0.0.1:{port}/oauth/callback")) .context("failed to build loopback redirect URI") } pub fn new_device_fingerprint() -> String { let mut bytes = [0_u8; 16]; rand::rng().fill(&mut bytes); hex::encode(bytes) } pub fn new_device_login_token() -> String { let mut bytes = [0_u8; 32]; rand::rng().fill_bytes(&mut bytes); hex::encode(bytes) } pub fn hash_device_login_token(token: &str) -> String { let mut hasher = Sha256::new(); hasher.update(token.as_bytes()); hex::encode(hasher.finalize()) }