I am trying to create the Redirect to URL after clicking email verification link (explained in this github issue). I am also following these Stackoverflow replies
I have a Cognito user pool with a single Lambda trigger: Custom message Lambda trigger, which looks like this:
exports.handler = (event, context, callback) => {
console.log("event")
console.log(event)
// Identify why was this function invoked
if(event.triggerSource === "CustomMessage_SignUp") {
console.log("editing email message...")
const { codeParameter } = event.request
const { userName, region } = event
const { clientId } = event.callerContext
const { email } = event.request.userAttributes
const url = 'https://my-api.execute-api.us-east-1.amazonaws.com/dev/redirect'
const link = `<a href="${url}?code=${codeParameter}&username=${userName}&clientId=${clientId}®ion=${region}&email=${email}" target="_blank">here</a>`
console.log(link)
event.response.emailSubject = "Your verification link"; // event.request.codeParameter
event.response.emailMessage = `Thank you for signing up. Click ${link} to verify your email.`;
} else {
console.log("trigger source was invalid")
}
// Return to Amazon Cognito
callback(null, event);
};
Then I made an API Gateway with a dev
stage, a redirect
resource and a GET method pointing to a confirm_user Lambda as explained in this Medium tutorial. The Lambda looks like this:
'use strict';
var AWS = require('aws-sdk');
AWS.config.setPromisesDependency(require('bluebird'));
var CognitoIdentityServiceProvider = new AWS.CognitoIdentityServiceProvider({ apiVersion: '2019-11-07', region: 'us-east-1'});
exports.handler = (req, context, callback) => {
console.log('req');
console.log(req);
const confirmationCode = req.code
const username = req.username
const clientId = req.clientId
const region = req.region
const email = req.email
let params = {
ClientId: clientId,
ConfirmationCode: confirmationCode,
Username: username
}
var confirmSignUp = CognitoIdentityServiceProvider.confirmSignUp(params).promise();
confirmSignUp.then(
(data) => {
let redirectUrl = process.env.POST_REGISTRATION_VERIFICATION_REDIRECT_URL;
const response = {
statusCode: 302,
headers: {
Location: redirectUrl,
}
};
return callback(null, response);
}
).catch(
(error) => {
callback(error.message)
}
)
}
In Cognito -> Messaging -> Verification message, I put verification type: code.
This is how my user pool sign-up experience looks like:
My expectation is that Cognito generates the custom message, the user gets it in the email. When they click on it, they get confirmed and redirected to my website.
What happens is that Cognito generates the custom message, then for some seconds nothing happens, then the API gets called, the confirm_user Lambda gets called, the user gets confirmed, and then the email arrives. When clicking the link the code is expired because it was already used.
I cannot figure out why the link is being called in the background, which makes the user get confirmed even before they get the email.
Any help is appreciated!