oauth2-client icon indicating copy to clipboard operation
oauth2-client copied to clipboard

code verifier generation fails in a service worker

Open ymajoros opened this issue 2 years ago • 2 comments

This code from authorization-code.ts failed:

      const arr = new Uint8Array(32);
      crypto.webcrypto.getRandomValues(arr);
      return base64Url(arr);

So I had to create my own solution:

function generateCodeVerifier() {
    const emptyCodeVerifierArray = new Uint8Array(32);
    const codeVerifierArray = crypto.getRandomValues(emptyCodeVerifierArray);
    return btoa(String.fromCharCode(...codeVerifierArray));
}

ymajoros avatar Jun 28 '22 13:06 ymajoros

I haven't done a lot of with Service workers. My understanding is that this is failing because window does not exist in this context, but from what I could read self.crypto does exist as refers to the same thing.

So with that in mind, does the following implementation work for you as a universal solution? The webworker case should now be handled in the first block.

export async function generateCodeVerifier(): Promise<string> {

  if ((typeof window !== 'undefined' && window.crypto) || (typeof self !== 'undefined' && self.crypto)) {
    // Built-in webcrypto
    const arr = new Uint8Array(32);
    crypto.getRandomValues(arr);
    return base64Url(arr);
  } else {

    // eslint-disable-next-line @typescript-eslint/no-var-requires
    const crypto = require('crypto');
    if (crypto.webcrypto) {
      // Webcrypto in a Node 16 or 18 module
      const arr = new Uint8Array(32);
      crypto.webcrypto.getRandomValues(arr);
      return base64Url(arr);

    } else {

      // Old node
      return new Promise<string>((res, rej) => {
        crypto.randomBytes(32, (err:Error, buf: Buffer) => {
          if (err) rej(err);
          res(buf.toString('base64url'));
        });
      });

    }

  }

}

evert avatar Jun 29 '22 03:06 evert

Leaving for two weeks now, I'll only be able to test it while back. The provided solution works for sure, can't tell about the universal one you provided without testing as service workers are quite sensitive.

ymajoros avatar Jun 29 '22 06:06 ymajoros

Closing due to no feedback

evert avatar Aug 01 '23 14:08 evert