aws / aws-sdk-js-v3

Modularized AWS SDK for JavaScript.
Apache License 2.0
3.04k stars 569 forks source link

AdminLinkProviderForUserCommand throws InvalidParameterException incorrectly #5281

Closed ignaciolarranaga closed 11 months ago

ignaciolarranaga commented 11 months ago

Checkboxes for prior research

Describe the bug

The following sequence causes the AdminLinkProviderForUserCommand command to throw InvalidParameterException: "Invalid SourceUser: Cognito users with a username/password may not be passed in as a SourceUser, only as a DestinationUser" while really parameters are passed correctly (indeed the linking is executed).

SDK version number

@aws-sdk/client-cognito-identity-provider@3.421.0

Which JavaScript Runtime is this issue in?

Node.js

Details of the browser/Node.js/ReactNative version

Lambda with node 18.x

Reproduction Steps

  1. Create a CognitoUser Pool with for example a Google provider
  2. Register a user with username/password
  3. Link the user in the PreSignUpTriggerEvent

Observed Behavior

The user is linked but an exception is thrown

Expected Behavior

The user is linked but NO exception is thrown

Possible Solution

No response

Additional Information/Context

Example stack trace:

2023-09-29T13:38:31.067Z    996fe0d3-1f4d-4009-a3e1-1bcac35f9aaa    ERROR   Invoke Error    {
    "errorType": "InvalidParameterException",
    "errorMessage": "Invalid SourceUser: Cognito users with a username/password may not be passed in as a SourceUser, only as a DestinationUser",
    "name": "InvalidParameterException",
    "$fault": "client",
    "$metadata": {
        "httpStatusCode": 400,
        "requestId": "1213cff5-6377-41ea-840f-018074efdb75",
        "attempts": 1,
        "totalRetryDelay": 0
    },
    "__type": "InvalidParameterException",
    "stack": [
        "InvalidParameterException: Invalid SourceUser: Cognito users with a username/password may not be passed in as a SourceUser, only as a DestinationUser",
        "    at deserializeAws_json1_1InvalidParameterExceptionResponse (/var/runtime/node_modules/@aws-sdk/client-cognito-identity-provider/dist-cjs/protocols/Aws_json1_1.js:6647:23)",
        "    at deserializeAws_json1_1AdminLinkProviderForUserCommandError (/var/runtime/node_modules/@aws-sdk/client-cognito-identity-provider/dist-cjs/protocols/Aws_json1_1.js:1758:25)",
        "    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)",
        "    at async /var/runtime/node_modules/@aws-sdk/middleware-serde/dist-cjs/deserializerMiddleware.js:7:24",
        "    at async /var/runtime/node_modules/@aws-sdk/middleware-signing/dist-cjs/middleware.js:13:20",
        "    at async StandardRetryStrategy.retry (/var/runtime/node_modules/@aws-sdk/middleware-retry/dist-cjs/StandardRetryStrategy.js:51:46)",
        "    at async /var/runtime/node_modules/@aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.js:6:22",
        "    at async e.handler (/var/task/index.js:2:821614)"
    ]
}

Example Payload:

{
  UserPoolId: 'us-east-1_1EZAgSDJ1',
  SourceUser: {
    ProviderAttributeName: 'Cognito_Subject',
    ProviderAttributeValue: '109049715757962865037',
    ProviderName: 'Google'
  },
  DestinationUser: {
    ProviderAttributeValue: '9fef2c71-9941-4297-9a7c-0d156ff56081',
    ProviderName: 'Cognito'
  }
}
RanVaknin commented 11 months ago

Hi @ignaciolarranaga ,

This is an interesting issue, that I think stems from an edge case in service side error handling.

Running your code once resulted in a successful link. After that, running the same bit of code again results in this wrong error.

$ node sample.mjs
{
  '$metadata': {
    httpStatusCode: 200,
    requestId: 'REDACTED',
    extendedRequestId: undefined,
    cfId: undefined,
    attempts: 1,
    totalRetryDelay: 0
  }
$ node sample.mjs
InvalidParameterException: Invalid SourceUser: Cognito users with a username/password may not be passed in as a SourceUser, only as a DestinationUser
    at de_InvalidParameterExceptionRes (/Users/rvaknin/test_folder/5281/node_modules/@aws-sdk/client-cognito-identity-provider/dist-cjs/protocols/Aws_json1_1.js:6356:23)
    at de_AdminLinkProviderForUserCommandError (/Users/rvaknin/test_folder/5281/node_modules/@aws-sdk/client-cognito-identity-provider/dist-cjs/protocols/Aws_json1_1.js:1456:25)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async /Users/rvaknin/test_folder/5281/node_modules/@smithy/middleware-serde/dist-cjs/deserializerMiddleware.js:7:24
    at async /Users/rvaknin/test_folder/5281/node_modules/@aws-sdk/middleware-signing/dist-cjs/awsAuthMiddleware.js:14:20
    at async /Users/rvaknin/test_folder/5281/node_modules/@smithy/middleware-retry/dist-cjs/retryMiddleware.js:27:46
    at async /Users/rvaknin/test_folder/5281/node_modules/@aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.js:7:26
    at async file:///Users/rvaknin/test_folder/5281/sample.mjs:29:16 {
  '$fault': 'client',
  '$metadata': {
    httpStatusCode: 400,
    requestId: 'REDACTED',
    extendedRequestId: undefined,
    cfId: undefined,
    attempts: 1,
    totalRetryDelay: 0
  },
  __type: 'InvalidParameterException'
}

In an ideal world the service would return something like "4xx - the user is already linked", but this is probably an oversight in error handling.

This means that the your code is being called twice with the same input.

Let me know if you need anything else. Thanks, Ran~

ignaciolarranaga commented 11 months ago

Thanks @RanVaknin , I didn't noticed the code can be called twice. Will research to find out more.

github-actions[bot] commented 11 months ago

This issue has not received a response in 1 week. If you still think there is a problem, please leave a comment to avoid the issue from automatically closing.

github-actions[bot] commented 10 months ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.