Skip to content

Instantly share code, notes, and snippets.

@morgler
Created April 26, 2019 06:27
Show Gist options
  • Save morgler/651e5dc48bcfae5680181e1b7bb8d04b to your computer and use it in GitHub Desktop.
Save morgler/651e5dc48bcfae5680181e1b7bb8d04b to your computer and use it in GitHub Desktop.
AWS Cognito user migration lambda function
'use strict';
const https = require('https');
const attributes = (response) => {
return {
"email": response.email,
"email_verified": "true",
"name": response.name,
"custom:rails_app_id": response.id
};
};
const checkUser = (server, data, callback) => {
let postData = JSON.stringify( data );
let options = {
hostname: server,
path: "/aws/auth",
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': postData.length
}
};
console.log('checkUser', options, data)
let req = https.request(options, (res) => {
console.log("result", res)
let data = "";
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
if ( data ){
let response = JSON.parse( data );
//console.log( 'response:', JSON.stringify(response, null, 2) );
callback( null, response);
} else {
callback( "Authentication error");
}
});
});
req.on('error', (e) => {
callback( e );
});
req.write( postData );
req.end();
}
exports.handler = (event, context, callback) => {
console.log('Migrating user:', event.userName);
let rails_server_url = process.env.rails_server_url;
checkUser( rails_server_url, {
email: event.userName,
password: event.request && event.request.password,
access_token: process.env.rails_server_access_token
}, (err, response ) => {
if ( err ){
return context.fail("Connection error", err);
}
if ( event.triggerSource == "UserMigration_Authentication" ) {
// authenticate the user with your existing user directory service
if ( response.success ) {
event.response.userAttributes = attributes( response ) ;
event.response.finalUserStatus = "CONFIRMED";
event.response.messageAction = "SUPPRESS";
console.log(event)
console.log('Migrating user:', event.userName);
callback(null, event)
} else if ( response.user_exists ) {
// Return error to Amazon Cognito
callback("Bad password");
} else {
callback("Bad user");
}
} else if ( event.triggerSource == "UserMigration_ForgotPassword" ) {
if ( response.user_exists ) {
event.response.userAttributes = attributes( response ) ;
event.response.messageAction = "SUPPRESS";
console.log('Migrating user with password reset:', event.userName);
callback(null, event);
} else {
callback("Bad user");
}
} else {
// Return error to Amazon Cognito
callback("Bad triggerSource " + event.triggerSource);
}
});
};
@ankitaramesh
Copy link

H.Could you tell the user migration is happening from where into congito user pool?

@morgler
Copy link
Author

morgler commented Sep 3, 2020

The user migration is happening from a custom system. In this example it is a Rails application, but it could be any system. The only thing needed is an API endpoint to verify user credentials.

@ankitaramesh
Copy link

Just out of curiosity, Can this migration work if my user data is in RDS mysql db and I want migrate them to cognito user pool?

@morgler
Copy link
Author

morgler commented Sep 3, 2020

Theoretically it should work. You would simply substitute the checkUser function with a call to RDS and a check of the credentials you retrieved. But maybe, since RDS is also AWS, there is an even simpler way to migrate – I don't know.

@ankitaramesh
Copy link

Alright.I do have another silly question, which is how does it know which pool to migrate it to?as I see nothing defined in the code.
Thank in advance, for answering my questions patiently.

@morgler
Copy link
Author

morgler commented Sep 6, 2020

You set the lambda function with this code as being triggered in your Cognito user pool: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-migrate-user.html . Cognito will call that lambda whenever it needs to migrate a user and then uses the return value of your function to create the user in Cognito.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment