Hooks and overrides
Add custom logic in the authentication flow by overriding the SuperTokens APIs.
SuperTokens exposes a set of constructs that allow you to trigger different actions during the authentication lifecycle or to even fully customize the logic based on your use case.
The following sections describe how you can modify adjust the emailpassword
recipe to your needs.
Explore the references pages for a more in depth guide on hooks and overrides.
Sign in
Frontend hook
What type of UI are you using?
This method gets fired, with the SUCCESS
action, immediately after a successful sign in or sign up.
Follow the code snippet to determine if the user is signing up or signing in.
With this method you can fire events immediately after a successful sign in. You can use it to send analytics events.
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({
onHandleEvent: async (context) => {
if (context.action === "SUCCESS") {
if (context.isNewRecipeUser && context.user.loginMethods.length === 1) {
// TODO: Sign up
} else {
// TODO: Sign in
}
}
}
}),
Session.init()
]
});
Backend override
Overriding the signIn
function allows you to introduce your own logic for the sign in process.
Use it to persist different types of data or trigger actions.
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({
override: {
functions: (originalImplementation) => {
return {
...originalImplementation,
signIn: async function (input) {
// First we call the original implementation of signIn.
let response = await originalImplementation.signIn(input);
// Post sign up response, we check if it was successful
if (response.status === "OK") {
/**
*
* response.user contains the following info:
* - emails
* - id
* - timeJoined
* - tenantIds
* - phone numbers
* - third party login info
* - all the login methods associated with this user.
* - information about if the user's email is verified or not.
*
*/
// TODO: post sign in logic
}
return response;
}
}
}
}
}),
Session.init({ /* ... */ })
]
});
Sign up
Frontend hook
This method gets fired, with the SUCCESS
action, immediately after a successful sign in or sign up.
Follow the code snippet to determine if the user is signing up.
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({
onHandleEvent: async (context) => {
if (context.action === "SUCCESS") {
if (context.isNewRecipeUser && context.user.loginMethods.length === 1) {
// TODO: Sign up
} else {
// TODO: Sign in
}
}
}
}),
Session.init()
]
});
Backend override
Overriding the signUp
function allows you to introduce your own logic for the sign in process.
Use it to persist different types of data, synchronize users between SuperTokens and your systems or to trigger other types of actions.
import SuperTokens from "supertokens-node";
import EmailPassword from "supertokens-node/recipe/emailpassword";
import Session from "supertokens-node/recipe/session";
// backend
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
supertokens: {
connectionURI: "...",
},
recipeList: [
EmailPassword.init({
override: {
functions: (originalImplementation) => {
return {
...originalImplementation,
signUp: async function (input) {
// First we call the original implementation of signUp.
let response = await originalImplementation.signUp(input);
// Post sign up response, we check if it was successful
if (response.status === "OK" && response.user.loginMethods.length === 1 && input.session === undefined) {
/**
*
* response.user contains the following info:
* - emails
* - id
* - timeJoined
* - tenantIds
* - phone numbers
* - third party login info
* - all the login methods associated with this user.
* - information about if the user's email is verified or not.
*
*/
// TODO: post sign up logic
}
return response;
}
}
}
}
}),
Session.init({ /* ... */ })
]
});
Password reset
Frontend hook
This method gets fired during the password reset flow with either the PASSWORD_RESET_SUCCESSFUL
or RESET_PASSWORD_EMAIL_SENT
action.
Use it to fire analytics events or to add any additional logic.
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({
onHandleEvent: async (context) => {
if (context.action === "PASSWORD_RESET_SUCCESSFUL") {
// Add you custom logic here
} else if (context.action === "RESET_PASSWORD_EMAIL_SENT") {
// Add you custom logic here
}
}
}),
Session.init()
]
});
Backend override
Overriding the passwordResetPOST
function allows you to introduce your own logic for the password reset process.
Use it to introduce your own logic for the flow.
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: "..."
},
recipeList: [
EmailPassword.init({
override: {
apis: (originalImplementation) => {
return {
...originalImplementation,
passwordResetPOST: async function(input) {
if (originalImplementation.passwordResetPOST === undefined) {
throw Error("Should never come here");
}
// First we call the original implementation
let response = await originalImplementation.passwordResetPOST(input);
// Then we check if it was successfully completed
if (response.status === "OK") {
// TODO: post password reset logic
}
return response;
}
};
},
},
}),
Session.init()
]
});