Hari Honor
Hari Honor

Reputation: 8924

AWS user-migration Lambda won't create a user in Cognito

For some reason I can no longer get my user-migration to create a user in Cognito. I've paired it back to the most basic:

    def migration_handler(event, context):

        # Create the user in Cognito
        event["response"]["userAttributes"] = {
            "username": event["userName"],
            "email": event["userName"],
            # "email_verified": True,
            # "custom:nutrinoId": 'nutrino_id',
            # 'custom:finished-signup': 'true'
        }
        event["response"]["finalUserStatus"] = "CONFIRMED"
        event["response"]["messageAction"] = "SUPPRESS"

        return event

I'm using Serverless (v2.72.2) to publish, which all seems fine as the migration handler fires. Here are the Cloudwatch logs from an InitiateAuth attempt:

timestamp message
1643820943789 START RequestId: 7381165c-88b7-4a57-98b2-28abc8a53abe Version: $LATEST
1643820943789 [INFO] 2022-02-02T16:55:43.789Z Found credentials in environment variables.
1643820943884 [INFO] 2022-02-02T16:55:43.884Z 7381165c-88b7-4a57-98b2-28abc8a53abe Migration Lambda. Event: {'version': '1', 'triggerSource': 'UserMigration_Authentication', 'region': 'us-west-2', 'userPoolId': 'us-west-2_xxx', 'userName': '[email protected]', 'callerContext': {'awsSdkVersion': 'aws-sdk-unknown-unknown', 'clientId': 'xxx'}, 'request': {'password': 'TestPassword', 'validationData': None, 'userAttributes': None}, 'response': {'userAttributes': None, 'forceAliasCreation': None, 'finalUserStatus': None, 'messageAction': None, 'desiredDeliveryMediums': None}}
1643820943884 [DEBUG] 2022-02-02T16:55:43.884Z 7381165c-88b7-4a57-98b2-28abc8a53abe Final Event: {'version': '1', 'triggerSource': 'UserMigration_Authentication', 'region': 'us-west-2', 'userPoolId': 'us-west-2_xxx', 'userName': '[email protected]', 'callerContext': {'awsSdkVersion': 'aws-sdk-unknown-unknown', 'clientId': 'xxx'}, 'request': {'password': 'TestPassword', 'validationData': None, 'userAttributes': None}, 'response': {'userAttributes': {'username': '[email protected]'}, 'forceAliasCreation': None, 'finalUserStatus': 'CONFIRMED', 'messageAction': 'SUPPRESS', 'desiredDeliveryMediums': None}}
1643820943885 END RequestId: 7381165c-88b7-4a57-98b2-28abc8a53abe
1643820943885 REPORT RequestId: 7381165c-88b7-4a57-98b2-28abc8a53abe Duration: 1.74 ms Billed Duration: 2 ms Memory Size: 1024 MB Max Memory Used: 65 MB Init Duration: 797.46 ms

As far as I can see it, the final event object returned in the lambda should create the user but I get a NotAuthorizedException: Incorrect username or password. exception from boto and the user isn't listed in my User Pool.

As you can see there are no error messages in the lambda logs.

Any ideas, or tips on further investigation?

Upvotes: 1

Views: 835

Answers (2)

Aaron Campos
Aaron Campos

Reputation: 1

Make sure that the target pool allow email format for username attribute. In my case when I created an user manually, it throws me this error:

Username cannot be of email format, since user pool is configured for email alias.

So I tried to cut the username that comes as email with a split function and it works for me:

const handler = async (event) => {
  if (event.triggerSource == "UserMigration_Authentication") {
    const user = await authenticateUser(event.userName, event.request.password);

    if (user) {
      const userAttributes = user.UserAttributes.reduce((acc, { Name, Value }) => {
                acc[Name] = Value;
                return acc;
            }, {});
      
      userAttributes['username'] = event.userName.split('@')[0]
      delete userAttributes.sub
      
      event.response.userAttributes = userAttributes
      event.response.finalUserStatus = "CONFIRMED";
      event.response.messageAction = "SUPPRESS";
    }
  } else if (event.triggerSource == "UserMigration_ForgotPassword") {
    // Look up the user in your existing user directory service
    const user = await lookupUser(event.userName);
    if (user) {
      
       const userAttributes = user.UserAttributes.reduce((acc, { Name, Value }) => {
                acc[Name] = Value;
                return acc;
            }, {});
            
       userAttributes['username'] = event.userName.split('@')[0]
       delete userAttributes.sub
       event.response.messageAction = "SUPPRESS";
    }
  }
  
  return event;
};

Upvotes: 0

Gael
Gael

Reputation: 1

In the standard attributes there's no username field. It should be name instead. https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html#user-pool-settings-custom-attributes.html

Upvotes: 0

Related Questions