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 setupStart by following the backend quick setup for the EmailPassword recipe.
#
Change validation logicChange 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 logicBy 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
.