Skip to main content

authkestra_engine/auth/
pkce.rs

1use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine as _};
2use rand::{distr::Alphanumeric, rng, Rng};
3use sha2::{Digest, Sha256};
4
5/// Proof Key for Code Exchange (PKCE) parameters.
6#[derive(Debug, Clone)]
7#[non_exhaustive]
8pub struct Pkce {
9    /// High-entropy cryptographic random string
10    pub code_verifier: String,
11    /// BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
12    pub code_challenge: String,
13}
14
15impl Pkce {
16    /// Generates a new PKCE verifier and challenge.
17    pub fn new() -> Self {
18        let code_verifier: String = rng()
19            .sample_iter(&Alphanumeric)
20            .take(64)
21            .map(char::from)
22            .collect();
23
24        let mut hasher = Sha256::new();
25        hasher.update(code_verifier.as_bytes());
26        let hash = hasher.finalize();
27
28        let code_challenge = URL_SAFE_NO_PAD.encode(hash);
29
30        Self {
31            code_verifier,
32            code_challenge,
33        }
34    }
35}
36
37impl Default for Pkce {
38    fn default() -> Self {
39        Self::new()
40    }
41}