basant307/AI_Governance_Project
048
1let crypto;2crypto =3 globalThis.crypto?.webcrypto ?? // Node.js [18-16] REPL4 globalThis.crypto ?? // Node.js >185 import("node:crypto").then(m => m.webcrypto); // Node.js <18 Non-REPL6/**7 * Creates an array of length `size` of random bytes8 * @param size9 * @returns Array of random ints (0 to 255)10 */11async function getRandomValues(size) {12 return (await crypto).getRandomValues(new Uint8Array(size));13}14/** Generate cryptographically strong random string15 * @param size The desired length of the string16 * @returns The random string17 */18async function random(size) {19 const mask = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~";20 let result = "";21 const randomUints = await getRandomValues(size);22 for (let i = 0; i < size; i++) {23 // cap the value of the randomIndex to mask.length - 124 const randomIndex = randomUints[i] % mask.length;25 result += mask[randomIndex];26 }27 return result;28}29/** Generate a PKCE challenge verifier30 * @param length Length of the verifier31 * @returns A random verifier `length` characters long32 */33async function generateVerifier(length) {34 return await random(length);35}36/** Generate a PKCE code challenge from a code verifier37 * @param code_verifier38 * @returns The base64 url encoded code challenge39 */40export async function generateChallenge(code_verifier) {41 const buffer = await (await crypto).subtle.digest("SHA-256", new TextEncoder().encode(code_verifier));42 // Generate base64url string43 // btoa is deprecated in Node.js but is used here for web browser compatibility44 // (which has no good replacement yet, see also https://github.com/whatwg/html/issues/6811)45 return btoa(String.fromCharCode(...new Uint8Array(buffer)))46 .replace(/\//g, '_')47 .replace(/\+/g, '-')48 .replace(/=/g, '');49}50/** Generate a PKCE challenge pair51 * @param length Length of the verifer (between 43-128). Defaults to 43.52 * @returns PKCE challenge pair53 */54export default async function pkceChallenge(length) {55 if (!length)56 length = 43;57 if (length < 43 || length > 128) {58 throw `Expected a length between 43 and 128. Received ${length}.`;59 }60 const verifier = await generateVerifier(length);61 const challenge = await generateChallenge(verifier);62 return {63 code_verifier: verifier,64 code_challenge: challenge,65 };66}67/** Verify that a code_verifier produces the expected code challenge68 * @param code_verifier69 * @param expectedChallenge The code challenge to verify70 * @returns True if challenges are equal. False otherwise.71 */72export async function verifyChallenge(code_verifier, expectedChallenge) {73 const actualChallenge = await generateChallenge(code_verifier);74 return actualChallenge === expectedChallenge;75}76 