diff --git a/packages/amazon-cognito-identity-js/__tests__/cryptoSecureRandomInt-test.js b/packages/amazon-cognito-identity-js/__tests__/cryptoSecureRandomInt-test.js new file mode 100644 index 00000000000..c70e47777d4 --- /dev/null +++ b/packages/amazon-cognito-identity-js/__tests__/cryptoSecureRandomInt-test.js @@ -0,0 +1,59 @@ +const crypto = require('crypto'); + +describe('cryptoSecureRandomInt test', () => { + let windowSpy; + + beforeEach(() => { + jest.resetModules(); + windowSpy = jest.spyOn(window, 'window', 'get'); + }); + + afterEach(() => { + windowSpy.mockRestore(); + }); + + test('crypto is set for window (browser)', () => { + windowSpy.mockImplementation(() => ({ + crypto: { + getRandomValues: () => [12345], + }, + })); + + const cryptoSecureRandomInt = require('../src/utils/cryptoSecureRandomInt') + .default; + expect(window.crypto).toBeTruthy(); + expect(cryptoSecureRandomInt()).toBe(12345); + }); + + test('crypto is set for window (IE 11)', () => { + windowSpy.mockImplementation(() => ({ + crypto: undefined, + msCrypto: { + getRandomValues: () => [67890], + }, + })); + + const cryptoSecureRandomInt = require('../src/utils/cryptoSecureRandomInt') + .default; + expect(window.msCrypto).toBeTruthy(); + expect(cryptoSecureRandomInt()).toBe(67890); + }); + + test('crypto is set for Node', () => { + windowSpy.mockImplementation(() => ({ + crypto: null, + })); + + const randomBytesMock = jest + .spyOn(crypto, 'randomBytes') + .mockImplementationOnce(() => ({ + readInt32LE: jest.fn().mockReturnValueOnce(54321), + })); + + const cryptoSecureRandomInt = require('../src/utils/cryptoSecureRandomInt') + .default; + expect(cryptoSecureRandomInt()).toBe(54321); + + randomBytesMock.mockRestore(); + }); +}); diff --git a/packages/amazon-cognito-identity-js/src/utils/cryptoSecureRandomInt.js b/packages/amazon-cognito-identity-js/src/utils/cryptoSecureRandomInt.js index 35103184ac5..c695e84310a 100644 --- a/packages/amazon-cognito-identity-js/src/utils/cryptoSecureRandomInt.js +++ b/packages/amazon-cognito-identity-js/src/utils/cryptoSecureRandomInt.js @@ -15,6 +15,13 @@ if (!crypto && typeof global !== 'undefined' && global.crypto) { crypto = global.crypto; } +// Native crypto import via require (NodeJS) +if (!crypto && typeof require === 'function') { + try { + crypto = require('crypto'); + } catch (err) {} +} + /* * Cryptographically secure pseudorandom number generator * As Math.random() is cryptographically not safe to use diff --git a/packages/amazon-cognito-identity-js/webpack.config.js b/packages/amazon-cognito-identity-js/webpack.config.js index 7f336961f80..d344cb92c51 100644 --- a/packages/amazon-cognito-identity-js/webpack.config.js +++ b/packages/amazon-cognito-identity-js/webpack.config.js @@ -36,6 +36,9 @@ var config = { devtoolModuleFilenameTemplate: require('../aws-amplify/webpack-utils') .devtoolModuleFilenameTemplate, }, + externals: { + crypto: 'crypto', + }, plugins: [ new webpack.optimize.OccurrenceOrderPlugin(), new webpack.BannerPlugin({ banner, raw: true }),