amplify-js: Auth.signUp doesn't work with validationData

Describe the bug When calling Auth.signUp with a username, password and a set of validationData and without a set of attributes, it fails with

Cannot read property ‘0’ of undefined

To Reproduce Steps to reproduce the behavior:

  1. Create a SignUpParams Object with username, password, validationData and nothing else
  2. Call Auth.signUp() with said object

Expected behavior No error.

Code Snippet In Auth.ts, lines 318 through 334:

if (attrs) {
    Object.keys(attrs).map(key => {
	    attributes.push(
		    new CognitoUserAttribute({ Name: key, Value: attrs[key] })
	    );
    });
}

const validationDataObject = params['validationData'];
if (validationDataObject) {
    validationData = [];
    Object.keys(validationDataObject).map(key => {
	    validationData.push(
		    new CognitoUserAttribute({ Name: key, Value: attrs[key] })
	    );
    });
}

In the second if statement I believe it should be validationDataObject[key] instead of attrs[key]

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 6
  • Comments: 18 (6 by maintainers)

Most upvoted comments

@eryon very glad this works for you now! Thanks for validating on your end.

@davidgarc & @calumleask thank you for calling out the TypeScript issue here, I was also able to reproduce this and have discovered a fix which I will be submitting in a PR shortly to address the problem.

@evcodes This issue appears to have been introduced in @aws-amplify/auth@3.4.18. Running the same code in 3.4.17 works as expected.

Example of incorrect ValidationData (3.4.18): image

Example of correct ValidationData (3.4.17): image

Thanks @nickarocho all working with typescript now

@eryon I messed around with this a bit and was able to successfully sign users up by passing validation data like this:

validationData: {
  'invitationCode': action.user.invitation
}

In any case, please give this approach a shot and let me know if it solves the problem.

@nickarocho thanks for the update. This does work better when it is a plain object and not an array, and this is a more natural JS API. I can see the library converts it to an array of Name/Value entries for the request, under the hood, and that’s all right with me; maybe this is what the docs are referring to, but clearly it’s not the way the API actually works 😃

Anyway, this fixes my problem. I can use the latest aws-amplify@3.3.26 (using @aws-amplify/auth@3.4.29 under the hood) now 🎉

We had the same issue with v3.3.20. Switching back to version "aws-amplify": "3.3.11", fixed the problem (Other version might work as well, but this was the last one we had in)

npm i aws-amplify@3.3.11

@eryon I messed around with this a bit and was able to successfully sign users up by passing validation data like this:

validationData: {
  'invitationCode': action.user.invitation
}

So in summary, I am:

  1. Not passing an array of objects, but rather a regular object with key: 'value' pairs.
  2. Omitting the “Name” and “Value” keys. This is already inferred by the native object you are passing.

I’ve attached a screenshot of my sample app code to show an example of how this also works with multiple attributes, like such:

validationData: {
  foo: 'bar',
  test: '123',
  invitationCode: 'VwXyZ',
},
Screen Shot 2021-04-02 at 6 12 13 PM

To be verbose:

✅ This works
validationData: {
  foo: 'bar',
},

❌ This doesn't work - (contains unnecessary keys)
validationData: {
  Name: 'foo',
  Value: 'bar',
},


✅ This works
validationData: {
  foo: 'bar',
  invitationCode: 'VwXyZ',
  test: '123',
},

❌ This doesn't work - (passed as an array)
 validationData: [
  {
    foo: 'bar',
    invitationCode: 'VwXyZ',
    test: '123',
  }
],

I’m still looking into the history of if/when this syntax might have changed.

If this is how the validationData is supposed to be passed (still need to double check the source code to be sure, even though it appears correct), it looks like our documentation needs to be corrected.

Via the Amplify Auth docs: https://docs.amplify.aws/lib/auth/advanced/q/platform/js#pre-authentication-and-pre-sign-up-lambda-triggers

validationData, // Optional, an array of key-value pairs which can contain any key and will be passed to your Lambda trigger as-is.

(This is explained in Auth.signIn() rather than Auth.signUp() but at first glance it seems to treat validationData similarly in both methods.)

I will create a ticket to adjust the documentation on our side after consulting the rest of the team to ensure this is correct.

In any case, please give this approach a shot and let me know if it solves the problem.

Thanks!

Hi @eryon, just wanted to touch base with you here to let you know we are actively working on reproducing this issue to fully understand the scope and determine the underlying problem.

Thank you for your patience while we continue to investigate.

Not quite fixed, but getting closer I think. The correct object seems to be nested within another validation object.

Screenshot taken from @aws-amplify/auth@3.4.24: image

Hello @davidgarc & @calumleask, we have merged https://github.com/aws-amplify/amplify-js/pull/8045 that fixes this issue.

This will be available in aws-amplify@unstable shortly and will be released in the next release cycle. Please let us know if the issue persists afterwards.

I’ll be opening a PR today to update our documentation to avoid any future confusion on how to pass validationData to these methods.

Thanks!

I’m also using Typescript. Only wanting to update from v3.3.14 to fix high vulnerability aws-amplify > @aws-amplify/datastore > immer

I might be wrong but my earlier comment links to the commit that introduced the issue.

Also experiencing this issue since updating aws-amplify from 3.3.14 which breaks recaptcha validation in a preSignUp lambda since the recaptcha token is not longer making it to the lambda.

I don’t think the fix from the initial comment will fix the underlying issue since ValidationDataObject isn’t defined as an object, it’s an array which is why the key is being set as “0”.

I believe this line may have been incorrectly changed?

3a9efb0#diff-d7133ba15216009e91d0c1632f34aa2279f4e6a03873e701c4abf582e011ed5fL314

Unless the type here is also updated to be an object but that would be a breaking change?

https://github.com/aws-amplify/amplify-js/blob/main/packages/auth/src/types/Auth.ts#L27

Hi @eryon, quick update - I was able to reproduce the same error on my end with a fresh React app and directly calling Auth.signUp({...}). I’ve labeled this as a bug and I’m going to move forward trying to get to the bottom of the problem.

Any insight on this issue? Getting this after updating dependencies (3.4.16 -> 3.4.28), which I needed to do in order to support functional analytics (3.2.7 -> 4.0.16 #7934). Now users can’t sign up because I need to include an invitation code in the validation data.

I can use the code below (the piece in red, which worked before) or I can alter it (green) and reproduce the above users’ issues. If I use the original code, the error is a little different.

    const { userSub } = yield call([Auth, Auth.signUp], {
      username: action.user.email,
      password: action.user.password,
      attributes: {
        name: action.user.name
      },
      validationData: [
        {
-          Name: 'invitationCode',
-          Value: action.user.invitation
+         invitationCode: action.user.invitation
        }
      ]
    });

Original code, different but still related error: {"__type":"SerializationException","Message":"Start of structure or map found where not expected."}

If I roll back to auth <= 3.4.16, sign up with validation data works fine. If I stay on auth@3.4.28 and remove the validationData entirely, the request works but my business logic fails because I need it.

Not quite fixed, but getting closer I think. The correct object seems to be nested within another validation object.

Screenshot taken from @aws-amplify/auth@3.4.24: image

Still having the same issue as well

Also experiencing this issue since updating aws-amplify from 3.3.14 which breaks recaptcha validation in a preSignUp lambda since the recaptcha token is not longer making it to the lambda.

I don’t think the fix from the initial comment will fix the underlying issue since ValidationDataObject isn’t defined as an object, it’s an array which is why the key is being set as “0”.

I believe this line may have been incorrectly changed?

https://github.com/aws-amplify/amplify-js/commit/3a9efb0b596cf2795d7e1424f011f8e59058ecfb#diff-d7133ba15216009e91d0c1632f34aa2279f4e6a03873e701c4abf582e011ed5fL314

Unless the type here is also updated to be an object but that would be a breaking change?

https://github.com/aws-amplify/amplify-js/blob/main/packages/auth/src/types/Auth.ts#L27