I wouldn't say I'm new to JS but I haven't stuck with it long enough to be that knowledgeable so hopefully someone here can help. I have recently started making a website with React and I'm getting the following error when attempting to authenticate a user against Amazon Cognito using amazon-cognito-identity-js. I have looked around but the only thing I can find is from 2016 which is followed by comments saying it was fixed.

Versions:

React:18.2.0 amazon-cognito-identity-js:6.3.1

The error on submit:

Uncaught (in promise) TypeError: Cannot set properties of undefined (setting 'validationData')
    at AuthenticationDetails (AuthenticationDetails.js:22:1)
    at cognito.js:11:1
    ...

The aws library code that is causing the error is as follows:

AWS Cognito library (amazon-cognito-identity-js) AuthenticationDetails.js

/**
   * Constructs a new AuthenticationDetails object
   * @param {object=} data Creation options.
   * @param {string} data.Username User being authenticated.
   * @param {string} data.Password Plain-text password to authenticate with.
   * @param {(AttributeArg[])?} data.ValidationData Application extra metadata.
   * @param {(AttributeArg[])?} data.AuthParamaters Authentication paramaters for custom auth.
   */
  function AuthenticationDetails(data) {
    var _ref = data || {},
      ValidationData = _ref.ValidationData,
      Username = _ref.Username,
      Password = _ref.Password,
      AuthParameters = _ref.AuthParameters,
      ClientMetadata = _ref.ClientMetadata;
    this.validationData = ValidationData || {};
    this.authParameters = AuthParameters || {};
    this.clientMetadata = ClientMetadata || {};
    this.username = Username;
    this.password = Password;
  }

I have moved the lines about in debug to see what it does and it happens on any of the lines that seem optional (ending in || {}) even when I explicitly set the values to {}.

My Code

import { CognitoUserPool, CognitoUser, AuthenticationDetails } from 'amazon-cognito-identity-js';
import { cognitoConfig } from './cognitoConfig.js'

const userPool = new CognitoUserPool({
    UserPoolId: cognitoConfig.UserPoolId,
    ClientId: cognitoConfig.ClientId
});

export const signIn = async (username, password) => {
    return new Promise((resolve, reject) => {
        const authDetails = AuthenticationDetails({
            Username: username,
            Password: password
        })
        const cognitoUser = CognitoUser({
            Username: username,
            Pool: userPool
        });

        cognitoUser.authenticateUser(authDetails, {
            onSuccess: (result) => {
                resolve(result);
            },
            onFailure: (err) => {
                reject(err);
            }
        });
    });
};
1

There are 1 best solutions below

1
On BEST ANSWER

So I found the answer a few days ago but left it a few days for someone else to answer but no-one has so will respond for anyone who comes across the same issue.

My main issue is that so far in my learning I have mostly used inline arrow functions = () => { ... } which do not allow the new keyword when creating an instance. This lead me to think that the new keyword was not required in JS. I was wrong.

The simple fix was the following:

const authDetails = AuthenticationDetails({

changes to:

const authDetails = new AuthenticationDetails({