diff --git a/v2/emailpassword/common-customizations/sessions/multiple-api-endpoints.mdx b/v2/emailpassword/common-customizations/sessions/multiple-api-endpoints.mdx
index 34c277f4c..98f332ceb 100644
--- a/v2/emailpassword/common-customizations/sessions/multiple-api-endpoints.mdx
+++ b/v2/emailpassword/common-customizations/sessions/multiple-api-endpoints.mdx
@@ -25,10 +25,10 @@ To enable use of sessions for multiple API endpoints, you need to use the `sessi
:::important
- All your API endpoints must have the same top level domain. For example, they can be `{"api.example.com", "api2.example.com"}`, but they cannot be `{"api.example.com", "api.otherdomain.com"}`.
-- `sessionTokenBackendDomain` in the frontend config must match the `cookieDomain` set in the backend config.
+- The backend config (step 1 and 2) need to only be done if you are using cookie based auth (which is the default for web apps). If using header based auth, please skip to step 3.
:::
-## Step 1) Set Cookie Domain in the Backend Config
+## Step 1) Set Cookie Domain in the Backend Config (only applicable for cookie based auth)
You need to set the `cookieDomain` value to be the common top level domain. For example, if your API endpoints are `{"api.example.com", "api2.example.com", "api3.example.com"}`, the common portion of these endpoints is `".example.com"` (The dot is NOT important). So you would need to set the following:
@@ -112,7 +112,7 @@ Whilst the `cookieDomain` can start with a leading `.`, the value of the `apiDom
For local development, you should not set the `cookieDomain` to an IP address based domain, or `.localhost` - browsers will reject these cookies. Instead, you should [alias `localhost` to a named domain and use that](https://superuser.com/questions/152146/how-to-alias-a-hostname-on-mac-osx).
:::
-## Step 2) Set Older Cookie Domain in the Backend Config
+## Step 2) Set Older Cookie Domain in the Backend Config (only applicable for cookie based auth)
To avoid locking out users with existing sessions (they will get a 500 error when try to refresh their session), set `olderCookieDomain` to match your previous `cookieDomain`. If your `cookieDomain` was not set, you can use an empty string. However, if you don't have any existing sessions, you can skip this step entirely.
@@ -208,7 +208,7 @@ init(
The `olderCookieDomain` value should be set to prevent clients from having multiple session cookies from different domains. This can happen when cookies from a previous domain are still valid and sent with requests. For instance, if your previous `cookieDomain` was `api.example.com` and the new one is `.example.com`, both sets of cookies would be sent to the apiDomain `api.example.com`, leading to an inconsistent state. This can cause issues until the older cookies are cleared. Setting `olderCookieDomain` in the configuration ensures that the SuperTokens SDK can automatically remove these older cookies.
:::
-## Step 3) Frontend config
+## Step 3) Frontend config (for cookie or header based auth)
You need to set the same value for `sessionTokenBackendDomain` on the frontend. This will allow the frontend SDK to apply interception and automatic refreshing across all your API calls:
diff --git a/v2/mfa/backend-setup.mdx b/v2/mfa/backend-setup.mdx
index 1956a6361..1b0e84120 100644
--- a/v2/mfa/backend-setup.mdx
+++ b/v2/mfa/backend-setup.mdx
@@ -24,10 +24,6 @@ MFA requires account linking to be enabled (see [here](./important-concepts#rela
```ts
import SuperTokens, { User, RecipeUserId, } from "supertokens-node";
import { UserContext } from "supertokens-node/types";
-import ThirdPartyEmailPassword from "supertokens-node/recipe/thirdpartyemailpassword"
-import Passwordless from "supertokens-node/recipe/passwordless"
-import MultiFactorAuth from "supertokens-node/recipe/multifactorauth"
-import totp from "supertokens-node/recipe/totp"
import AccountLinking from "supertokens-node/recipe/accountlinking"
import { AccountInfoWithRecipeId } from "supertokens-node/recipe/accountlinking/types";
import { SessionContainerInterface } from "supertokens-node/recipe/session/types";
@@ -46,16 +42,25 @@ SuperTokens.init({
// highlight-start
AccountLinking.init({
shouldDoAutomaticAccountLinking: async (newAccountInfo: AccountInfoWithRecipeId & { recipeUserId?: RecipeUserId }, user: User | undefined, session: SessionContainerInterface | undefined, tenantId: string, userContext: UserContext) => {
- // This will enable first factor account linking.
- // For example, if a user logs in via email password with email e1,
- // and then signs out and logs in via Google with the same email,
- // we will link the accounts (as long as the email password user's email is
- // verified).
- // It will also enable account linking for MFA purposes.
- return {
- shouldAutomaticallyLink: true,
- shouldRequireVerification: true
+ if (session === undefined) {
+ // we do not want to do first factor account linking by default. To enable that,
+ // please see the automatic account linking docs in the recipe docs for your first factor.
+ return {
+ shouldAutomaticallyLink: false
+ };
}
+ if (user === undefined || session.getUserId() === user.id) {
+ // if it comes here, it means that a session exists, and we are trying to link the
+ // newAccountInfo to the session user, which means it's an MFA flow, so we enable
+ // linking here.
+ return {
+ shouldAutomaticallyLink: true,
+ shouldRequireVerification: false
+ }
+ }
+ return {
+ shouldAutomaticallyLink: false
+ };
}
}),
// highlight-end
@@ -80,7 +85,9 @@ Coming soon. In the meantime, checkout the [legacy method](./legacy-method/how-i
-The above snippet enables account linking for first factor login, and also for MFA purposes. However, if you want to enable account linking only for MFA purposes, you can see [this section](#enabling-account-linking-only-for-mfa-purposes).
+- The above snippet enables auto account linking only during the second factor and not for the first factor login. This means that if a user has an email password account, and then they login via Google separately (with the same email), those two accounts will not be linked. However, if the second factor for logging in is email or phone OTP, then that passwordless account will be linked to the first factor login method of that session.
+- Notice that we have set `shouldRequireVerification: false` for account linking. It means that the second factor can be linked to the first factor even though the first factor is not verified. If you want to do email verification of the first factor before setting up the second factor (for example if the first factor is email password, and the second is phone OTP), then you can set this boolean to `true`, and also init the email verification recipe on the frontend and backend in `REQUIRED` mode.
+- If you also want to enable first factor automatic account linking, see [this link](/docs/thirdpartyemailpassword/common-customizations/account-linking/automatic-account-linking).
:::important
Account linking is a paid feature, and you need to generate a license key to enable it. Enabling the MFA feature also enables account linking automatically, so you don't need to check the account linking feature separately.
@@ -869,75 +876,4 @@ It's a very common use case to want to override the default behaviour of SuperTo
Now since the sign up / sign in APIs are shared for first factor and second factor login, your override will be called for both first and second factor login. So if you want to have different behaviour for first and second factor login, you can use the `input` argument to the function to determine if the user is doing first or second factor login.
-The `input` argument contains the `session` object using which you can determine if the user is doing first or second factor login. If the `session` property is `undefined`, it means it's a first factor login, else it's a second factor login. In the links above, the code snippets we have check for `input.session === undefined` to determine if it's a first factor login.
-
-## Enabling account linking only for MFA purposes
-
-The step 1 above, enables account linking for first factor login and also for MFA purposes. However, if you want to enable account linking only for MFA purposes, you can do this in the following way:
-
-
-
-
-```ts
-import SuperTokens, { User, RecipeUserId, } from "supertokens-node";
-import { UserContext } from "supertokens-node/types";
-import AccountLinking from "supertokens-node/recipe/accountlinking"
-import { AccountInfoWithRecipeId } from "supertokens-node/recipe/accountlinking/types";
-import { SessionContainerInterface } from "supertokens-node/recipe/session/types";
-
-SuperTokens.init({
- supertokens: {
- connectionURI: "..."
- },
- appInfo: {
- appName: "...",
- apiDomain: "...",
- websiteDomain: "..."
- },
- recipeList: [
- // ...
- // highlight-start
- AccountLinking.init({
- shouldDoAutomaticAccountLinking: async (newAccountInfo: AccountInfoWithRecipeId & { recipeUserId?: RecipeUserId }, user: User | undefined, session: SessionContainerInterface | undefined, tenantId: string, userContext: UserContext) => {
- if (session === undefined) {
- // we do not want to do first factor account linking by default. To enable that,
- // please see the automatic account linking docs in the recipe docs for your first factor.
- return {
- shouldAutomaticallyLink: false
- };
- }
- if (user === undefined || session.getUserId() === user.id) {
- // if it comes here, it means that a session exists, and we are trying to link the
- // newAccountInfo to the session user, which means it's an MFA flow, so we enable
- // linking here.
- return {
- shouldAutomaticallyLink: true,
- shouldRequireVerification: true
- }
- }
- return {
- shouldAutomaticallyLink: false
- };
- }
- }),
- // highlight-end
- ]
-})
-```
-
-
-
-
-:::note
-Coming soon. In the meantime, checkout the [legacy method](./legacy-method/how-it-works) for adding MFA to your app.
-:::
-
-
-
-
-:::note
-Coming soon. In the meantime, checkout the [legacy method](./legacy-method/how-it-works) for adding MFA to your app.
-:::
-
-
-
\ No newline at end of file
+The `input` argument contains the `session` object using which you can determine if the user is doing first or second factor login. If the `session` property is `undefined`, it means it's a first factor login, else it's a second factor login. In the links above, the code snippets we have check for `input.session === undefined` to determine if it's a first factor login.
\ No newline at end of file
diff --git a/v2/mfa/email-sms-otp/otp-for-all-users.mdx b/v2/mfa/email-sms-otp/otp-for-all-users.mdx
index 49ffb0e34..7261b20b8 100644
--- a/v2/mfa/email-sms-otp/otp-for-all-users.mdx
+++ b/v2/mfa/email-sms-otp/otp-for-all-users.mdx
@@ -69,16 +69,25 @@ supertokens.init({
}),
AccountLinking.init({
shouldDoAutomaticAccountLinking: async (newAccountInfo: AccountInfoWithRecipeId & { recipeUserId?: RecipeUserId }, user: User | undefined, session: SessionContainerInterface | undefined, tenantId: string, userContext: UserContext) => {
- // This will enable first factor account linking.
- // For example, if a user logs in via email password with email e1,
- // and then signs out and logs in via Google with the same email,
- // we will link the accounts (as long as the email password user's email is
- // verified).
- // It will also enable account linking for MFA purposes.
- return {
- shouldAutomaticallyLink: true,
- shouldRequireVerification: true
+ if (session === undefined) {
+ // we do not want to do first factor account linking by default. To enable that,
+ // please see the automatic account linking docs in the recipe docs for your first factor.
+ return {
+ shouldAutomaticallyLink: false
+ };
+ }
+ if (user === undefined || session.getUserId() === user.id) {
+ // if it comes here, it means that a session exists, and we are trying to link the
+ // newAccountInfo to the session user, which means it's an MFA flow, so we enable
+ // linking here.
+ return {
+ shouldAutomaticallyLink: true,
+ shouldRequireVerification: false
+ }
}
+ return {
+ shouldAutomaticallyLink: false
+ };
}
}),
// highlight-end
@@ -122,7 +131,8 @@ Coming soon. In the meantime, checkout the [legacy method](../legacy-method/how-
- Notice that we have initialised the Passwordless recipe in the `recipeList`. In this example, we only want to enable email based OTP, so we set the `contactMethod` to `EMAIL` and `flowType` to `USER_INPUT_CODE` (i.e. otp). If instead, you want to use phone sms based OTP, you should set the contact method to `PHONE`. If you want to give users both the options, or for some users use email, and for others use phone, you should set `contactMethod` to `EMAIL_OR_PHONE`.
-- We have also enabled the account linking feature since [it's required for MFA to work](../important-concepts#relation-of-account-linking-and-mfa). The above enables account linking for first and second factor login, but if you only want to enable it for second factor, see [this section](../backend-setup#enabling-account-linking-only-for-mfa-purposes).
+- We have also enabled the account linking feature since [it's required for MFA to work](../important-concepts#relation-of-account-linking-and-mfa). The above enables account linking for second factor only, but if you also want to enable it for first factor, see [this section](/docs/thirdpartyemailpassword/common-customizations/account-linking/automatic-account-linking).
+- Notice that we have set `shouldRequireVerification: false` for account linking. It means that the second factor can be linked to the first factor even though the first factor is not verified. If you want to do email verification of the first factor before setting up the second factor (for example if the first factor is email password, and the second is phone OTP), then you can set this boolean to `true`, and also init the email verification recipe on the frontend and backend in `REQUIRED` mode.
- We also override the `getMFARequirementsForAuth` function to indicate that `otp-email` must be completed before the user can access the app. Notice that we do not check for the userId there, and return `otp-email` for all users. You can also return `otp-phone` instead if you want users to complete the OTP challenge via a phone SMS. Finally, if you want to give users an option for email or phone, you can return the following array from the function:
```json
@@ -443,16 +453,25 @@ supertokens.init({
}),
AccountLinking.init({
shouldDoAutomaticAccountLinking: async (newAccountInfo: AccountInfoWithRecipeId & { recipeUserId?: RecipeUserId }, user: User | undefined, session: SessionContainerInterface | undefined, tenantId: string, userContext: UserContext) => {
- // This will enable first factor account linking.
- // For example, if a user logs in via email password with email e1,
- // and then signs out and logs in via Google with the same email,
- // we will link the accounts (as long as the email password user's email is
- // verified).
- // It will also enable account linking for MFA purposes.
- return {
- shouldAutomaticallyLink: true,
- shouldRequireVerification: true
+ if (session === undefined) {
+ // we do not want to do first factor account linking by default. To enable that,
+ // please see the automatic account linking docs in the recipe docs for your first factor.
+ return {
+ shouldAutomaticallyLink: false
+ };
+ }
+ if (user === undefined || session.getUserId() === user.id) {
+ // if it comes here, it means that a session exists, and we are trying to link the
+ // newAccountInfo to the session user, which means it's an MFA flow, so we enable
+ // linking here.
+ return {
+ shouldAutomaticallyLink: true,
+ shouldRequireVerification: false
+ }
}
+ return {
+ shouldAutomaticallyLink: false
+ };
}
}),
MultiFactorAuth.init()
diff --git a/v2/mfa/email-sms-otp/otp-for-opt-in-users.mdx b/v2/mfa/email-sms-otp/otp-for-opt-in-users.mdx
index 84fe5f53b..c729cbc51 100644
--- a/v2/mfa/email-sms-otp/otp-for-opt-in-users.mdx
+++ b/v2/mfa/email-sms-otp/otp-for-opt-in-users.mdx
@@ -78,16 +78,25 @@ supertokens.init({
}),
AccountLinking.init({
shouldDoAutomaticAccountLinking: async (newAccountInfo: AccountInfoWithRecipeId & { recipeUserId?: RecipeUserId }, user: User | undefined, session: SessionContainerInterface | undefined, tenantId: string, userContext: UserContext) => {
- // This will enable first factor account linking.
- // For example, if a user logs in via email password with email e1,
- // and then signs out and logs in via Google with the same email,
- // we will link the accounts (as long as the email password user's email is
- // verified).
- // It will also enable account linking for MFA purposes.
- return {
- shouldAutomaticallyLink: true,
- shouldRequireVerification: true
+ if (session === undefined) {
+ // we do not want to do first factor account linking by default. To enable that,
+ // please see the automatic account linking docs in the recipe docs for your first factor.
+ return {
+ shouldAutomaticallyLink: false
+ };
}
+ if (user === undefined || session.getUserId() === user.id) {
+ // if it comes here, it means that a session exists, and we are trying to link the
+ // newAccountInfo to the session user, which means it's an MFA flow, so we enable
+ // linking here.
+ return {
+ shouldAutomaticallyLink: true,
+ shouldRequireVerification: false
+ }
+ }
+ return {
+ shouldAutomaticallyLink: false
+ };
}
}),
// highlight-end
@@ -200,16 +209,25 @@ supertokens.init({
}),
AccountLinking.init({
shouldDoAutomaticAccountLinking: async (newAccountInfo: AccountInfoWithRecipeId & { recipeUserId?: RecipeUserId }, user: User | undefined, session: SessionContainerInterface | undefined, tenantId: string, userContext: UserContext) => {
- // This will enable first factor account linking.
- // For example, if a user logs in via email password with email e1,
- // and then signs out and logs in via Google with the same email,
- // we will link the accounts (as long as the email password user's email is
- // verified).
- // It will also enable account linking for MFA purposes.
- return {
- shouldAutomaticallyLink: true,
- shouldRequireVerification: true
+ if (session === undefined) {
+ // we do not want to do first factor account linking by default. To enable that,
+ // please see the automatic account linking docs in the recipe docs for your first factor.
+ return {
+ shouldAutomaticallyLink: false
+ };
+ }
+ if (user === undefined || session.getUserId() === user.id) {
+ // if it comes here, it means that a session exists, and we are trying to link the
+ // newAccountInfo to the session user, which means it's an MFA flow, so we enable
+ // linking here.
+ return {
+ shouldAutomaticallyLink: true,
+ shouldRequireVerification: false
+ }
}
+ return {
+ shouldAutomaticallyLink: false
+ };
}
}),
MultiFactorAuth.init({
@@ -247,7 +265,9 @@ Coming soon. In the meantime, checkout the [legacy method](../legacy-method/how-
In both of the examples above, notice that we have initialised the Passwordless recipe in the `recipeList`. In this example, we only want to enable email based OTP, so we set the `contactMethod` to `EMAIL` and `flowType` to `USER_INPUT_CODE` (i.e. otp). If instead, you want to use phone sms based OTP, you should set the contact method to `PHONE`. If you want to give users both the options, or for some users use email, and for others use phone, you should set `contactMethod` to `EMAIL_OR_PHONE`.
-We have also enabled the account linking feature since [it's required for MFA to work](../important-concepts#relation-of-account-linking-and-mfa). The above enables account linking for first and second factor login, but if you only want to enable it for second factor, see [this section](../backend-setup#enabling-account-linking-only-for-mfa-purposes).
+We have also enabled the account linking feature since [it's required for MFA to work](../important-concepts#relation-of-account-linking-and-mfa). The above enables account linking for second factor only, but if you also want to enable it for first factor, see [this section](/docs/thirdpartyemailpassword/common-customizations/account-linking/automatic-account-linking).
+
+Notice that we have set `shouldRequireVerification: false` for account linking. It means that the second factor can be linked to the first factor even though the first factor is not verified. If you want to do email verification of the first factor before setting up the second factor (for example if the first factor is email password, and the second is phone OTP), then you can set this boolean to `true`, and also init the email verification recipe on the frontend and backend in `REQUIRED` mode.
Once the user finishes the first factor (for example, with emailpassword), their session access token payload will look like this (for those that require OTP):
```json
@@ -409,16 +429,25 @@ supertokens.init({
}),
AccountLinking.init({
shouldDoAutomaticAccountLinking: async (newAccountInfo: AccountInfoWithRecipeId & { recipeUserId?: RecipeUserId }, user: User | undefined, session: SessionContainerInterface | undefined, tenantId: string, userContext: UserContext) => {
- // This will enable first factor account linking.
- // For example, if a user logs in via email password with email e1,
- // and then signs out and logs in via Google with the same email,
- // we will link the accounts (as long as the email password user's email is
- // verified).
- // It will also enable account linking for MFA purposes.
- return {
- shouldAutomaticallyLink: true,
- shouldRequireVerification: true
+ if (session === undefined) {
+ // we do not want to do first factor account linking by default. To enable that,
+ // please see the automatic account linking docs in the recipe docs for your first factor.
+ return {
+ shouldAutomaticallyLink: false
+ };
+ }
+ if (user === undefined || session.getUserId() === user.id) {
+ // if it comes here, it means that a session exists, and we are trying to link the
+ // newAccountInfo to the session user, which means it's an MFA flow, so we enable
+ // linking here.
+ return {
+ shouldAutomaticallyLink: true,
+ shouldRequireVerification: false
+ }
}
+ return {
+ shouldAutomaticallyLink: false
+ };
}
}),
MultiFactorAuth.init({
@@ -525,16 +554,25 @@ supertokens.init({
}),
AccountLinking.init({
shouldDoAutomaticAccountLinking: async (newAccountInfo: AccountInfoWithRecipeId & { recipeUserId?: RecipeUserId }, user: User | undefined, session: SessionContainerInterface | undefined, tenantId: string, userContext: UserContext) => {
- // This will enable first factor account linking.
- // For example, if a user logs in via email password with email e1,
- // and then signs out and logs in via Google with the same email,
- // we will link the accounts (as long as the email password user's email is
- // verified).
- // It will also enable account linking for MFA purposes.
- return {
- shouldAutomaticallyLink: true,
- shouldRequireVerification: true
+ if (session === undefined) {
+ // we do not want to do first factor account linking by default. To enable that,
+ // please see the automatic account linking docs in the recipe docs for your first factor.
+ return {
+ shouldAutomaticallyLink: false
+ };
+ }
+ if (user === undefined || session.getUserId() === user.id) {
+ // if it comes here, it means that a session exists, and we are trying to link the
+ // newAccountInfo to the session user, which means it's an MFA flow, so we enable
+ // linking here.
+ return {
+ shouldAutomaticallyLink: true,
+ shouldRequireVerification: false
+ }
}
+ return {
+ shouldAutomaticallyLink: false
+ };
}
}),
MultiFactorAuth.init({
diff --git a/v2/passwordless/common-customizations/sessions/multiple-api-endpoints.mdx b/v2/passwordless/common-customizations/sessions/multiple-api-endpoints.mdx
index 34c277f4c..98f332ceb 100644
--- a/v2/passwordless/common-customizations/sessions/multiple-api-endpoints.mdx
+++ b/v2/passwordless/common-customizations/sessions/multiple-api-endpoints.mdx
@@ -25,10 +25,10 @@ To enable use of sessions for multiple API endpoints, you need to use the `sessi
:::important
- All your API endpoints must have the same top level domain. For example, they can be `{"api.example.com", "api2.example.com"}`, but they cannot be `{"api.example.com", "api.otherdomain.com"}`.
-- `sessionTokenBackendDomain` in the frontend config must match the `cookieDomain` set in the backend config.
+- The backend config (step 1 and 2) need to only be done if you are using cookie based auth (which is the default for web apps). If using header based auth, please skip to step 3.
:::
-## Step 1) Set Cookie Domain in the Backend Config
+## Step 1) Set Cookie Domain in the Backend Config (only applicable for cookie based auth)
You need to set the `cookieDomain` value to be the common top level domain. For example, if your API endpoints are `{"api.example.com", "api2.example.com", "api3.example.com"}`, the common portion of these endpoints is `".example.com"` (The dot is NOT important). So you would need to set the following:
@@ -112,7 +112,7 @@ Whilst the `cookieDomain` can start with a leading `.`, the value of the `apiDom
For local development, you should not set the `cookieDomain` to an IP address based domain, or `.localhost` - browsers will reject these cookies. Instead, you should [alias `localhost` to a named domain and use that](https://superuser.com/questions/152146/how-to-alias-a-hostname-on-mac-osx).
:::
-## Step 2) Set Older Cookie Domain in the Backend Config
+## Step 2) Set Older Cookie Domain in the Backend Config (only applicable for cookie based auth)
To avoid locking out users with existing sessions (they will get a 500 error when try to refresh their session), set `olderCookieDomain` to match your previous `cookieDomain`. If your `cookieDomain` was not set, you can use an empty string. However, if you don't have any existing sessions, you can skip this step entirely.
@@ -208,7 +208,7 @@ init(
The `olderCookieDomain` value should be set to prevent clients from having multiple session cookies from different domains. This can happen when cookies from a previous domain are still valid and sent with requests. For instance, if your previous `cookieDomain` was `api.example.com` and the new one is `.example.com`, both sets of cookies would be sent to the apiDomain `api.example.com`, leading to an inconsistent state. This can cause issues until the older cookies are cleared. Setting `olderCookieDomain` in the configuration ensures that the SuperTokens SDK can automatically remove these older cookies.
:::
-## Step 3) Frontend config
+## Step 3) Frontend config (for cookie or header based auth)
You need to set the same value for `sessionTokenBackendDomain` on the frontend. This will allow the frontend SDK to apply interception and automatic refreshing across all your API calls:
diff --git a/v2/session/common-customizations/sessions/multiple-api-endpoints.mdx b/v2/session/common-customizations/sessions/multiple-api-endpoints.mdx
index 20f73ab34..5eb3a2232 100644
--- a/v2/session/common-customizations/sessions/multiple-api-endpoints.mdx
+++ b/v2/session/common-customizations/sessions/multiple-api-endpoints.mdx
@@ -25,10 +25,10 @@ To enable use of sessions for multiple API endpoints, you need to use the `sessi
:::important
- All your API endpoints must have the same top level domain. For example, they can be `{"api.example.com", "api2.example.com"}`, but they cannot be `{"api.example.com", "api.otherdomain.com"}`.
-- `sessionTokenBackendDomain` in the frontend config must match the `cookieDomain` set in the backend config.
+- The backend config (step 1 and 2) need to only be done if you are using cookie based auth (which is the default for web apps). If using header based auth, please skip to step 3.
:::
-## Step 1) Set Cookie Domain in the Backend Config
+## Step 1) Set Cookie Domain in the Backend Config (only applicable for cookie based auth)
You need to set the `cookieDomain` value to be the common top level domain. For example, if your API endpoints are `{"api.example.com", "api2.example.com", "api3.example.com"}`, the common portion of these endpoints is `".example.com"` (The dot is NOT important). So you would need to set the following:
@@ -112,7 +112,7 @@ Whilst the `cookieDomain` can start with a leading `.`, the value of the `apiDom
For local development, you should not set the `cookieDomain` to an IP address based domain, or `.localhost` - browsers will reject these cookies. Instead, you should [alias `localhost` to a named domain and use that](https://superuser.com/questions/152146/how-to-alias-a-hostname-on-mac-osx).
:::
-## Step 2) Set Older Cookie Domain in the Backend Config
+## Step 2) Set Older Cookie Domain in the Backend Config (only applicable for cookie based auth)
To avoid locking out users with existing sessions (they will get a 500 error when try to refresh their session), set `olderCookieDomain` to match your previous `cookieDomain`. If your `cookieDomain` was not set, you can use an empty string. However, if you don't have any existing sessions, you can skip this step entirely.
@@ -208,7 +208,7 @@ init(
The `olderCookieDomain` value should be set to prevent clients from having multiple session cookies from different domains. This can happen when cookies from a previous domain are still valid and sent with requests. For instance, if your previous `cookieDomain` was `api.example.com` and the new one is `.example.com`, both sets of cookies would be sent to the apiDomain `api.example.com`, leading to an inconsistent state. This can cause issues until the older cookies are cleared. Setting `olderCookieDomain` in the configuration ensures that the SuperTokens SDK can automatically remove these older cookies.
:::
-## Step 3) Frontend config
+## Step 3) Frontend config (for cookie or header based auth)
You need to set the same value for `sessionTokenBackendDomain` on the frontend. This will allow the frontend SDK to apply interception and automatic refreshing across all your API calls:
diff --git a/v2/thirdparty/common-customizations/account-linking/automatic-account-linking.mdx b/v2/thirdparty/common-customizations/account-linking/automatic-account-linking.mdx
index 7967d1a3b..4d3c4d059 100644
--- a/v2/thirdparty/common-customizations/account-linking/automatic-account-linking.mdx
+++ b/v2/thirdparty/common-customizations/account-linking/automatic-account-linking.mdx
@@ -103,6 +103,12 @@ Coming Soon
- `shouldAutomaticallyLink`: If this is `true`, it means that the `newAccountInfo` will be linked or will become a primary user during this API call (assuming a set of security checks pass). If this is `false`, it means that there will be no account linking related operation during this API call.
- `shouldRequireVerification`: If this is `true`, that account linking operations will only happen if the `newAccountInfo` is verified. **We strongly recommend keeping it set to `true` for security reasons.**
+:::important
+If you are returning `shouldRequireVerification` as `true`, then you need to also [enable the email verification recipe](../email-verification/about) in `REQUIRED` mode. This means that if the login method does not inherently verify the email (like for email password login), SuperTokens will require the user to go through the email verification flow first and then attempt auto linking of the account. For other login methods like sign in with Google, the email is already verified during login, so the user will not be asked to verify the email again, and account linking will be tried immediately.
+
+If you enable email verification in `OPTIONAL` mode, then whilst the user can access the account after email password login, account linking will only be attempted after they have verified their email later on. This is risky because whilst the user had access to their email password account after sign up, they could loose access to that after verification and after account linking has been completed due to the change in the primary user ID (though we provide a callback - see below - to help you migrate data from one user ID to another).
+:::
+
You can use the input of the function to dynamically decide if you want to do account linking for a particular user and / or login method or not.
diff --git a/v2/thirdparty/common-customizations/account-linking/manual-account-linking.mdx b/v2/thirdparty/common-customizations/account-linking/manual-account-linking.mdx
index a9f748409..79d0602be 100644
--- a/v2/thirdparty/common-customizations/account-linking/manual-account-linking.mdx
+++ b/v2/thirdparty/common-customizations/account-linking/manual-account-linking.mdx
@@ -19,6 +19,62 @@ Manual account linking allows you to take control of when and which accounts are
- Adding a password to an account that was created with a social or passwordless login.
- Linking accounts which don't have the same email or phone number, or have a different identifier alltogether.
+## Initialilse the account linking recipe
+
+
+
+
+```tsx
+import supertokens, { User, RecipeUserId } from "supertokens-node";
+import AccountLinking from "supertokens-node/recipe/accountlinking";
+import { AccountInfoWithRecipeId } from "supertokens-node/recipe/accountlinking/types";
+import { SessionContainerInterface } from "supertokens-node/recipe/session/types";
+
+supertokens.init({
+ supertokens: {
+ connectionURI: "...",
+ apiKey: "..."
+ },
+ appInfo: {
+ apiDomain: "...",
+ appName: "...",
+ websiteDomain: "..."
+ },
+ recipeList: [
+ // highlight-start
+ AccountLinking.init({
+ shouldDoAutomaticAccountLinking: async (newAccountInfo: AccountInfoWithRecipeId & { recipeUserId?: RecipeUserId }, user: User | undefined, session: SessionContainerInterface | undefined, tenantId: string, userContext: any) => {
+ return {
+ shouldAutomaticallyLink: false
+ }
+ }
+ })
+ // highlight-end
+ ]
+});
+```
+
+
+
+
+:::note
+Coming Soon
+:::
+
+
+
+
+:::note
+Coming Soon
+:::
+
+
+
+
+In the above, we tell SuperTokens not to do automatic account linking (during sign up or sign in APIs) by returning `shouldAutomaticallyLink: false`. Initialising the recipe is still important though so that you can use the functions from our SDK as shown below.
+
+It is of course possible to [enable auto account linking](./automatic-account-linking) and still use the functions for manual account linking below.
+
## Creating a primary user
In order to link two accounts, you first need to make one of them a primary user:
diff --git a/v2/thirdparty/common-customizations/sessions/multiple-api-endpoints.mdx b/v2/thirdparty/common-customizations/sessions/multiple-api-endpoints.mdx
index 34c277f4c..98f332ceb 100644
--- a/v2/thirdparty/common-customizations/sessions/multiple-api-endpoints.mdx
+++ b/v2/thirdparty/common-customizations/sessions/multiple-api-endpoints.mdx
@@ -25,10 +25,10 @@ To enable use of sessions for multiple API endpoints, you need to use the `sessi
:::important
- All your API endpoints must have the same top level domain. For example, they can be `{"api.example.com", "api2.example.com"}`, but they cannot be `{"api.example.com", "api.otherdomain.com"}`.
-- `sessionTokenBackendDomain` in the frontend config must match the `cookieDomain` set in the backend config.
+- The backend config (step 1 and 2) need to only be done if you are using cookie based auth (which is the default for web apps). If using header based auth, please skip to step 3.
:::
-## Step 1) Set Cookie Domain in the Backend Config
+## Step 1) Set Cookie Domain in the Backend Config (only applicable for cookie based auth)
You need to set the `cookieDomain` value to be the common top level domain. For example, if your API endpoints are `{"api.example.com", "api2.example.com", "api3.example.com"}`, the common portion of these endpoints is `".example.com"` (The dot is NOT important). So you would need to set the following:
@@ -112,7 +112,7 @@ Whilst the `cookieDomain` can start with a leading `.`, the value of the `apiDom
For local development, you should not set the `cookieDomain` to an IP address based domain, or `.localhost` - browsers will reject these cookies. Instead, you should [alias `localhost` to a named domain and use that](https://superuser.com/questions/152146/how-to-alias-a-hostname-on-mac-osx).
:::
-## Step 2) Set Older Cookie Domain in the Backend Config
+## Step 2) Set Older Cookie Domain in the Backend Config (only applicable for cookie based auth)
To avoid locking out users with existing sessions (they will get a 500 error when try to refresh their session), set `olderCookieDomain` to match your previous `cookieDomain`. If your `cookieDomain` was not set, you can use an empty string. However, if you don't have any existing sessions, you can skip this step entirely.
@@ -208,7 +208,7 @@ init(
The `olderCookieDomain` value should be set to prevent clients from having multiple session cookies from different domains. This can happen when cookies from a previous domain are still valid and sent with requests. For instance, if your previous `cookieDomain` was `api.example.com` and the new one is `.example.com`, both sets of cookies would be sent to the apiDomain `api.example.com`, leading to an inconsistent state. This can cause issues until the older cookies are cleared. Setting `olderCookieDomain` in the configuration ensures that the SuperTokens SDK can automatically remove these older cookies.
:::
-## Step 3) Frontend config
+## Step 3) Frontend config (for cookie or header based auth)
You need to set the same value for `sessionTokenBackendDomain` on the frontend. This will allow the frontend SDK to apply interception and automatic refreshing across all your API calls:
diff --git a/v2/thirdpartyemailpassword/common-customizations/account-linking/automatic-account-linking.mdx b/v2/thirdpartyemailpassword/common-customizations/account-linking/automatic-account-linking.mdx
index 9867cf517..33fafc732 100644
--- a/v2/thirdpartyemailpassword/common-customizations/account-linking/automatic-account-linking.mdx
+++ b/v2/thirdpartyemailpassword/common-customizations/account-linking/automatic-account-linking.mdx
@@ -103,6 +103,12 @@ Coming Soon
- `shouldAutomaticallyLink`: If this is `true`, it means that the `newAccountInfo` will be linked or will become a primary user during this API call (assuming a set of security checks pass). If this is `false`, it means that there will be no account linking related operation during this API call.
- `shouldRequireVerification`: If this is `true`, that account linking operations will only happen if the `newAccountInfo` is verified. **We strongly recommend keeping it set to `true` for security reasons.**
+:::important
+If you are returning `shouldRequireVerification` as `true`, then you need to also [enable the email verification recipe](../email-verification/about) in `REQUIRED` mode. This means that if the login method does not inherently verify the email (like for email password login), SuperTokens will require the user to go through the email verification flow first and then attempt auto linking of the account. For other login methods like sign in with Google, the email is already verified during login, so the user will not be asked to verify the email again, and account linking will be tried immediately.
+
+If you enable email verification in `OPTIONAL` mode, then whilst the user can access the account after email password login, account linking will only be attempted after they have verified their email later on. This is risky because whilst the user had access to their email password account after sign up, they could loose access to that after verification and after account linking has been completed due to the change in the primary user ID (though we provide a callback - see below - to help you migrate data from one user ID to another).
+:::
+
You can use the input of the function to dynamically decide if you want to do account linking for a particular user and / or login method or not.
diff --git a/v2/thirdpartyemailpassword/common-customizations/account-linking/manual-account-linking.mdx b/v2/thirdpartyemailpassword/common-customizations/account-linking/manual-account-linking.mdx
index 5d585891d..5f2b20445 100644
--- a/v2/thirdpartyemailpassword/common-customizations/account-linking/manual-account-linking.mdx
+++ b/v2/thirdpartyemailpassword/common-customizations/account-linking/manual-account-linking.mdx
@@ -19,6 +19,62 @@ Manual account linking allows you to take control of when and which accounts are
- Adding a password to an account that was created with a social or passwordless login.
- Linking accounts which don't have the same email or phone number, or have a different identifier alltogether.
+## Initialilse the account linking recipe
+
+
+
+
+```tsx
+import supertokens, { User, RecipeUserId } from "supertokens-node";
+import AccountLinking from "supertokens-node/recipe/accountlinking";
+import { AccountInfoWithRecipeId } from "supertokens-node/recipe/accountlinking/types";
+import { SessionContainerInterface } from "supertokens-node/recipe/session/types";
+
+supertokens.init({
+ supertokens: {
+ connectionURI: "...",
+ apiKey: "..."
+ },
+ appInfo: {
+ apiDomain: "...",
+ appName: "...",
+ websiteDomain: "..."
+ },
+ recipeList: [
+ // highlight-start
+ AccountLinking.init({
+ shouldDoAutomaticAccountLinking: async (newAccountInfo: AccountInfoWithRecipeId & { recipeUserId?: RecipeUserId }, user: User | undefined, session: SessionContainerInterface | undefined, tenantId: string, userContext: any) => {
+ return {
+ shouldAutomaticallyLink: false
+ }
+ }
+ })
+ // highlight-end
+ ]
+});
+```
+
+
+
+
+:::note
+Coming Soon
+:::
+
+
+
+
+:::note
+Coming Soon
+:::
+
+
+
+
+In the above, we tell SuperTokens not to do automatic account linking (during sign up or sign in APIs) by returning `shouldAutomaticallyLink: false`. Initialising the recipe is still important though so that you can use the functions from our SDK as shown below.
+
+It is of course possible to [enable auto account linking](./automatic-account-linking) and still use the functions for manual account linking below.
+
## Creating a primary user
In order to link two accounts, you first need to make one of them a primary user:
diff --git a/v2/thirdpartyemailpassword/common-customizations/sessions/multiple-api-endpoints.mdx b/v2/thirdpartyemailpassword/common-customizations/sessions/multiple-api-endpoints.mdx
index 20f73ab34..5eb3a2232 100644
--- a/v2/thirdpartyemailpassword/common-customizations/sessions/multiple-api-endpoints.mdx
+++ b/v2/thirdpartyemailpassword/common-customizations/sessions/multiple-api-endpoints.mdx
@@ -25,10 +25,10 @@ To enable use of sessions for multiple API endpoints, you need to use the `sessi
:::important
- All your API endpoints must have the same top level domain. For example, they can be `{"api.example.com", "api2.example.com"}`, but they cannot be `{"api.example.com", "api.otherdomain.com"}`.
-- `sessionTokenBackendDomain` in the frontend config must match the `cookieDomain` set in the backend config.
+- The backend config (step 1 and 2) need to only be done if you are using cookie based auth (which is the default for web apps). If using header based auth, please skip to step 3.
:::
-## Step 1) Set Cookie Domain in the Backend Config
+## Step 1) Set Cookie Domain in the Backend Config (only applicable for cookie based auth)
You need to set the `cookieDomain` value to be the common top level domain. For example, if your API endpoints are `{"api.example.com", "api2.example.com", "api3.example.com"}`, the common portion of these endpoints is `".example.com"` (The dot is NOT important). So you would need to set the following:
@@ -112,7 +112,7 @@ Whilst the `cookieDomain` can start with a leading `.`, the value of the `apiDom
For local development, you should not set the `cookieDomain` to an IP address based domain, or `.localhost` - browsers will reject these cookies. Instead, you should [alias `localhost` to a named domain and use that](https://superuser.com/questions/152146/how-to-alias-a-hostname-on-mac-osx).
:::
-## Step 2) Set Older Cookie Domain in the Backend Config
+## Step 2) Set Older Cookie Domain in the Backend Config (only applicable for cookie based auth)
To avoid locking out users with existing sessions (they will get a 500 error when try to refresh their session), set `olderCookieDomain` to match your previous `cookieDomain`. If your `cookieDomain` was not set, you can use an empty string. However, if you don't have any existing sessions, you can skip this step entirely.
@@ -208,7 +208,7 @@ init(
The `olderCookieDomain` value should be set to prevent clients from having multiple session cookies from different domains. This can happen when cookies from a previous domain are still valid and sent with requests. For instance, if your previous `cookieDomain` was `api.example.com` and the new one is `.example.com`, both sets of cookies would be sent to the apiDomain `api.example.com`, leading to an inconsistent state. This can cause issues until the older cookies are cleared. Setting `olderCookieDomain` in the configuration ensures that the SuperTokens SDK can automatically remove these older cookies.
:::
-## Step 3) Frontend config
+## Step 3) Frontend config (for cookie or header based auth)
You need to set the same value for `sessionTokenBackendDomain` on the frontend. This will allow the frontend SDK to apply interception and automatic refreshing across all your API calls:
diff --git a/v2/thirdpartypasswordless/common-customizations/account-linking/automatic-account-linking.mdx b/v2/thirdpartypasswordless/common-customizations/account-linking/automatic-account-linking.mdx
index 7967d1a3b..4d3c4d059 100644
--- a/v2/thirdpartypasswordless/common-customizations/account-linking/automatic-account-linking.mdx
+++ b/v2/thirdpartypasswordless/common-customizations/account-linking/automatic-account-linking.mdx
@@ -103,6 +103,12 @@ Coming Soon
- `shouldAutomaticallyLink`: If this is `true`, it means that the `newAccountInfo` will be linked or will become a primary user during this API call (assuming a set of security checks pass). If this is `false`, it means that there will be no account linking related operation during this API call.
- `shouldRequireVerification`: If this is `true`, that account linking operations will only happen if the `newAccountInfo` is verified. **We strongly recommend keeping it set to `true` for security reasons.**
+:::important
+If you are returning `shouldRequireVerification` as `true`, then you need to also [enable the email verification recipe](../email-verification/about) in `REQUIRED` mode. This means that if the login method does not inherently verify the email (like for email password login), SuperTokens will require the user to go through the email verification flow first and then attempt auto linking of the account. For other login methods like sign in with Google, the email is already verified during login, so the user will not be asked to verify the email again, and account linking will be tried immediately.
+
+If you enable email verification in `OPTIONAL` mode, then whilst the user can access the account after email password login, account linking will only be attempted after they have verified their email later on. This is risky because whilst the user had access to their email password account after sign up, they could loose access to that after verification and after account linking has been completed due to the change in the primary user ID (though we provide a callback - see below - to help you migrate data from one user ID to another).
+:::
+
You can use the input of the function to dynamically decide if you want to do account linking for a particular user and / or login method or not.
diff --git a/v2/thirdpartypasswordless/common-customizations/account-linking/manual-account-linking.mdx b/v2/thirdpartypasswordless/common-customizations/account-linking/manual-account-linking.mdx
index a9f748409..79d0602be 100644
--- a/v2/thirdpartypasswordless/common-customizations/account-linking/manual-account-linking.mdx
+++ b/v2/thirdpartypasswordless/common-customizations/account-linking/manual-account-linking.mdx
@@ -19,6 +19,62 @@ Manual account linking allows you to take control of when and which accounts are
- Adding a password to an account that was created with a social or passwordless login.
- Linking accounts which don't have the same email or phone number, or have a different identifier alltogether.
+## Initialilse the account linking recipe
+
+
+
+
+```tsx
+import supertokens, { User, RecipeUserId } from "supertokens-node";
+import AccountLinking from "supertokens-node/recipe/accountlinking";
+import { AccountInfoWithRecipeId } from "supertokens-node/recipe/accountlinking/types";
+import { SessionContainerInterface } from "supertokens-node/recipe/session/types";
+
+supertokens.init({
+ supertokens: {
+ connectionURI: "...",
+ apiKey: "..."
+ },
+ appInfo: {
+ apiDomain: "...",
+ appName: "...",
+ websiteDomain: "..."
+ },
+ recipeList: [
+ // highlight-start
+ AccountLinking.init({
+ shouldDoAutomaticAccountLinking: async (newAccountInfo: AccountInfoWithRecipeId & { recipeUserId?: RecipeUserId }, user: User | undefined, session: SessionContainerInterface | undefined, tenantId: string, userContext: any) => {
+ return {
+ shouldAutomaticallyLink: false
+ }
+ }
+ })
+ // highlight-end
+ ]
+});
+```
+
+
+
+
+:::note
+Coming Soon
+:::
+
+
+
+
+:::note
+Coming Soon
+:::
+
+
+
+
+In the above, we tell SuperTokens not to do automatic account linking (during sign up or sign in APIs) by returning `shouldAutomaticallyLink: false`. Initialising the recipe is still important though so that you can use the functions from our SDK as shown below.
+
+It is of course possible to [enable auto account linking](./automatic-account-linking) and still use the functions for manual account linking below.
+
## Creating a primary user
In order to link two accounts, you first need to make one of them a primary user:
diff --git a/v2/thirdpartypasswordless/common-customizations/sessions/multiple-api-endpoints.mdx b/v2/thirdpartypasswordless/common-customizations/sessions/multiple-api-endpoints.mdx
index 34c277f4c..98f332ceb 100644
--- a/v2/thirdpartypasswordless/common-customizations/sessions/multiple-api-endpoints.mdx
+++ b/v2/thirdpartypasswordless/common-customizations/sessions/multiple-api-endpoints.mdx
@@ -25,10 +25,10 @@ To enable use of sessions for multiple API endpoints, you need to use the `sessi
:::important
- All your API endpoints must have the same top level domain. For example, they can be `{"api.example.com", "api2.example.com"}`, but they cannot be `{"api.example.com", "api.otherdomain.com"}`.
-- `sessionTokenBackendDomain` in the frontend config must match the `cookieDomain` set in the backend config.
+- The backend config (step 1 and 2) need to only be done if you are using cookie based auth (which is the default for web apps). If using header based auth, please skip to step 3.
:::
-## Step 1) Set Cookie Domain in the Backend Config
+## Step 1) Set Cookie Domain in the Backend Config (only applicable for cookie based auth)
You need to set the `cookieDomain` value to be the common top level domain. For example, if your API endpoints are `{"api.example.com", "api2.example.com", "api3.example.com"}`, the common portion of these endpoints is `".example.com"` (The dot is NOT important). So you would need to set the following:
@@ -112,7 +112,7 @@ Whilst the `cookieDomain` can start with a leading `.`, the value of the `apiDom
For local development, you should not set the `cookieDomain` to an IP address based domain, or `.localhost` - browsers will reject these cookies. Instead, you should [alias `localhost` to a named domain and use that](https://superuser.com/questions/152146/how-to-alias-a-hostname-on-mac-osx).
:::
-## Step 2) Set Older Cookie Domain in the Backend Config
+## Step 2) Set Older Cookie Domain in the Backend Config (only applicable for cookie based auth)
To avoid locking out users with existing sessions (they will get a 500 error when try to refresh their session), set `olderCookieDomain` to match your previous `cookieDomain`. If your `cookieDomain` was not set, you can use an empty string. However, if you don't have any existing sessions, you can skip this step entirely.
@@ -208,7 +208,7 @@ init(
The `olderCookieDomain` value should be set to prevent clients from having multiple session cookies from different domains. This can happen when cookies from a previous domain are still valid and sent with requests. For instance, if your previous `cookieDomain` was `api.example.com` and the new one is `.example.com`, both sets of cookies would be sent to the apiDomain `api.example.com`, leading to an inconsistent state. This can cause issues until the older cookies are cleared. Setting `olderCookieDomain` in the configuration ensures that the SuperTokens SDK can automatically remove these older cookies.
:::
-## Step 3) Frontend config
+## Step 3) Frontend config (for cookie or header based auth)
You need to set the same value for `sessionTokenBackendDomain` on the frontend. This will allow the frontend SDK to apply interception and automatic refreshing across all your API calls: