use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD};
use sha2::{Digest, Sha256};
use crate::rand::random_b64;
pub(crate) fn generate() -> (String, String) {
let verifier = random_b64();
let challenge = challenge_s256(&verifier);
(challenge, verifier)
}
pub(crate) fn challenge_s256(verifier: &str) -> String {
URL_SAFE_NO_PAD.encode(Sha256::digest(verifier.as_bytes()))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn rfc_7636_appendix_b() {
let verifier = "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk";
let challenge = "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM";
assert_eq!(challenge_s256(verifier), challenge);
}
#[test]
fn generated_pair_matches() {
let (challenge, verifier) = generate();
assert_eq!(challenge, challenge_s256(&verifier));
assert_eq!(verifier.len(), 43);
}
}