import crypto from "crypto"; /** * Generate PKCE code verifier (43-128 characters) * * @param {number} [bytes=32] number of random bytes (xAI uses 96) */ export function generateCodeVerifier(bytes = 32) { return crypto.randomBytes(bytes).toString("base64url"); } /** * Generate PKCE code challenge from verifier (S256 method) */ export function generateCodeChallenge(verifier) { return crypto.createHash("sha256").update(verifier).digest("base64url"); } /** * Generate random state for CSRF protection */ export function generateState() { return crypto.randomBytes(32).toString("base64url"); } /** * Generate complete PKCE pair */ export function generatePKCE(bytes = 32) { const codeVerifier = generateCodeVerifier(bytes); const codeChallenge = generateCodeChallenge(codeVerifier); const state = generateState(); return { codeVerifier, codeChallenge, state, }; }