Post signin / signup callbacks
#
1) On the frontendThis method allows you to fire events immediately after a successful sign in. For example to send analytics events post sign in.
- ReactJS
- Angular
- Vue
- Plain JavaScript
- React Native
Note
You can use the
You can refer to this example app as a reference for using the
supertokens-web-js
SDK which exposes several helper functions that query the APIs exposed by the SuperTokens backend SDK.You can refer to this example app as a reference for using the
supertokens-web-js
SDK.Note
To use SuperTokens with React Native you need to use the
To add login functionality, you need to build your own UI and call the APIs exposed by the backend SDKs. You can find the API spec here
supertokens-react-native
SDK. The SDK provides session management features.To add login functionality, you need to build your own UI and call the APIs exposed by the backend SDKs. You can find the API spec here
What type of UI are you using?
Prebuilt UICustom UI
What type of UI are you using?
Prebuilt UICustom UI
import SuperTokens from "supertokens-auth-react";import ThirdPartyPasswordless from "supertokens-auth-react/recipe/thirdpartypasswordless";import Session from "supertokens-auth-react/recipe/session";
SuperTokens.init({ appInfo: { apiDomain: "...", appName: "...", websiteDomain: "..." }, recipeList: [ ThirdPartyPasswordless.init({ contactMethod: "EMAIL_OR_PHONE",
onHandleEvent: async (context) => { if (context.action === "SESSION_ALREADY_EXISTS") { // TODO: } else if (context.action === "PASSWORDLESS_RESTART_FLOW") { // TODO: } else if (context.action === "PASSWORDLESS_CODE_SENT") { // TODO: } else if (context.action === "SUCCESS") { if (context.isNewUser) { if ("phoneNumber" in context.user) { const { phoneNumber } = context.user; } else { const { email } = context.user; } // TODO: Sign up } else { // TODO: Sign in } } } }), Session.init() ]});
info
Please refer to this page to learn more about the onHandleEvent
hook.
#
2) On the backendFor this, you'll have to override the consumeCodePOST
API in the init
function call.
- NodeJS
- GoLang
- Python
import SuperTokens from "supertokens-node";import ThirdPartyPasswordless from "supertokens-node/recipe/thirdpartypasswordless";import Session from "supertokens-node/recipe/session";
SuperTokens.init({ appInfo: { apiDomain: "...", appName: "...", websiteDomain: "..." }, recipeList: [ ThirdPartyPasswordless.init({ contactMethod: "EMAIL", // This example will work with any contactMethod flowType: "USER_INPUT_CODE_AND_MAGIC_LINK", // This example will work with any flowType
override: { apis: (originalImplementation) => { return { ...originalImplementation, // override the thirdparty sign in / up API thirdPartySignInUpPOST: async function (input) { if (originalImplementation.thirdPartySignInUpPOST === undefined) { throw Error("Should never come here"); }
// TODO: Some pre sign in / up logic
let response = await originalImplementation.thirdPartySignInUpPOST(input);
if (response.status === "OK") { if (response.createdNewUser) { // TODO: some post sign up logic } else { // TODO: some post sign in logic } }
return response; },
consumeCodePOST: async (input) => { if (originalImplementation.consumeCodePOST === undefined) { throw Error("Should never come here"); }
// First we call the original implementation of consumeCodePOST. const response = await originalImplementation.consumeCodePOST(input);
// Post sign up response, we check if it was successful if (response.status === "OK") { if ("phoneNumber" in response.user) { const { id, phoneNumber } = response.user; } else { const { id, email } = response.user; }
if (response.createdNewUser) { // TODO: post sign up logic } else { // TODO: post sign in logic } } return response; } } } } }), Session.init({ /* ... */ }) ]});
import ( "fmt"
"github.com/supertokens/supertokens-golang/recipe/passwordless/plessmodels" "github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels" "github.com/supertokens/supertokens-golang/recipe/thirdpartypasswordless" "github.com/supertokens/supertokens-golang/recipe/thirdpartypasswordless/tplmodels" "github.com/supertokens/supertokens-golang/supertokens")
func main() {
supertokens.Init(supertokens.TypeInput{ RecipeList: []supertokens.Recipe{ thirdpartypasswordless.Init(tplmodels.TypeInput{ Override: &tplmodels.OverrideStruct{ APIs: func(originalImplementation tplmodels.APIInterface) tplmodels.APIInterface {
// create a copy of the original function originalConsumeCodePOST := *originalImplementation.ConsumeCodePOST originalThirdPartySignInUpPOST := *originalImplementation.ThirdPartySignInUpPOST
// override the thirdparty sign in / up API (*originalImplementation.ThirdPartySignInUpPOST) = func(provider tpmodels.TypeProvider, code string, authCodeResponse interface{}, redirectURI string, options tpmodels.APIOptions, userContext supertokens.UserContext) (tplmodels.ThirdPartySignInUpOutput, error) {
// TODO: some pre sign in / up logic
resp, err := originalThirdPartySignInUpPOST(provider, code, authCodeResponse, redirectURI, options, userContext) if err != nil { return tplmodels.ThirdPartySignInUpOutput{}, err }
if resp.OK != nil { if resp.OK.CreatedNewUser { // TODO: some post sign up logic } else { // TODO: some post sign in logic } }
return resp, err }
// override the passwordless sign in up API (*originalImplementation.ConsumeCodePOST) = func(userInput *plessmodels.UserInputCodeWithDeviceID, linkCode *string, preAuthSessionID string, options plessmodels.APIOptions, userContext supertokens.UserContext) (tplmodels.ConsumeCodePOSTResponse, error) {
// First we call the original implementation of ConsumeCodeUpPOST. response, err := originalConsumeCodePOST(userInput, linkCode, preAuthSessionID, options, userContext) if err != nil { return tplmodels.ConsumeCodePOSTResponse{}, err }
if response.OK != nil { // sign in was successful
// user object contains the ID and email or phone number user := response.OK.User fmt.Println(user)
if response.OK.CreatedNewUser { // TODO: Post sign up logic } else { // TODO: Post sign in logic }
} return response, nil }
return originalImplementation }, }, }), }, })}
from supertokens_python import init, InputAppInfofrom supertokens_python.recipe import thirdpartypasswordlessfrom supertokens_python.recipe.thirdpartypasswordless.interfaces import APIInterface, PasswordlessAPIOptions, ConsumeCodePostOkResult, ThirdPartyAPIOptions, ThirdPartySignInUpPostOkResultfrom typing import Union, Dict, Anyfrom supertokens_python.recipe.thirdparty.provider import Provider
def override_thirdpartypasswordless_apis(original_implementation: APIInterface): original_thirdparty_sign_in_up_post = original_implementation.thirdparty_sign_in_up_post original_consume_code_post = original_implementation.consume_code_post
async def thirdparty_sign_in_up_post(provider: Provider, code: str, redirect_uri: str, client_id: Union[str, None], auth_code_response: Union[Dict[str, Any], None], api_options: ThirdPartyAPIOptions, user_context: Dict[str, Any]): # call the default behaviour as show below result = await original_thirdparty_sign_in_up_post(provider, code, redirect_uri, client_id, auth_code_response, api_options, user_context) if isinstance(result, ThirdPartySignInUpPostOkResult): if result.created_new_user: pass # TODO: some post sign up logic else: pass # TODO: some post sign in logic return result async def consume_code_post(pre_auth_session_id: str, user_input_code: Union[str, None], device_id: Union[str, None], link_code: Union[str, None], api_options: PasswordlessAPIOptions, user_context: Dict[str, Any]): # First we call the original implementation of consume_code_post. response = await original_consume_code_post(pre_auth_session_id, user_input_code, device_id, link_code, api_options, user_context)
# Post sign up response, we check if it was successful if isinstance(response, ConsumeCodePostOkResult): _ = response.user.user_id __ = response.user.email ___ = response.user.phone_number
if response.created_new_user: pass # TODO: Post sign up logic else: pass # TODO: Post sign in logic
return response original_implementation.thirdparty_sign_in_up_post = thirdparty_sign_in_up_post original_implementation.consume_code_post = consume_code_post return original_implementation
init( app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."), framework='...', recipe_list=[ thirdpartypasswordless.init( contact_config=..., flow_type="...", override=thirdpartypasswordless.InputOverrideConfig( apis=override_thirdpartypasswordless_apis ), ) ])
Using the code above, if createdNewUser
is true
, you can (for example):
- Add the user's ID and their info to your own database (in addition to it being stored in SuperTokens).
- Send analytics events about a sign up.
- Send a welcome email to the user.