Skip to main content

1) EmailPassword customisation

This recipe will provide APIs for email & password login as well as reset password flow. By default, it will only accept emails as an input. We can customise this to accept phone numbers instead as well as send reset password links via SMS instead of emails.

Quick setup#

Start by following the backend quick setup for the EmailPassword recipe.

Change validation logic#

Change the email validator to check for phone number syntax instead. We use the libphonenumber-js library for it:

import parsePhoneNumber from "libphonenumber-js/max";
import EmailPassword from "supertokens-node/recipe/emailpassword";
import supertokens from "supertokens-node";

supertokens.init({
framework: "...",
appInfo: { /*...*/ },
recipeList: [
EmailPassword.init({
signUpFeature: {
formFields: [
{
id: "email",
validate: async (value) => {
if (typeof value !== "string") {
return "Phone number is invalid";
}

let parsedPhoneNumber = parsePhoneNumber(value);
if (parsedPhoneNumber === undefined || !parsedPhoneNumber.isValid()) {
return "Phone number is invalid";
}
return undefined;
},
},
],
},
})
]
})

The above will make sure that a phone number input is accepted only if it's syntactically a valid phone number.

Notice that the id of the form field is still email. This is not modifiable at the moment, however, this does not affect the end user experience.

Change reset password logic#

By default, the recipe will attempt to send an email with the reset password link. This will of course fail since we are accepting phone numbers.

To fix this, we will need to provide our own callback for sending an SMS with the reset password link:

import EmailPassword from "supertokens-node/recipe/emailpassword";
import supertokens from "supertokens-node";

supertokens.init({
framework: "...",
appInfo: { /*...*/ },
recipeList: [
EmailPassword.init({
emailDelivery: {
override: (originalImplemenation) => {
return {
...originalImplemenation,
sendEmail: async function (input) {
if (input.type === "PASSWORD_RESET") {
// TODO: send SMS to user.email (it is actually a phone number)
console.log("Send password reset link to: ", input.user.email);
console.log("Password reset link:", input.passwordResetLink);
} else {
return originalImplemenation.sendEmail(input);
}
}
}
}
}
})
]
})

In this callback, you can use a service like Twilio to send a SMS to the user. The phone number to send the SMS to is user.email.

Looking for older versions of the documentation?
Which UI do you use?
Custom UI
Pre built UI