function base64Url(bytes) { let binary = ""; for (const byte of bytes) { binary += String.fromCharCode(byte); } return btoa(binary) .replaceAll("+", "-") .replaceAll("/", "_") .replace(/=+$/u, ""); } export async function createPkcePair(cryptoApi = globalThis.crypto) { const verifierBytes = new Uint8Array(32); cryptoApi.getRandomValues(verifierBytes); const verifier = base64Url(verifierBytes); const digest = await cryptoApi.subtle.digest( "SHA-256", new TextEncoder().encode(verifier), ); return { verifier, challenge: base64Url(new Uint8Array(digest)), method: "S256", }; }