AtAuth
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 69 lines 1.8 kB view raw
1/** 2 * PKCE (Proof Key for Code Exchange) Utilities 3 * 4 * Handles PKCE code challenge verification for OAuth 2.0 5 */ 6 7import crypto from 'crypto'; 8 9/** 10 * Verify a PKCE code verifier against a code challenge 11 */ 12export function verifyCodeChallenge( 13 codeVerifier: string, 14 codeChallenge: string, 15 method: 'S256' | 'plain' = 'S256' 16): boolean { 17 // Reject plain method -- only S256 is secure 18 if (method === 'plain') { 19 return false; 20 } 21 22 // S256: SHA256(code_verifier) base64url encoded 23 const hash = crypto.createHash('sha256').update(codeVerifier).digest(); 24 const computed = hash.toString('base64url'); 25 26 // Constant-time comparison to prevent timing attacks 27 const a = Buffer.from(computed); 28 const b = Buffer.from(codeChallenge); 29 if (a.length !== b.length) return false; 30 return crypto.timingSafeEqual(a, b); 31} 32 33/** 34 * Generate a code verifier for testing 35 */ 36export function generateCodeVerifier(): string { 37 return crypto.randomBytes(32).toString('base64url'); 38} 39 40/** 41 * Generate a code challenge from a code verifier 42 */ 43export function generateCodeChallenge(codeVerifier: string, method: 'S256' | 'plain' = 'S256'): string { 44 if (method === 'plain') { 45 return codeVerifier; 46 } 47 48 const hash = crypto.createHash('sha256').update(codeVerifier).digest(); 49 return hash.toString('base64url'); 50} 51 52/** 53 * Validate code verifier format 54 * Must be 43-128 characters, containing only [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" 55 */ 56export function isValidCodeVerifier(codeVerifier: string): boolean { 57 if (codeVerifier.length < 43 || codeVerifier.length > 128) { 58 return false; 59 } 60 61 return /^[A-Za-z0-9\-._~]+$/.test(codeVerifier); 62} 63 64/** 65 * Validate code challenge method 66 */ 67export function isValidCodeChallengeMethod(method: string): method is 'S256' { 68 return method === 'S256'; 69}