I have an integration test that uses the AWS Cognito library; specifically, I'm calling CognitoUser.authenticateUser(). When I start my webpage this all works fine: however, in my tests I'm getting the following error:
Error: Native crypto module could not be used to get secure random number.
at cryptoSecureRandomInt (/source/project/master/website/node_modules/amazon-cognito-identity-js/lib/utils/cryptoSecureRandomInt.web.js:38:9)
at WordArray.random (/source/project/master/website/node_modules/amazon-cognito-identity-js/lib/utils/WordArray.js:50:56)
at randomBytes (/source/project/master/website/node_modules/amazon-cognito-identity-js/lib/AuthenticationHelper.js:47:58)
at AuthenticationHelper.generateRandomSmallA (/source/project/master/website/node_modules/amazon-cognito-identity-js/lib/AuthenticationHelper.js:113:21)
at new AuthenticationHelper (/source/project/master/website/node_modules/amazon-cognito-identity-js/lib/AuthenticationHelper.js:67:29)
at CognitoUser.authenticateUserDefaultAuth (/source/project/master/website/node_modules/amazon-cognito-identity-js/lib/CognitoUser.js:264:32)
at CognitoUser.authenticateUser (/source/project/master/website/node_modules/amazon-cognito-identity-js/lib/CognitoUser.js:237:19)
Researching for answers I came across many posts suggesting:
Object.defineProperty(global.self, 'crypto', {
value: {
getRandomValues: arr => crypto.randomBytes(arr.length),
}
});
Unfortunatley that does not work.
Looking at the crypto source:
function cryptoSecureRandomInt() {
if (crypto) {
// Use getRandomValues method (Browser)
if (typeof crypto.getRandomValues === 'function') {
try {
return crypto.getRandomValues(new Uint32Array(1))[0];
} catch (err) {}
} // Use randomBytes method (NodeJS)
if (typeof crypto.randomBytes === 'function') {
try {
return crypto.randomBytes(4).readInt32LE();
} catch (err) {}
}
}
throw new Error('Native crypto module could not be used to get secure random number.');
}
I can see where this error is being thrown. I'm guessing that under normal circumstances the crypto package is loaded by the browser which obviously doesn't exist when testing.
Any suggestions?
Update 1
Stepped through using the debugger and in the crypto source it's getting undefined for the 'crypto' variable on this line
if (crypto) {
This means that the Object.defineProperty is not working. I tried attaching it to the window but that doesn't work either
Object.defineProperty(window, 'crypto', {
value: {
getRandomValues: (arr) => crypto.randomBytes(arr.length)
}
});