Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Broken on SSR #33

Open
mz921 opened this issue Sep 8, 2022 · 2 comments
Open

Broken on SSR #33

mz921 opened this issue Sep 8, 2022 · 2 comments

Comments

@mz921
Copy link

mz921 commented Sep 8, 2022

This library is broken on SSR,because webpack won't replace global to window object, and global.crypto is undefined.

@razorness
Copy link

Same with Vite.js: Uncaught ReferenceError: global is not defined

@catamphetamine
Copy link

Fixed code:

npm install buffer --save
// Copy-pasted from the source code of an unmaintained package:
// https://github.com/browserify/randombytes/blob/master/browser.js
//
// Fixed `Uncaught ReferenceError: global is not defined`.
// https://github.com/browserify/randombytes/issues/33
//
// Replaced `safe-buffer` with `buffer`.

// eslint-disable-next-line unicorn/prefer-node-protocol
import Buffer from 'buffer';

// limit of Crypto.getRandomValues()
// https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
const MAX_BYTES = 65_536;

// Node supports requesting up to this number of bytes
// https://github.com/nodejs/node/blob/master/lib/internal/crypto/random.js#L48
const MAX_UINT32 = 4_294_967_295;

// eslint-disable-next-line no-undef
const crypto = typeof window === 'undefined' ? null : window.crypto;

// https://nodejs.org/api/crypto.html#cryptorandombytessize-callback
export default function randomBytes_(size, callback) {
  if (!crypto || !crypto.getRandomValues) {
    throw new Error('Secure random number generation is not supported by this browser.\nUse Chrome, Firefox or Internet Explorer 11');
  }

  return randomBytes(size, callback);
}

function randomBytes(size, cb) {
  // phantomjs needs to throw
  if (size > MAX_UINT32) {
    throw new RangeError('requested too many random bytes');
  }

  const bytes = Buffer.allocUnsafe(size);

  if (size > 0) { // getRandomValues fails on IE if size == 0
    if (size > MAX_BYTES) { // this is the max bytes crypto.getRandomValues
      // can do at once see https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues
      for (let generated = 0; generated < size; generated += MAX_BYTES) {
        // buffer.slice automatically checks if the end is past the end of
        // the buffer so we don't have to here
        crypto.getRandomValues(bytes.slice(generated, generated + MAX_BYTES));
      }
    } else {
      crypto.getRandomValues(bytes);
    }
  }

  if (typeof cb === 'function') {
    return process.nextTick(() => {
      cb(null, bytes);
    });
  }

  return bytes;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants