forked from
slices.network/quickslice
Auto-indexing service and GraphQL API for AT Protocol Records
1/// PKCE (Proof Key for Code Exchange) implementation
2/// Reference: RFC 7636
3import gleam/bit_array
4import gleam/crypto
5
6/// Generate a cryptographically random code verifier
7/// Returns a 43-128 character URL-safe string
8pub fn generate_code_verifier() -> String {
9 let random_bytes = crypto.strong_random_bytes(32)
10 bit_array.base64_url_encode(random_bytes, False)
11}
12
13/// Generate a code challenge from a code verifier using S256 method
14/// SHA-256 hash of verifier, base64url encoded
15pub fn generate_code_challenge(verifier: String) -> String {
16 let verifier_bytes = bit_array.from_string(verifier)
17 let hash = crypto.hash(crypto.Sha256, verifier_bytes)
18 bit_array.base64_url_encode(hash, False)
19}
20
21/// Verify a code verifier against a code challenge
22/// Returns True if the verifier matches the challenge using S256
23pub fn verify_code_challenge(
24 verifier: String,
25 challenge: String,
26 method: String,
27) -> Bool {
28 case method {
29 "S256" -> {
30 let computed_challenge = generate_code_challenge(verifier)
31 computed_challenge == challenge
32 }
33 "plain" -> verifier == challenge
34 _ -> False
35 }
36}