Skip to main content

Setting up the 1st factor

1. Initialisation

Start by following the recipe guide for the first factor. In this guide, we will take the example of thirdparty and emailpassword recipes as being the first factor.

After following the backend quick setup section (or any of the framework specific integration guides), you should have all the auth APIs exposed to the frontend via the SuperTokens middleware. The supertokens.init code on the server would look like this:

App Info

Adjust these values based on the application that you are trying to configure. To learn more about what each field means check the references page.
This is the URL of your app's API server.
This is the URL of your app's API server.
SuperTokens will expose it's APIs scoped by this base API path.
This is the URL of your website.
The path where the login UI will be rendered
import supertokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";
import UserMetadata from "supertokens-node/recipe/usermetadata";
import ThirdParty from "supertokens-node/recipe/thirdparty"
import EmailPassword from "supertokens-node/recipe/emailpassword"

supertokens.init({
framework: "express",
supertokens: {
connectionURI: "<CORE_API_ENDPOINT>",
apiKey: "<YOUR_API_KEY>",
},
appInfo: {
// learn more about this on https://supertokens.com/docs/thirdpartyemailpassword/appinfo
appName: "<YOUR_APP_NAME>",
apiDomain: "<YOUR_API_DOMAIN>",
websiteDomain: "<YOUR_WEBSITE_DOMAIN>",
apiBasePath: "/auth",
websiteBasePath: "/auth"
},
recipeList: [
ThirdParty.init({
//...
}),
EmailPassword.init({
//...
}),
Session.init(), // initializes session features
UserMetadata.init() // initializes the user metadata feature
]
});

// // //

important

You should have also added the SuperTokens middleware and errorHandler (depending on your framework) to your application. We are not showing it in the above code snippet for brevity, but it is explained in the ThirdParty + EmailPassword recipe guide.

2. Adding SecondFactorClaim

After sign up or sign in of the first factor, the existence of the session signifies the completion of the first factor, but we want to explicitly mark the second factor as incomplete. This can be done by overriding the createNewSession function in the Session.init config:

import Session from "supertokens-node/recipe/session";
import { BooleanClaim } from "supertokens-node/recipe/session/claims";

/*
This will be used to modify the session's access token payload
to add {"2fa-completed": false} into it.
*/
export const SecondFactorClaim = new BooleanClaim({
fetchValue: () => false,
key: "2fa-completed",
});

Session.init({
override: {
functions: (originalImplementation) => {
return {
...originalImplementation,
/* This function is called after signing in or signing up via the first factor */
createNewSession: async function (input) {
return originalImplementation.createNewSession({
...input,
accessTokenPayload: {
...input.accessTokenPayload,
...(await SecondFactorClaim.build(input.userId, input.recipeUserId, input.tenantId, undefined, input.userContext)),
},
});
},
};
},
},
})

We add SecondFactorClaim into the access token payload. This will be set to false on session creation (see fetchValue in the claim definition).