1use base64::{engine::general_purpose, Engine as _};
2use sha2::{Digest as _, Sha256};
3
4use crate::types::{
5 code_verifier::{CODE_VERIFIER_LEN_MAX, CODE_VERIFIER_LEN_MIN},
6 CodeChallenge, CodeChallengeMethod, CodeVerifier,
7};
8
9pub fn gen_code_challenge(
11 code_verifier: CodeVerifier,
12 code_challenge_method: impl Into<Option<CodeChallengeMethod>>,
13) -> (CodeChallenge, CodeChallengeMethod) {
14 assert!(
15 code_verifier.len() >= CODE_VERIFIER_LEN_MIN
16 && code_verifier.len() <= CODE_VERIFIER_LEN_MAX
17 );
18
19 let code_challenge_method: CodeChallengeMethod =
20 code_challenge_method.into().unwrap_or_default();
21
22 let code_challenge = match code_challenge_method {
23 CodeChallengeMethod::Sha256 => {
24 let digest = Sha256::digest(code_verifier.as_bytes());
25 general_purpose::URL_SAFE_NO_PAD.encode(digest)
26 }
27 CodeChallengeMethod::Plain => code_verifier,
28 };
29
30 (code_challenge, code_challenge_method)
31}