Overview
This article contains additional information regarding how to send Email Invitations for Application Signup.
Applies To
- Email Invitations
- Application Signup
- Change password email template
Solution
As mentioned in the docs, a user invitation is basically a change password link repurposed as an invitation. The user invitation email is derived from the “change password” template. With Auth0, there are two common approaches for implementing user invitations:
- Customize an email template and use it to send a change password email.
- Create a password change ticket.
Two main customizations should be achieved to differentiate an invite from a regular password reset flow. First, decide if it is desired to send a password change email or to create a password change ticket and share it with the user.
- If it is desired to create the password change ticket, the only customization needed is for the password reset UI using query parameters since the password change emails will not be used.
- If it was decided to use Auth0’s password change email as well, then customize both the change email template and the password reset UI.
To use Auth0’s password change emails to send email invitations to the users, do the following:
-
Create new users with the
user.email_verified
parameter set tofalse
. Use the Create a User endpoint. The most important part when creating the user is to add an app_metadata attribute, something likeuser.app_metadata.invitedToMyApp: true.
-
In the email template, use liquid syntax to change the wording both for the body of the email and the subject, depending on the flow, like this:
{% if user.app_metadata.invitedToMyApp == true %} // user invitation email text {% else %} // password change email text {% endif %}
-
After a user successfully resets their password and logs in for the first time, create a post-login Action to remove that app_metadata attribute so that the next time they reset their password, they receive the correct change password email instead of the invitation one. Check when it is a first login with event.stats.logins_count <= 1. This is an example:
exports.onExecutePostLogin = async (event, api) => { if (event.stats.logins_count === 1) { if (event.user.app_metadata?.invitedToMyApp) { api.user.setAppMetadata("invitedToMyApp", null); } } };
For customizing the password reset page UI, as mentioned in the docs, use query string parameters, like this type=invite
. The returned URL, both if a password change ticket was requested and if a password change email was sent, has a unique code value that allows the user to set their password, followed by a #
. Do not edit anything before the #
. The query parameter should go after that, like this: #type=invite
- If it was chosen to create the password change ticket, the URL to share with the user will be get. Just append the query parameter at the end.
- If it was chosen to use Auth0’s password change email, add the query parameter after the URL variable, which is the password change ticket:
<a href="{{ url }}type=invite">Click here to change your password</a>e
Now that the query parameter is in the link, it is possible to access it from the custom Page Template (this works for the New Universal Login experience only, and a Custom Domain needs to be used). For example, try adding this scrip right at the end of the template, after the body:
<script>
var href = window.location.href
var qsParams = href.substring(href.indexOf("#") + 1);
var parsedQsParams = new URLSearchParams(qsParams);
var isInvite = parsedQsParams.get('type') === "invite";
if (isInvite) {
const paragraphs = document.querySelectorAll('p');
const titles = document.querySelectorAll('h1');
const textToFind1 = 'Change Your Password';
const textToFind2 = 'Enter a new password below to change your password.';
const newText1 = 'Set Your Password';
const newText2 = 'Enter a password below to set your password.';
paragraphs.forEach(paragraph => {
if (paragraph.textContent.includes(textToFind2)) {
paragraph.textContent = paragraph.textContent.replace(textToFind2, newText2);
}
});
titles.forEach(title => {
if (title.textContent.includes(textToFind1)) {
title.textContent = title.textContent.replace(textToFind1, newText1);
}
});
}
</script>
It captures the type query parameter and checks if it’s “invite”. If it is, it changes the title and text of the Password Change page.
With that, it should be possible to successfully implement Email Invitations for Application Signup.