11import type { webcrypto } from 'node:crypto' ;
22
3- let crypto : webcrypto . Crypto ;
3+ let crypto : webcrypto . Crypto | Promise < webcrypto . Crypto > ;
44
55// diverge:if env=browser
66crypto = globalThis . crypto ; // web browsers
77// diverge:else
88crypto =
99 globalThis . crypto ?. webcrypto ?? // Node.js 16 REPL has globalThis.crypto as node:crypto
10- globalThis . crypto ?? // Node.js 18+
11- ( await import ( "node:crypto" ) ) . webcrypto ; // Node.js 16 non-REPL
10+ globalThis . crypto ?? // Node.js 18+
11+ import ( "node:crypto" ) . then ( m => m . webcrypto ) ; // Node.js 16 non-REPL
1212// diverge:fi
1313
1414/**
1515 * Creates an array of length `size` of random bytes
1616 * @param size
1717 * @returns Array of random ints (0 to 255)
1818 */
19- function getRandomValues ( size : number ) {
20- return crypto . getRandomValues ( new Uint8Array ( size ) ) ;
19+ async function getRandomValues ( size : number ) {
20+ return ( await crypto ) . getRandomValues ( new Uint8Array ( size ) ) ;
2121}
2222
2323/** Generate cryptographically strong random string
2424 * @param size The desired length of the string
2525 * @returns The random string
2626 */
27- function random ( size : number ) {
27+ async function random ( size : number ) {
2828 const mask =
2929 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~" ;
3030 let result = "" ;
31- const randomUints = getRandomValues ( size ) ;
31+ const randomUints = await getRandomValues ( size ) ;
3232 for ( let i = 0 ; i < size ; i ++ ) {
3333 // cap the value of the randomIndex to mask.length - 1
3434 const randomIndex = randomUints [ i ] % mask . length ;
@@ -41,16 +41,16 @@ function random(size: number) {
4141 * @param length Length of the verifier
4242 * @returns A random verifier `length` characters long
4343 */
44- function generateVerifier ( length : number ) : string {
45- return random ( length ) ;
44+ async function generateVerifier ( length : number ) : Promise < string > {
45+ return await random ( length ) ;
4646}
4747
4848/** Generate a PKCE code challenge from a code verifier
4949 * @param code_verifier
5050 * @returns The base64 url encoded code challenge
5151 */
5252export async function generateChallenge ( code_verifier : string ) {
53- const buffer = await crypto . subtle . digest (
53+ const buffer = await ( await crypto ) . subtle . digest (
5454 "SHA-256" ,
5555 new TextEncoder ( ) . encode ( code_verifier )
5656 ) ;
@@ -77,7 +77,7 @@ export default async function pkceChallenge(length?: number): Promise<{
7777 throw `Expected a length between 43 and 128. Received ${ length } .` ;
7878 }
7979
80- const verifier = generateVerifier ( length ) ;
80+ const verifier = await generateVerifier ( length ) ;
8181 const challenge = await generateChallenge ( verifier ) ;
8282
8383 return {
0 commit comments