1use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _};
2use rand::{distr::Alphanumeric, rng, Rng};
3use sha2::{Digest, Sha256};
4
5#[derive(Debug, Clone)]
7pub struct Pkce {
8 pub code_verifier: String,
10 pub code_challenge: String,
12}
13
14impl Pkce {
15 pub fn new() -> Self {
17 let code_verifier: String = rng()
18 .sample_iter(&Alphanumeric)
19 .take(64)
20 .map(char::from)
21 .collect();
22
23 let mut hasher = Sha256::new();
24 hasher.update(code_verifier.as_bytes());
25 let hash = hasher.finalize();
26
27 let code_challenge = URL_SAFE_NO_PAD.encode(hash);
28
29 Self {
30 code_verifier,
31 code_challenge,
32 }
33 }
34}
35
36impl Default for Pkce {
37 fn default() -> Self {
38 Self::new()
39 }
40}