AWS Amplify login with K6 failing on webpack error

I am trying to login using ‘aws-amplify’ node module.
I followed the template given [GitHub - grafana/k6-template-es6: Template repository for bundling test projects into single test scripts runnable by k6]
Basic examples run fine, but when I use for ‘aws-amplify’ compilation passes, but throws run time error.

Function which calls ‘aws-amplify’ and causes error:
Note: I have not removed commented lines to show the options already tried.

import {Amplify as amp} from 'aws-amplify';
//import { Auth } from '@aws-amplify/auth';

export function configureAmplify() {
    //const { Amplify } = import('aws-amplify');
    //const amplifyobj = new Amplify();
    amp.configure({
        Auth: {
            authenticationFlowType: 'CUSTOM_AUTH',
            region: process.env.AWS_AUTH_REGION,
            identityPoolId:  process.env.AWS_AUTH_USER_POOL_ID,
            identityPoolRegion: process.env.AWS_AUTH_REGION,
            userPoolId: process.env.AWS_AUTH_USER_POOL_ID,
            userPoolWebClientId: process.env.AWS_AUTH_USER_POOL_WEB_CLIENT_ID,
        }
    })
    
}

Webpack Configuration:

var webpack = require('webpack');
var path = require('path');

const Dotenv = require('dotenv-webpack');
module.exports = {
  mode: 'production',
  entry: './main.js',
  output: {
    path: path.resolve(__dirname, 'build'),
    libraryTarget: 'commonjs',
    filename: 'app.bundle.js',
    publicPath: '',//Added with webpack 5.74.0 & node 16.16.0
    //globalObject: 'this', //Added for ReferenceError associated in AmplifyLogin
  },
  plugins: [
    new Dotenv(),
    /*new webpack.optimize.LimitChunkCountPlugin({
      maxChunks: 1
  })*/
  ],
  /*optimization:{
    splitChunks: { chunks: 'all' }
  },*/
  module: {
    rules: [
      {
        test: /\.js$/,
        //exclude: /node_modules/,//Added to avoid Window not defined error, not resolved
        loader: 'babel-loader',
      },
    ],
  },
  stats: {
    colors: true,
  },
  target: 'web',
  externals: /^(k6|https?\:\/\/)(\/.*)?/,
  devtool: 'source-map',
};

Package.json file content

{
  "name": "k6-es6",
  "version": "1.0.0",
  "description": "test project for k6 to use es6 through the power of babel and webpack",
  "main": "main.js",
  "devDependencies": {
    "@babel/core": "^7.4.4",
    "@babel/plugin-transform-block-scoping": "^7.14.1",
    "@babel/preset-env": "^7.4.4",
    "babel-loader": "^8.0.6",
    "core-js": "^3.0.1",
    "dotenv-webpack": "^8.0.0",
    "moment": "^2.24.0",
    "webpack": "^5.74.0",
    "webpack-cli": "^4.10.0"
  },
  "engines": {},
  "scripts": {
    "webpack": "webpack",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "k6"
  ],
  "author": "Mihail Stoykov",
  "license": "ISC",
  "dependencies": {
    "amazon-cognito-identity-js": "^5.2.10",
    "aws-amplify": "^4.3.27",
    "aws-sdk": "^2.1120.0",
    "chai": "^4.3.6",
    "chai-json-schema": "^1.5.1",
    "cheerio": "^1.0.0-rc.12",
    "dotenv": "^16.0.0",
    "faker": "^5.5.3",
    "googleapis": "^100.0.0",
    "ts-node": "^10.9.1",
    "typescript": "^4.7.4",
    "xml2js": "^0.4.19"
  }
}

babel.config.json

{
  "presets": [
    [
      "@babel/preset-env"
    ]
  ],
  "plugins": [ "@babel/plugin-transform-block-scoping"]
}

Hi @sumitbhowmick, welcome to the community forum :tada: and sorry for the slow reply :frowning:

From the looks of this - this is a bug in the library that is mentioned in the stacktrace. Also it seems like it’s … unmaintained :(. So not really certain if anyone can do anything but start forking which will be fun as this likely is a dependency of a dependency that is used :(.

Unfortunately I don’t know a good way of doing this apart from editing the file by hand.

But even that will likely not help you in your case as I explained here. This particular library seems to try to polyfill the fetch API … by the looks of it for older browsers. And this is done with XMLHttpRequest which k6 also doesn’t support, and is likely that we will never even try. Although maybe a polyfill is possible :person_shrugging: .

You might want to try to expand GitHub - grafana/k6-jslib-aws: Javascript Library allowing to interact with AWS resources from k6 scripts as depending on how many APIs from aws-amplify you need … this might be a lot simpler :person_shrugging:

Hope this helps you!

Hi @mstoykov ,

Your response is helpful and motivating.
As advised, I took the hard path of changing the library by hand without success. SRP calculation is crypto intensive operation. With K6, I had to used K6 crypto library.

In following function, I didn’t find a direct replacement of following javascript code for K6.
return crypto.randomBytes(4).readInt32LE();

I replaced that with following code in K6
const bytes = crypto.randomBytes(4);
const view = new Uint32Array(bytes);
return view

I suspect this is not a good replacement as my code spend nearly 2 minutes in these complex functions without throwing any error. At the end Cognito reports invalid operation.

/*
 * Cryptographically secure pseudorandom number generator
 * As Math.random() is cryptographically not safe to use
 */
export default function cryptoSecureRandomInt() {
	if (crypto) {
		// Use getRandomValues method (Browser)
		if (typeof crypto.getRandomValues === 'function') {
			console.log(2)
			try {
				return crypto.getRandomValues(new Uint32Array(1))[0];
			} catch (err) {}
		}
		
		console.log(2.5)
		// Use randomBytes method (NodeJS)
		if (typeof crypto.randomBytes === 'function') {
			console.log(3)
			try {
				return crypto.randomBytes(4).readInt32LE();
			} catch (err) {}
		}
	}

	throw new Error(
		'Native crypto module could not be used to get secure random number.'
	);
}

Hi @sumitbhowmick,

For me the last snippet is throwing as k6 does not implement readInt32LE on the ArrayBuffer.

You can combine it though with the above so something like:

    return (new Uint32Array(crypto.randomBytes(4)))[0];

does work.

This also seems to be fairly perforamnt on my machine so :person_shrugging:.

can you provide us with a full reproducible example - maybe a github repo?

Hello @mstoykov,

We are planning to share our repo with you.
Please let me know the GitHub IDs that require access to this repo.

Thanks,
Sumit