unjs / unenv

🕊️ Convert javaScript code to be runtime agnostic
MIT License
348 stars 18 forks source link

`getRandomValues` throwing error `TypeError: Illegal invocation` on Cloudflare Workers #133

Closed brendonmatos closed 10 months ago

brendonmatos commented 11 months ago

Environment

unenv@1.7.1 node 18

Reproduction

Unfortunately, runnings wrangler@3 from stackblitz it's still not supported. The original issue was found on Nuxt3 but there the error stops the render of the page, in Nitro this seems like just been ignored.

https://stackblitz.com/edit/github-vk94cj-546phx?file=package.json

Steps:

  1. npm run build

  2. npm run simulate

  3. Open debugger
  4. Enable image
  5. Clear application storage
  6. Enter in url

Describe the bug

Seems like when we are in Cloudflare worker environment, this kind of reference destructuring:

https://github.com/unjs/unenv/blob/2edb8fde481e3ee83d6b3c76de426a9d3d22da48/src/runtime/node/crypto/node.ts#L12-L22

Makes the invoke "Illegal"

Adding these lines makes work like a charm:

export const webcrypto = new Proxy(
  globalThis.crypto as typeof nodeCrypto.webcrypto,
  {
    get(_, key: keyof typeof globalThis.crypto | "CryptoKey") {
      if (key === "CryptoKey") {
        return globalThis.CryptoKey;
      }

+      if (typeof globalThis.crypto[key] === "function") {
+        // @ts-ignore
+        return globalThis.crypto[key].bind(globalThis.crypto);
+      }

      return globalThis.crypto[key];
    },
  },
);

Additional context

No response

Logs

TypeError: Illegal invocation
    at Object.getRandomValues (49seyck67av.js:1821:85)
    at 49seyck67av.js:1887:15
    at randomBits (49seyck67av.js:1888:5)
    at generateKey (49seyck67av.js:1906:18)
    at 49seyck67av.js:1938:22
    at seal (49seyck67av.js:1940:5)
    at 49seyck67av.js:2807:104
    at updateSession (49seyck67av.js:2809:6)
    at getSession (49seyck67av.js:2801:114)
    at useSession (49seyck67av.js:2765:9) {
pi0 commented 10 months ago

Thanks for the nice reproduction and explanations!