Doing operations post a password reset
To perform any task like analytics, sending a user an email, notifying an internal dashboard, post resetting a password, you'll need to override the passwordResetPOST
API.
- NodeJS
- GoLang
- Python
- Other Frameworks
Important
For other backend frameworks, you can follow our guide on how to spin up a separate server configured with the SuperTokens backend SDK to authenticate requests and issue session tokens.
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()
]
});
import (
"github.com/supertokens/supertokens-golang/recipe/emailpassword"
"github.com/supertokens/supertokens-golang/recipe/emailpassword/epmodels"
"github.com/supertokens/supertokens-golang/supertokens"
)
func main() {
supertokens.Init(supertokens.TypeInput{
RecipeList: []supertokens.Recipe{
emailpassword.Init(&epmodels.TypeInput{
Override: &epmodels.OverrideStruct{
APIs: func(originalImplementation epmodels.APIInterface) epmodels.APIInterface {
// first we copy the original implementation
originalPasswordResetPOST := *originalImplementation.PasswordResetPOST
// override the password reset API
(*originalImplementation.PasswordResetPOST) = func(formFields []epmodels.TypeFormField, token string, tenantId string, options epmodels.APIOptions, userContext supertokens.UserContext) (epmodels.ResetPasswordPOSTResponse, error) {
// First we call the original implementation
resp, err := originalPasswordResetPOST(formFields, token, tenantId, options, userContext)
if err != nil {
return epmodels.ResetPasswordPOSTResponse{}, err
}
// Then we check if it was successfully completed
if resp.OK != nil {
// TODO: post password reset logic
}
return resp, nil
}
return originalImplementation
},
},
}),
},
})
}
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import emailpassword
from supertokens_python.recipe.emailpassword.interfaces import (
APIInterface,
PasswordResetPostOkResult,
)
from supertokens_python.recipe.emailpassword.interfaces import APIOptions
from supertokens_python.recipe.emailpassword.types import FormField
from typing import Dict, List, Any
def override_apis(original_implementation: APIInterface):
original_password_reset_post = original_implementation.password_reset_post
async def password_reset_post(
form_fields: List[FormField],
token: str,
tenant_id: str,
api_options: APIOptions,
user_context: Dict[str, Any],
):
response = await original_password_reset_post(
form_fields, token, tenant_id, api_options, user_context
)
# Then we check if it was successfully completed
if isinstance(response, PasswordResetPostOkResult):
pass # TODO: post password reset logic
return response
original_implementation.password_reset_post = password_reset_post
return original_implementation
init(
app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
framework="...",
recipe_list=[
emailpassword.init(
override=emailpassword.InputOverrideConfig(apis=override_apis)
)
],
)