AWS Cognito - Custom email verification template

Cover Image for AWS Cognito - Custom email verification template

Let's say you want to use the new awesome user management service provided by AWS. All nice and dandy, until you find that you can't customize the email validation behaviour that much. I mean, yes, you can send HTML and you can add a custom domain, but that's pretty much it. For example, I wanted to be able to redirect the user to my website after they validated their email and save the validatedAt timestamp in RDS.

I ended up using Cognito's CustomMessage_SignUp event for altering the template and pointing the link to an API Gateway that did the actual validation, validatedAt save and the redirect.

In more detail, here's the event handling. For the sake of simplicity this is not a valid HTML :)

if (event.triggerSource === 'CustomMessage_SignUp') { // Ensure that your message contains event.request.codeParameter. This is the placeholder for code that will be sent const { codeParameter, linkParameter } = event.request; const { userName } = event; const { clientId } = event.callerContext; const { email } = event.request.userAttributes; const url = `https://yourdomain.com/userEmailVerification/?code=${codeParameter}&username=${userName}&clientId=${clientId}&email=${email}`; event.response.emailSubject = 'Please verify your email addresss'; event.response.emailMessage = ` <!DOCTYPE html> <html> <a href="${url}" target="_blank" style="display: inline-block; color: #ffffff; background-color: #3498db; border: solid 1px #3498db; border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 14px; font-weight: bold; margin: 0; padding: 12px 25px; text-transform: capitalize; border-color: #3498db;" >Verify</a > <div style="display: none">${linkParameter}</div> </html> `; return event; }

The most important part is <div style="display: none">${linkParameter}</div>. Basically Cognito gives you this token that you need to add in your HTML and it will replace it with the validation URL that points to their hosted UI. Since that's what I was aiming to avoid, I tried removing it all together but surprise, you can't. You need to add it, even if it's hidden, but it needs to be there. Another thing to keep in mind in the limitation for the emailMessage, you need to keep the text under 20000 characters, otherwise the email will not be sent.

The link https://yourdomain.com/userEmailVerification/ points to the above mentioned API Gateway and it's Lambda function looks like this:

import { CognitoIdentityServiceProvider } from 'aws-sdk'; import { UserMapper } from '../database'; export const handler = async (event, context, callback) => { const { clientId, code, email, username } = event.queryStringParameters; const cognitoISP = new CognitoIdentityServiceProvider(); const params = { ClientId: clientId, ConfirmationCode: code, Username: username, }; try { await cognitoISP.confirmSignUp(params).promise(); await UserMapper.verifyUser({ email: username }); return callback(null, { statusCode: 302, headers: { Location: `https://mywebsite.com/login?verified=true&email=${email}`, }, }); } catch (e) { // woops, error, redirect but without verified=true return callback(null, { statusCode: 302, headers: { Location: `https://www.mywebsite.com/login?email=${email}`, }, }); } };


More Stories

Cover Image for LottieFiles downloader

LottieFiles downloader

Today I needed a cool animation for a small website project, and, as usual, I headed over to LottieFiles to grab one. It’s not something I do often, maybe once every few months. But to my surprise, I ...

Mihai Blaga's profile picture
Mihai Blaga
Cover Image for ESPHome ESP32C3 Bootloop

ESPHome ESP32C3 Bootloop

If you’ve recently tried to get an ESP32-C3 board running with ESPHome, specifically using the esp-idf framework, you might have encountered a frustrating boot loop. The loop typically produces logs t...

Mihai Blaga's profile picture
Mihai Blaga