Skip to content

Commit

Permalink
fix(NODE-4211): Do not require crypto in browser builds (#500)
Browse files Browse the repository at this point in the history
  • Loading branch information
rvanmil committed Jun 14, 2022
1 parent 210fc11 commit b32ab40
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 34 deletions.
26 changes: 25 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -43,6 +43,7 @@
"@rollup/plugin-commonjs": "^15.0.0",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^9.0.0",
"@rollup/plugin-replace": "^4.0.0",
"@rollup/plugin-typescript": "^6.0.0",
"@typescript-eslint/eslint-plugin": "^3.10.1",
"@typescript-eslint/parser": "^3.10.1",
Expand Down
37 changes: 23 additions & 14 deletions rollup.config.js
Expand Up @@ -5,6 +5,7 @@ import { nodeResolve } from '@rollup/plugin-node-resolve';
import { babel } from '@rollup/plugin-babel';
import typescript from '@rollup/plugin-typescript';
import nodeGlobals from 'rollup-plugin-node-globals';
import replace from '@rollup/plugin-replace';

const tsConfig = {
allowJs: false,
Expand Down Expand Up @@ -33,18 +34,26 @@ const tsConfig = {
};
const input = 'src/bson.ts';

const plugins = [
typescript(tsConfig),
nodeResolve({ preferBuiltins: false }),
nodeBuiltins(),
nodeGlobals(),
commonjs({ extensions: ['.js', '.ts'] }),
babel({
babelHelpers: 'external',
plugins: ['@babel/plugin-external-helpers'],
presets: [['@babel/env', { modules: false }]]
})
];
const plugins = (options = { browser: false }) => {
return [
typescript(tsConfig),
nodeResolve({ preferBuiltins: false }),
nodeBuiltins(),
nodeGlobals(),
replace({
preventAssignment: true,
values: {
'process.browser': options.browser
}
}),
commonjs({ extensions: ['.js', '.ts'] }),
babel({
babelHelpers: 'external',
plugins: ['@babel/plugin-external-helpers'],
presets: [['@babel/env', { modules: false }]]
})
];
};

const external = Object.keys(pkg.dependencies || {});

Expand All @@ -60,7 +69,7 @@ module.exports = [
exports: 'named',
sourcemap: true
},
plugins,
plugins: plugins(),
external
},
{
Expand Down Expand Up @@ -88,6 +97,6 @@ module.exports = [
sourcemap: true
}
],
plugins
plugins: plugins({ browser: true })
}
];
44 changes: 25 additions & 19 deletions src/parser/utils.ts
Expand Up @@ -34,32 +34,38 @@ declare let require: Function;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
declare let global: any;
declare const self: unknown;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
declare let process: any; // Used by @rollup/plugin-replace

const detectRandomBytes = (): RandomBytesFunction => {
if (typeof window !== 'undefined') {
// browser crypto implementation(s)
const target = window.crypto || window.msCrypto; // allow for IE11
if (target && target.getRandomValues) {
return size => target.getRandomValues(Buffer.alloc(size));
if (process.browser) {
if (typeof window !== 'undefined') {
// browser crypto implementation(s)
const target = window.crypto || window.msCrypto; // allow for IE11
if (target && target.getRandomValues) {
return size => target.getRandomValues(Buffer.alloc(size));
}
}
}

if (typeof global !== 'undefined' && global.crypto && global.crypto.getRandomValues) {
// allow for RN packages such as https://www.npmjs.com/package/react-native-get-random-values to populate global
return size => global.crypto.getRandomValues(Buffer.alloc(size));
}
if (typeof global !== 'undefined' && global.crypto && global.crypto.getRandomValues) {
// allow for RN packages such as https://www.npmjs.com/package/react-native-get-random-values to populate global
return size => global.crypto.getRandomValues(Buffer.alloc(size));
}

let requiredRandomBytes: RandomBytesFunction | null | undefined;
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
requiredRandomBytes = require('crypto').randomBytes;
} catch (e) {
// keep the fallback
}
return insecureRandomBytes;
} else {
let requiredRandomBytes: RandomBytesFunction | null | undefined;
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
requiredRandomBytes = require('crypto').randomBytes;
} catch (e) {
// keep the fallback
}

// NOTE: in transpiled cases the above require might return null/undefined
// NOTE: in transpiled cases the above require might return null/undefined

return requiredRandomBytes || insecureRandomBytes;
return requiredRandomBytes || insecureRandomBytes;
}
};

export const randomBytes = detectRandomBytes();
Expand Down

0 comments on commit b32ab40

Please sign in to comment.