aws-sdk-js icon indicating copy to clipboard operation
aws-sdk-js copied to clipboard

Migration Lambda gives invalid username and password for old user pool user

Open neerajhere opened this issue 3 years ago • 8 comments

**I have created a migration lambda using nodejs (https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-migrate-user.html#cognito-user-pools-lambda-trigger-syntax-user-migration) It first time returns below exception for old users though lambda work perfectly fine and create user in new user pool and at the end it returns context.succeed(event); return event; but still Hosted UI shows Incorrect username or password error and amplify return below error NotAuthorizedException{message=Failed since user is not authorized., cause=com.amazonaws.services.cognitoidentityprovider.model.NotAuthorizedException: Incorrect username or password. (Service: AmazonCognitoIdentityProvider; Status Code: 400; Error Code: NotAuthorizedException; Request ID: b36702d6-3b9c-4615-9858-9c5f235517a9), recoverySuggestion=Check whether the given values are correct and the user is authorized to perform the operation.}

Second time user is able to login without any error as the user is already created.**

neerajhere avatar Nov 27 '21 20:11 neerajhere

Hi @neerajhere this example shows you how you can migrate a new user. If you still experience the problem with the latest version of SDK, can you provide more information about what we can support you? You can use this template, and provide a reproducible code that we can use to investigate more?

vudh1 avatar Dec 09 '21 22:12 vudh1

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] avatar Dec 15 '21 00:12 github-actions[bot]

Hi @vudh1 , Thanks for the reply. I used that example but I am still facing the issue. Here is the code which I used var AWS = require('aws-sdk'); var OLD_CLIENT_ID = 'someID'; var OLD_CLIENT_ID2 = 'someID'; var OLD_USER_POOL_ID = 'someID'; var NEW_CLIENT_ID = 'someID'; var NEW_USER_POOL_ID = 'someID'; exports.handler = async (event, context, callback) => {

var user;
if ( event.triggerSource == "UserMigration_Authentication" ) {

    console.log(event);
    var userInNewPool = await lookupUserInNewUserPool(event.userName);
    console.log("user in  new user pool");
    console.log(userInNewPool);
    if(userInNewPool === null || userInNewPool === '' || userInNewPool === undefined)
    {
        var userInOldPool = await lookupUser(event.userName);
        console.log("user in  old user pool");
        console.log(userInOldPool);
        if(userInOldPool != null || userInOldPool != '' || userInOldPool != undefined)
        {
            // authenticate the user with your existing user directory service
            
            user = await authenticateUser(event.userName, event.request.password);
            if ( user ) {
                event.response.userAttributes = user.UserAttributes;
                event.response.finalUserStatus = "CONFIRMED";
                event.response.messageAction = "SUPPRESS";
                
                console.log("------------------------create user in new pool --------")
                await createUser(user, event.request.password);
                console.log("Old User");
                //callback("Old User");
                //context.fail("Old User");
                context.succeed(event);
                return event;
            }
            else {
                // Return error to Amazon Cognito
                callback("Bad password");
            }
        }
    }
    else
    {
        user = await authenticateUserWithNewUserPool(event.userName, event.request.password);
        console.log('user is authenticated.');
        console.log(user);
        if ( user ) {
            event.response.userAttributes = user.UserAttributes;
            event.response.finalUserStatus = "CONFIRMED";
            event.response.messageAction = "SUPPRESS";
            
            context.succeed(event);
        }
        else {
            // Return error to Amazon Cognito
            callback("Bad password");
        }
    }
}
else if ( event.triggerSource == "UserMigration_ForgotPassword" ) {

    // Lookup the user in your existing user directory service
    user = await lookupUserInNewUserPool(event.userName);
    if ( user ) {
        event.response.userAttributes = user.userAttributes;
        event.response.messageAction = "SUPPRESS";
        context.succeed(event);
    }
    else {
        // Return error to Amazon Cognito
        callback("Bad password");
    }
}
else { 
    // Return error to Amazon Cognito
    callback("Bad triggerSource " + event.triggerSource);
}

};

async function authenticateUser(username, password) {

 var cognitoIdentityServiceProvider = new AWS.CognitoIdentityServiceProvider();
 
 // Validate username/password
 var resAuth
 try {
     resAuth = await cognitoIdentityServiceProvider.adminInitiateAuth({
    AuthFlow: 'ADMIN_USER_PASSWORD_AUTH',
    AuthParameters: {
      PASSWORD: password,
      USERNAME: username,
    },
    ClientId: OLD_CLIENT_ID,
    UserPoolId: OLD_USER_POOL_ID,
  }).promise();
 } catch (e) {console.error(e);}
  
  
  if (resAuth.code && resAuth.message) {
    try {
         resAuth = await cognitoIdentityServiceProvider.adminInitiateAuth({
        AuthFlow: 'ADMIN_USER_PASSWORD_AUTH',
        AuthParameters: {
          PASSWORD: password,
          USERNAME: username,
        },
        ClientId: OLD_CLIENT_ID2,
        UserPoolId: OLD_USER_POOL_ID,
      }).promise();
     } catch (e) {console.error(e);};
  }
  
if (resAuth.code && resAuth.message) {
    return undefined;
}
// Load user data
var resGet;
try {
    
   resGet =  await cognitoIdentityServiceProvider.adminGetUser({
    UserPoolId: OLD_USER_POOL_ID,
    Username: username,
  }).promise();
} catch (e) {console.error(e);}

  
  if (resGet.code && resGet.message) {
    return undefined;
  } 
  return resGet;

}

async function authenticateUserWithNewUserPool(username, password) {

 var cognitoIdentityServiceProvider = new AWS.CognitoIdentityServiceProvider();
 
 // Validate username/password
 try {
     var resAuth = await cognitoIdentityServiceProvider.adminInitiateAuth({
    AuthFlow: 'ADMIN_USER_PASSWORD_AUTH',
    AuthParameters: {
      PASSWORD: password,
      USERNAME: username,
    },
    ClientId: NEW_CLIENT_ID,
    UserPoolId: NEW_USER_POOL_ID,
  }).promise();
 } catch (e) {console.error(e);}
  
  
  if (resAuth.code && resAuth.message) {
    return undefined;
  }

// Load user data
try {
    var resGet;
   resGet =  await cognitoIdentityServiceProvider.adminGetUser({
    UserPoolId: NEW_USER_POOL_ID,
    Username: username,
  }).promise();
} catch (e) {console.error(e);}

  
  if (resGet.code && resGet.message) {
    return undefined;
  } 
  return resGet;

}

async function lookupUser(username) { var cognitoIdentityServiceProvider = new AWS.CognitoIdentityServiceProvider(); // Load user data try { var resGet = await cognitoIdentityServiceProvider.adminGetUser({ UserPoolId: OLD_USER_POOL_ID, Username: username, }).promise(); } catch (e) {console.error(e);}

  if (resGet.code && resGet.message) {
    return undefined;
  } 
  return resGet;

}

async function lookupUserInNewUserPool(username) { var cognitoIdentityServiceProvider = new AWS.CognitoIdentityServiceProvider(); // Load user data var resGet; try { resGet = await cognitoIdentityServiceProvider.adminGetUser({ UserPoolId: NEW_USER_POOL_ID, Username: username, }).promise(); } catch (e) {console.error(e);}

  return resGet;

}

async function createUser(user, password) { var cognitoIdentityServiceProvider = new AWS.CognitoIdentityServiceProvider(); console.log("creating new user with attributes"); console.log(user.UserAttributes); var newUser; try { newUser = await cognitoIdentityServiceProvider.adminCreateUser({ UserPoolId : NEW_USER_POOL_ID, Username : user.Username.split('@')[0], UserAttributes : user.UserAttributes.filter(a => a.Name == 'email_verified' || a.Name == 'email'), MessageAction : "SUPPRESS" }).promise(); console.log(newUser); } catch (e) {console.error(e)};

try
{
    await cognitoIdentityServiceProvider.adminSetUserPassword({
        UserPoolId : NEW_USER_POOL_ID,
        Username : user.Username.split('@')[0],
        Password : password,
        Permanent : true
    }).promise();
} catch(e) {console.error(e)}

//add roles
var params = {

    GroupName: 'stylist', //your confirmed user gets added to this group
    UserPoolId: NEW_USER_POOL_ID,  
    Username: user.Username.split('@')[0]
};
//console.log(params);
try {
await cognitoIdentityServiceProvider.adminAddUserToGroup(params).promise();
} catch (error) {
    console.error(error);
}

var userRoleparams = {

    GroupName: 'user', //your confirmed user gets added to this group
    UserPoolId: NEW_USER_POOL_ID,  
    Username: user.Username.split('@')[0]
};
//console.log(params);
try {
await cognitoIdentityServiceProvider.adminAddUserToGroup(userRoleparams).promise();
} catch (error) {
    console.error(error);
}

}

neerajhere avatar Dec 16 '21 16:12 neerajhere

Hi @vudh1 , you got any solution for this?

neerajhere avatar Dec 23 '21 15:12 neerajhere

Hi guys, did anyone find tge solutiom to this issue? I am fighting with the same one unfortunately.

boboci9 avatar Mar 21 '22 20:03 boboci9

Unfortunately, I met the same issue... no idea tho

JandenMa avatar Apr 01 '22 19:04 JandenMa

Same result.... any solution for this issue?

alanko0202 avatar Sep 05 '22 10:09 alanko0202

I am facing the same issue, I configured the Cognito trigger for User Migration to call a lambda trigger with the same example @vudh1 shared, but still, Cognito is not sending any invocations to the lambda function.

Abdelrhman-Yasser avatar Oct 16 '22 12:10 Abdelrhman-Yasser