Adding / Modifying field validators
What type of UI are you using?
Step 1. Front End
Now that you have added new fields to your signup form, let's see how you can add validators to make sure that your users provide the right information.
You can add a validate
method to any formFields
.
Building up on our previous example, let's add an age verification to our form:
import SuperTokens from "supertokens-auth-react";
import EmailPassword from "supertokens-auth-react/recipe/emailpassword";
import Session from "supertokens-auth-react/recipe/session";
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
EmailPassword.init({
signInAndUpFeature: {
signUpForm: {
formFields: [{
id: "name",
label: "Full name",
placeholder: "First name and last name"
}, {
id: "age",
label: "Your age",
placeholder: "How old are you?",
optional: true,
/* Validation method to make sure that age is above 18 */
validate: async (value) => {
if (parseInt(value) > 18) {
return undefined; // means that there is no error
}
return "You must be over 18 to register";
}
}, {
id: "country",
label: "Your country",
placeholder: "Where do you live?",
optional: true
}]
}
}
}),
Session.init()
]
});
Here is what happens if someone tries to register with an age of 17:
Front-end validation is great for user experience but you should always make sure that you are also applying these validations on the backend.
Step 2. Back End
In your backend's SuperTokens init method, let's replicate the validate
functions from above:
import SuperTokens from "supertokens-node";
import EmailPassword from "supertokens-node/recipe/emailpassword";
import Session from "supertokens-node/recipe/session";
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
supertokens: {
connectionURI: "...",
},
recipeList: [
EmailPassword.init({
signUpFeature: {
formFields: [{
id: "name"
}, {
id: "age",
/* Validation method to make sure that age >= 18 */
validate: async (value, tenantId) => {
if (parseInt(value) >= 18) {
return undefined; // means that there is no error
}
return "You must be over 18 to register";
}
}, {
id: "country",
optional: true
}]
}
}),
Session.init({
})
]
});
Notice the tenantId
argument passed into the validate
function. Using that, you can define custom logic per tenant. For example, you can define different password policies for different tenants.
Changing the default email and password validators
By default, SuperTokens adds an email and a password validator to the sign-up form.
- The default email validator makes sure that the provided email is in the correct email format.
- The default password validator makes sure that the provided password:
- has a minimum of 8 characters.
- contains at least one lowercase character
- contains at least one number
- The email validator that you define for Sign up is also applied automatically to Sign In.
- The password validator that you define for Sign up is also applied automatically to reset password forms.
Step 1. Front End
import SuperTokens from "supertokens-auth-react";
import EmailPassword from "supertokens-auth-react/recipe/emailpassword";
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
EmailPassword.init({
signInAndUpFeature: {
signUpForm: {
formFields: [{
id: "email",
label: "...",
validate: async (value) => {
// Your own validation returning a string or undefined if no errors.
return "...";
}
}, {
id: "password",
label: "...",
validate: async (value) => {
// Your own validation returning a string or undefined if no errors.
return "...";
}
}]
}
}
})
]
});
Step 2. Back End
import SuperTokens from "supertokens-node";
import EmailPassword from "supertokens-node/recipe/emailpassword";
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
supertokens: {
connectionURI: "...",
},
recipeList: [
EmailPassword.init({
signUpFeature: {
formFields: [{
id: "email",
validate: async (value, tenantId) => {
// Your own validation returning a string or undefined if no errors.
return "...";
}
}, {
id: "password",
validate: async (value, tenantId) => {
// Your own validation returning a string or undefined if no errors.
return "...";
}
}]
}
}),
]
});