Skip to content
Esc
navigateopen⌘Jpreview
Dashboard
On this page

Hooks and overrides

Add custom logic in the email verification 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 emailverification recipe to your needs.

Explore the references pages for a more in depth guide on hooks and overrides.

Backend override

To perform any task post email verification like analytics, sending a user a welcome email or notifying an internal dashboard, you need to override the verifyEmailPOST API.

import SuperTokens from "supertokens-node";
import EmailVerification from "supertokens-node/recipe/emailverification";
import Session from "supertokens-node/recipe/session";

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  recipeList: [
    EmailVerification.init({
      mode: "REQUIRED",
      override: {
        apis: (originalImplementation) => {
          return {
            ...originalImplementation,
            verifyEmailPOST: async function (input) {
              if (originalImplementation.verifyEmailPOST === undefined) {
                throw Error("Should never come here");
              }

              // First we call the original implementation
              let response = await originalImplementation.verifyEmailPOST(input);

              // Then we check if it was successfully completed
              if (response.status === "OK") {
                let { recipeUserId, email } = response.user;
                // TODO: post email verification logic
              }
              return response;
            },
          };
        },
      },
    }),
    Session.init(),
  ],
});
import (
	"fmt"

	"github.com/supertokens/supertokens-golang/recipe/emailverification"
	"github.com/supertokens/supertokens-golang/recipe/emailverification/evmodels"
	"github.com/supertokens/supertokens-golang/recipe/session/sessmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			emailverification.Init(evmodels.TypeInput{
				Mode: evmodels.ModeRequired,
				Override: &evmodels.OverrideStruct{
					APIs: func(originalImplementation evmodels.APIInterface) evmodels.APIInterface {
						ogVerifyEmailPOST := *originalImplementation.VerifyEmailPOST
						(*originalImplementation.VerifyEmailPOST) = func(token string, sessionContainer sessmodels.SessionContainer, tenantId string, options evmodels.APIOptions, userContext supertokens.UserContext) (evmodels.VerifyEmailPOSTResponse, error) {
							resp, err := ogVerifyEmailPOST(token, sessionContainer, tenantId, options, userContext)
							if err != nil {
								return evmodels.VerifyEmailPOSTResponse{}, err
							}

							if resp.OK != nil {
								id := resp.OK.User.ID
								email := resp.OK.User.Email
								fmt.Println(id)
								fmt.Println(email)
								// TODO: post email verification logic
							}

							return resp, nil
						}
						return originalImplementation
					},
				},
			}),
		},
	})
}
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import emailverification
from supertokens_python.recipe.emailverification.interfaces import APIInterface, APIOptions, EmailVerifyPostOkResult
from typing import Dict, Any, Optional
from supertokens_python.recipe.session.interfaces import SessionContainer

def override_email_verification_apis(original_implementation_email_verification: APIInterface):
    original_email_verify_post = original_implementation_email_verification.email_verify_post

    async def email_verify_post(token: str,
                                session: Optional[SessionContainer],
                                tenant_id: str,
                                api_options: APIOptions,
                                user_context: Dict[str, Any],):

        response = await original_email_verify_post(token, session, tenant_id, api_options, user_context)

        # Then we check if it was successfully completed
        if isinstance(response, EmailVerifyPostOkResult):
            _ = response.user
            # TODO: post email verification logic
        return response

    original_implementation_email_verification.email_verify_post = email_verify_post
    return original_implementation_email_verification

init(
    app_info=InputAppInfo(
        api_domain="...", app_name="...", website_domain="..."),
    framework='...',  
    recipe_list=[
        emailverification.init(
            mode="REQUIRED",
            override=emailverification.InputOverrideConfig(
                apis=override_email_verification_apis
            )
        )
    ]
)

API reference

API schema and response details