All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning
- Adds
getCookieNameForTokenType
config option to allow customizing the cookie name for a token type. - Adds
getResponseHeaderNameForTokenType
config option to allow customizing the response header name for a token type.- Please note, that using this will require further customizations on the frontend
- Fixes an issue where
removeDevice
API allowed removing verified TOTP devices without the user completing MFA.
- Added OAuth2Provider recipe
- Added a way to run CI on unmerged PRs
- Added support for FDIs: 3.1 and 4.0. Required by: auth-react >=0.48.0 and web-js>=0.14.0
- The
networkInterceptor
now also gets a newparams
prop in the request config. - Adds
customFramework
util functions to minimize code required in custom frameworks like remix, astro etc. - Replicates
fastify
types based on requirement for the SDK instead of using the original module. - Improved type definitions for
TypeProvider
- Changes type of value in formField object to be
unknown
instead ofstring
to add support for accepting any type of value in form fields. - Only supporting CDI 5.2, Compatible with Core version >= 9.3
- Removed the
overwriteSessionDuringSignInUp
option. - Added a new
shouldTryLinkingWithSessionUser
to sign in/up related APIs (and the related recipe functions)- This will default to false on the API
- This will be set to true in function calls if you pass a session, otherwise it is set to false
- By setting this to true you can enable MFA flows (trying to connect to the session user)
- If set to false, the sign-in/up will be considered a first-factor
- Changed APIs:
EmailPassword.signInPOST
EmailPassword.signUpPOST
ThirdParty.signInUpPOST
Passwordless.createCodePOST
Passwordless.consumeCodePOST
Passwordless.resendCodePOST
- Changed functions:
EmailPassword.signIn
EmailPassword.signUp
ThirdParty.signInUp
ThirdPary.manuallyCreateOrUpdateUser
Passwordless.createCode
Passwordless.consumeCode
- We no longer try to load the session if
shouldTryLinkingWithSessionUser
is set to false. - Changed the return type of
getOpenIdConfiguration
andgetOpenIdDiscoveryConfigurationGET
, and added the following props:- authorization_endpoint
- token_endpoint
- userinfo_endpoint
- revocation_endpoint
- token_introspection_endpoint
- end_session_endpoint
- subject_types_supported
- id_token_signing_alg_values_supported
- response_types_supported
- Exposing the OpenId recipe separately and remove it from the Session recipe
- This means that we removed
override.openIdFeature
from the Session recipe configuration
- This means that we removed
- Removed
getJWKS
from the OpenId recipe, as it is already exposed by the JWT recipe - We now automatically initialize the OpenId and JWT recipes even if you do not use the Session recipe
getAppDirRequestHandler
fornextjs
will no longer accept a Response object.
If you used to use the openIdFeature
in the Session recipe, you should now use the OpenId recipe directly instead:
Before:
import SuperTokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "...",
},
recipeList: [
Session.init({
override: {
openIdFeature: {
jwtFeature: {
functions: originalImplementation => ({
...originalImplementation,
getJWKS: async (input) => {
console.log("getJWKS called");
return originalImplementation.getJWKS(input);
},
})
},
functions: originalImplementation => ({
...originalImplementation,
getOpenIdDiscoveryConfiguration: async (input) => ({
issuer: "your issuer",
jwks_uri: "https://your.api.domain/auth/jwt/jwks.json",
status: "OK"
}),
})
}
}
});
],
});
After:
import SuperTokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";
import OpenId from "supertokens-node/recipe/openid";
import JWT from "supertokens-node/recipe/jwt";
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "...",
},
recipeList: [
Session.init(),
JWT.init({
override: {
functions: originalImplementation => ({
...originalImplementation,
getJWKS: async (input) => {
console.log("getJWKS called");
return originalImplementation.getJWKS(input);
},
})
}
}),
OpenId.init({
override: {
functions: originalImplementation => ({
...originalImplementation,
getOpenIdDiscoveryConfiguration: async (input) => ({
issuer: "your issuer",
jwks_uri: "https://your.api.domain/auth/jwt/jwks.json",
status: "OK"
}),
})
}
});
],
});
Before:
import { getAppDirRequestHandler } from "supertokens-node/nextjs";
import { NextResponse } from "next/server";
const handleCall = getAppDirRequestHandler(NextResponse);
After:
import { getAppDirRequestHandler } from "supertokens-node/nextjs";
const handleCall = getAppDirRequestHandler();
- Fixes an issue where users were not able to reset their password if a user with the same email address was created before account linking was enabled.
- Fixes and re-works some security checks connected to password reset.
- Fixes an issue where revoking sessions for a specific tenant didn't work well
- Fixes an issue where the automatic session revocation after linking didn't work across all tenants
- Replaces
psl
withtldts
to avoidpunycode
deprecation warning.
- Fixes formFields to accept non string types as well.
- Fixes an issue with Okta / Active Directory providers where we check for additional config if
oidcDiscoveryEndpoint
is not defined. It would not be necessary in the cases where other endpoints are already provided.
- Add edge compatibility for custom frameworks and Next.JS
- Optional form fields are now truly optional, can be omitted from the payload.
- Improves thirdParty debug logging to help with debugging issues with JSON parsing.
- Fixes issue with dashboard APIs
createOrUpdateThirdPartyConfig
anddeleteThirdPartyConfig
which did not takeincludeInNonPublicTenantsByDefault
into account for non-public tenants. - Updates test server to support dashboard tests.
- Fixes an issue where
shouldDoAutomaticAccountLinking
was called without a primary user when linking in some cases.
- Fixes an issue with
removeFromPayloadByMerge_internal
forMultiFactorAuthClaim
where it was not retaining other claims while removing the claim from the payload. - Updates testing with backend-sdk-testing repo to run against all supported FDI versions.
- Updates
createOrUpdateThirdPartyConfig
andgetThirdPartyConfig
dashboard APIs to handle boxy SAML inputs. - Fixes an issue where
isEmailChangeAllowed
was not checking across all tenants
- For a non-public tenant, when there are no providers added in the core, the SDK used to fallback to the providers added in the ThirdParty.init. Now, the SDK will not fallback to the providers added in the ThirdParty.init by default. If you require a thirdparty provider to be available for non-public tenants, you can make it available by setting
includeInNonPublicTenantsByDefault
for each of the providers. See the migration section below to see how to do this. Note that this only affects non-public tenants when there are no providers added in core.
To make all the providers added in the ThirdParty.init available for non-public tenants by default,
Before:
ThirdParty.init({
signInAndUpFeature: {
providers: [
{
config: {
thirdPartyId: "google",
// ... rest of the config
},
},
{
config: {
thirdPartyId: "github",
// ... rest of the config
},
},
],
},
});
After:
ThirdParty.init({
signInAndUpFeature: {
providers: [
{
config: {
thirdPartyId: "google",
// ... rest of the config
},
// Add the following line to make this provider available in non-public tenants by default
includeInNonPublicTenantsByDefault: true,
},
{
config: {
thirdPartyId: "github",
// ... rest of the config
},
// Add the following line to make this provider available in non-public tenants by default
includeInNonPublicTenantsByDefault: true,
},
],
},
});
- Fixes issue in fetching
thirdPartyConfig
for dashboard when OIDC discovery endpoint is added in core.
-
Defined the entry points of the library using the "exports" field in package.json to make ESM imports more comfortable. This can cause some issues for applications using directory imports from the
lib/build
directory. In those cases we recommend addingindex.js
to the import path. -
isEmailChangeAllowed
now returns false for unverified addresses if input user is a primary user and there exists another user with the same email address and linking requires verification -
Generating a password reset token is now denied if all of the following is true:
- a linked email password user exists
- the email address is not verified
- the user has another email address or phone number associated with it
-
Account linking based on emails now require the email to be verified in both users if
shouldRequireVerification
is set totrue
instead of only requiring it for the recipe user. -
The access token cookie expiry has been changed from 100 years to 1 year due to some browsers capping the maximum expiry at 400 days. No action is needed on your part.
-
Recipe functions that update the email address of users now call
isEmailChangeAllowed
to check if the email update should be allowed or not.- This only has an effect if account linking is turned on.
- This is aimed to help you avoid security issues.
isEmailChangeAllowed
is now called in functions:updateUser
(Passwordless recipe)updateEmailOrPassword
(EmailPassword recipe)manuallyCreateOrUpdateUser
(ThirdParty recipe)
-
Removes the default
maxAgeInSeconds
value (previously 300 seconds) in EmailVerification Claim. If the claim value is true andmaxAgeInSeconds
is not provided, it will not be refetched. -
In the multitenancy recipe,
- Removes
emailPasswordEnabled
,passwordlessEnabled
,thirdPartyEnabled
inputs fromcreateOrUpdateTenant
functions. - Recipe implementation uses v2 APIs for creating, fetching and listing tenants. Refer CDI spec for more information.
- Removes
-
SDK will no longer add
.well-known/openid-configuration
to theoidcDiscoveryEndpoint
config in thirdParty providers. If you have specified any customoidcDiscoveryEndpoint
in the ThirdParty.init or added to the core, please make sure to update them to include.well-known/openid-configuration
.
- Adds Multitenancy and Multifactor auth related APIs for dashboard:
- GET
/api/tenants
- GET
/api/tenant
- POST
/api/tenant
- DELETE
/api/tenant
- PUT
/api/tenant/first-factor
- PUT
/api/tenant/required-secondary-factor
- PUT
/api/tenant/core-config
- GET
/api/thirdparty/config
- PUT
/api/thirdparty/config
- DELETE
/api/thirdparty/config
- GET
passwordResetPOST
:- now verifies the email address in all cases if the EmailVerification recipe is initialized
- now tries to link accounts based on account info if AccountLinking is enabled
- Extracted some tests into a separate backend-sdk-testing repo, to reuse tests between our backend SDKs
- Sends
websiteDomain
andapiDomain
to core for telemetry. boxyURL
is no more mandatory input inadditionalConfig
while adding boxy-saml provider in thirdParty.- Fixes issue with OIDC discover when the input url already contains
.well-known/openid-configuration
. - Removes the default
maxAgeInSeconds
value in EmailVerification Claim when the claim value is true. Now, the SDK won't refetch the claim value ifmaxAgeInSeconds
is not provided and claim value is true. - Adds
jwksRefreshIntervalSec
config tosession.init
to set the default JWKS cache duration. The default is 4 hours.
If you were using Multitenancy.createOrUpdateTenant, you should remove the emailPasswordEnabled
, passwordlessEnabled
, thirdPartyEnabled
inputs from the function call, and just use the firstFactors
and requiredSecondaryFactors
as applicable.
Here are some examples:
-
Using Emailpassword and ThirdParty login methods
Before:
Multitenancy.createOrUpdateTenant("tenantId", { emailPasswordEnabled: true, thirdPartyEnabled: true, });
After:
Multitenancy.createOrUpdateTenant("tenantId", { firstFactors: ["emailpassword", "thirdparty"], });
-
Using Passwordless and ThirdParty login methods. Note that for passwordless, you need to specify all the passwordless factorIds you wish to use.
Before:
Multitenancy.createOrUpdateTenant("tenantId", { passwordlessEnabled: true, thirdPartyEnabled: true, });
After:
Multitenancy.createOrUpdateTenant("tenantId", { firstFactors: ["otp-email", "otp-phone", "link-email", "link-phone", "thirdparty"], });
-
Using EmailPassword, ThirdParty for first factor and phone OTP, TOTP for secondary factors
Before:
Multitenancy.createOrUpdateTenant("tenantId", { emailPasswordEnabled: true, thirdPartyEnabled: true, passwordlessEnabled: true, firstFactors: ["emailpassword", "thirdparty"], requiredSecondaryFactors: ["otp-phone", "totp"], });
After:
Multitenancy.createOrUpdateTenant("tenantId", { firstFactors: ["emailpassword", "thirdparty"], requiredSecondaryFactors: ["otp-phone", "totp"], });
-
Enable everything in core so that SDK can configure the required login methods and required secondary factors
Before:
Multitenancy.createOrUpdateTenant("tenantId", { emailPasswordEnabled: true, thirdPartyEnabled: true, passwordlessEnabled: true, });
After:
Multitenancy.createOrUpdateTenant("tenantId", { firstFactors: null, requiredSecondaryFactors: null, });
Before:
ThirdParty.init({
signInAndUpFeature: {
providers: [
{
config: {
thirdPartyId: "custom",
clients: [
// ...
],
oidcDiscoveryEndpoint: "https://auth.example.com",
},
},
],
},
});
After:
ThirdParty.init({
signInAndUpFeature: {
providers: [
{
config: {
thirdPartyId: "custom",
clients: [
// ...
],
oidcDiscoveryEndpoint: "https://auth.example.com/.well-known/openid-configuration",
},
},
],
},
});
For each tenant, do the following
-
GET
/appid-<appId>/<tenantId>/recipe/multitenancy/tenant/v2
You should see the thirdParty providers in the response using
response.thirdParty.providers
-
For each config in providers list, if you have
oidcDiscoveryEndpoint
in the config, update it to include.well-known/openid-configuration
at the end.
Here's a sample code snippet to update the oidcDiscoveryEndpoint
:
import Multitenancy from "supertokens-node/recipe/multitenancy";
const tenantsRes = await Multitenancy.listAllTenants();
function isCustomProvider(thirdPartyId: string): boolean {
const customProviders = [
"custom",
//... all your custom thirdPartyIds
];
return customProviders.includes(thirdPartyId);
}
for (const tenant of tenantsRes.tenants) {
for (const provider of tenant.thirdParty.providers) {
if (isCustomProvider(provider.thirdPartyId) && provider.oidcDiscoveryEndpoint !== undefined) {
if (provider.oidcDiscoveryEndpoint.endsWith("/")) {
provider.oidcDiscoveryEndpoint = provider.oidcDiscoveryEndpoint.slice(0, -1);
}
provider.oidcDiscoveryEndpoint = `${provider.config.oidcDiscoveryEndpoint}/.well-known/openid-configuration`;
await Multitenancy.createOrUpdateThirdPartyConfig(tenant.tenantId, provider);
}
}
}
refreshPOST
andrefreshSession
now clears all user tokens upon CSRF failures and if no tokens are found. See the latest comment on #141 for more details.
refreshPOST
andrefreshSession
now clears all user tokens upon CSRF failures and if no tokens are found. See the latest comment on #141 for more details.
- Fix a bug that was preventing errors from being caught in the fetch function, thus bypassing our error handling.
- Removed ThirdPartyEmailPassword and ThirdPartyPasswordless recipes. Instead, you should use ThirdParty + EmailPassword or ThirdParty + Passwordless recipes separately in your recipe list.
- Removed
rid
query param from:- email verification links
- passwordless magic links
- password reset links
- The API for checking if an email exists in the passwordless recipe has changed to return true only if there exists a user with that email as a passwordless user. So for example, earlier, if a user existed with email
[email protected]
as an emailpassword user (and not passwordless user), the passwordless API for does email exist would return true, but now, it won't.
- Even if the
rid
header is present in an API call, the routing now not only depends on that. If the SDK cannot resolve a request handler based on therid
, request path and method, it will try to resolve a request handler only based on the request path and method (therefore ignoring therid
header). - New API handlers are:
GET /emailpassword/email/exists
=> email password, does email exist API (used to beGET /signup/email/exists
withrid
ofemailpassword
orthirdpartyemailpassword
which is now deprecated)GET /passwordless/email/exists
=> email password, does email exist API (used to beGET /signup/email/exists
withrid
ofpasswordless
orthirdpartypasswordless
which is now deprecated)GET /passwordless/phonenumber/exists
=> email password, does email exist API (used to beGET /signup/phonenumber/exists
which is now deprecated)
- Support for FDI 2.0 and 3.0
-
If you were using
ThirdPartyEmailPassword
, you should now initThirdParty
andEmailPassword
recipes separately. The config for the individual recipes are mostly the same, except the syntax may be different. Check our recipe guides for ThirdParty and EmailPassword for more information. -
If you were using
ThirdPartyPasswordless
, you should now initThirdParty
andPasswordless
recipes separately. The config for the individual recipes are mostly the same, except the syntax may be different. Check our recipe guides for ThirdParty and Passwordless for more information.
- Fixes override recursion build-up in built-in providers due to the modification of the
input.override
object in the ThirdParty providers list. - Fixes issue with reference to
config
object inTypeProvider
in the provider override. The issue was theoriginalImplementation.config
object did not have the updatedconfig
values that was being used in the provider implementation.
- Add workaround for unsupported 'cache' field in Cloudflare Workers. We retry fetch requests without the 'cache' field if they fail due to it not being implemented.
- Fixed an issue when using Apple as a third party provider with our NextJs integration.
- Added a compatibility layer into
BaseRequest
to handle the form data parser returningFormData
instead of the raw parsed object. This is to address/fix the above issues, possibly present in other frameworks.
- Added
olderCookieDomain
config option in the session recipe. This will allow users to clear cookies from the older domain when thecookieDomain
is changed. - If
verifySession
detects multiple access tokens in the request, it will return a 401 error, prompting a refresh, even if one of the tokens is valid. refreshPOST
(/auth/session/refresh
by default) API changes:- now returns 500 error if multiple access tokens are present in the request and
config.olderCookieDomain
is not set. - now clears the access token cookie if it was called without a refresh token (if an access token cookie exists and if using cookie-based sessions).
- now clears cookies from the old domain if
olderCookieDomain
is specified and multiple refresh/access token cookies exist, without updating the front-token or any of the tokens. - now a 200 response may not include new session tokens.
- now returns 500 error if multiple access tokens are present in the request and
This update addresses an edge case where changing the cookieDomain
config on the server can lead to session integrity issues. For instance, if the API server URL is 'api.example.com' with a cookie domain of '.example.com', and the server updates the cookie domain to 'api.example.com', the client may retain cookies with both '.example.com' and 'api.example.com' domains, resulting in multiple sets of session token cookies existing.
Previously, verifySession would select one of the access tokens from the incoming request. If it chose the older cookie, it would return a 401 status code, prompting a refresh request. However, the refreshPOST
API would then set new session token cookies with the updated cookieDomain
, but older cookies will persist, leading to repeated 401 errors and refresh loops.
With this update, verifySession will return a 401 error if it detects multiple access tokens in the request, prompting a refresh request. The refreshPOST
API will clear cookies from the old domain if olderCookieDomain
is specified in the configuration, then return a 200 status. If olderCookieDomain
is not configured, the refreshPOST
API will return a 500 error with a message instructing to set olderCookieDomain
.
Example:
apiDomain
: 'api.example.com'cookieDomain
: 'api.example.com'
Flow:
- After authentication, the frontend has cookies set with
domain=api.example.com
, but the access token has expired. - The server updates
cookieDomain
to.example.com
. - An API call requiring session with an expired access token (cookie with
domain=api.example.com
) results in a 401 response. - The frontend attempts to refresh the session, generating a new access token saved with
domain=.example.com
. - The original API call is retried, but because it sends both the old and new cookies, it again results in a 401 response.
- The frontend tries to refresh the session with multiple access tokens: - If
olderCookieDomain
is not set, the refresh fails with a 500 error. - The user remains stuck until they clear cookies manually orolderCookieDomain
is set. - IfolderCookieDomain
is set, the refresh clears the older cookie, returning a 200 response. - The frontend retries the original API call, sending only the new cookie (domain=.example.com
), resulting in a successful request.
- Adds
no-cache
header when querying core, so that frameworks like NextJS don't cache GET requests (https://nextjs.org/docs/app/building-your-application/caching#data-cache)
- Fixes how FDI header is parsed from frontend requests to account for more than one version being passed.
- Support for websiteDomain / apiDomain ending with
.local
: #823
- Improved error message to help debugging if MFA was enabled without account linking.
- Now the
resyncSessionAndFetchMFAInfoPUT
will throw if the user is in a stuck state, because they are required to complete factors, but they are not allowed to because of some configuration issue.
- Smaller fixes in
Passwordless
:- Fixed an issue in
createCodePOST
where the flowtype wasn't appropriately set in some MFA cases - Fixed an interaction with the
firstFactors
config of theMultiFactorAuth
recipe increateCodePOST
- Fixed an issue in
resendCodePOST
where the email/text message included a magic link when it shouldn't have in some MFA cases
- Fixed an issue in
- Remove tenants listing dashboard API and update
getTenantLoginMethodsInfo
dashboard API to remove querying core in loop and return only firstFactors.
- We now allow sign in/up even if the session user is conflicting with the current sign in/up (because of the email verification status)
- This makes use-cases where an secondary factor (i.e.: otp-email) is also used as a means of verification.
- Enable smooth switching between
useDynamicAccessTokenSigningKey
settings by allowing refresh calls to change the signing key type of a session - Added a core call cache that should reduce traffic to your SuperTokens core instances
- Refactored sign in/up API codes to reduce code duplication
- Added MFA related information to dashboard APIs
- Added a cache to reduce the number of requests made to the core. This can be disabled using the
disableCoreCallCache: true
, in the config. - Added new
overwriteSessionDuringSignInUp
configuration option to the Session recipe - Added new function:
checkCode
to Passwordless and ThirdPartyPasswordless recipes - Added new function:
verifyCredentials
to EmailPassword and ThirdPartyEmailPassword recipes - Added the
MultiFactorAuth
andTOTP
recipes. To start using them you'll need compatible versions:- Core>=8.0.0
- supertokens-node>=17.0.0
- supertokens-website>=18.0.0
- supertokens-web-js>=0.10.0
- supertokens-auth-react>=0.39.0
- Now only supporting CDI 5.0. Compatible with core version >= 8.0
- Account linking now takes the active session into account.
- Account linking now also happens in sign in function calls (instead of sign ups and sign in API calls)
- Fixed the typing of the
userContext
:- All functions now take
Record<string, any>
instead ofany
asuserContext
. This means that primitives (strings, numbers) are no longer allowed asuserContext
. - All functions overrides that take a
userContext
parameter now get a well typeduserContext
parameter ensuring that the right object is passed to the original implementation calls
- All functions now take
- Calling sign in/up APIs with a session will now skip creating a new session by default. This is overrideable through by passing
overwriteSessionDuringSignInUp: true
to the Session recipe config. - Added new support codes to sign in/up APIs. This means that there are new possible values coming from the default implementation for the
reason
strings ofSIGN_IN_NOT_ALLOWED
,SIGN_UP_NOT_ALLOWED
andSIGN_IN_UP_NOT_ALLOWED
responses. Session
recipe:- The sign out API new returns a 401 instead of 200 in case the input access token has expired or is missing.
AccountLinking
recipe:- Changed the signature of the following functions, each taking a new (optional)
session
parameter:createPrimaryUserIdOrLinkAccounts
isSignUpAllowed
isSignInAllowed
isEmailChangeAllowed
- Changed the signature of the
shouldDoAutomaticAccountLinking
callback: it now takes a new (optional) session parameter.
- Changed the signature of the following functions, each taking a new (optional)
EmailPassword
:- Changed the signature of the following overrideable functions:
signUp
- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- Takes a new (optional)
signIn
- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- Takes a new (optional)
- Changed the signature of overrideable APIs, adding a new (optional) session parameter:
signInPOST
signUpPOST
- Changed the signature of functions:
signUp
- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- Takes a new (optional)
signIn
- Takes a new (optional)
session
parameter - Can now return with `status: "LINKING_TO_SESSION_USER_FAILED"
- Takes a new (optional)
- Changed the signature of the following overrideable functions:
Multitenancy
:- Changed the signature of the following functions:
createOrUpdateTenant
: Added optionalfirstFactors
andrequiredSecondaryFactors
parameters.getTenant
: AddedfirstFactors
andrequiredSecondaryFactors
to the return typelistAllTenants
: AddedfirstFactors
andrequiredSecondaryFactors
to the returned tenants
- Changed the signature of the following overrideable functions:
createOrUpdateTenant
: Now gets optionalfirstFactors
andrequiredSecondaryFactors
in the input.getTenant
: AddedfirstFactors
andrequiredSecondaryFactors
to the return typelistAllTenants
: AddedfirstFactors
andrequiredSecondaryFactors
to the returned tenants
- Changed the signature of the overrideable apis:
loginMethodsGET
: Now returnsfirstFactors
- Changed the signature of the following functions:
Passwordless
:revokeCode
(and the related overrideable func) can now be called with eitherpreAuthSessionId
orcodeId
instead of onlycodeId
.- Added new email and sms type for MFA
- Changed the signature of the following functions:
signInUp
,createCode
: Takes a new (optional)session
parameterconsumeCode
:- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- It now also returns
consumedDevice
if the code was successfully consumed
- Takes a new (optional)
- Changed the signature of the following overrideable functions:
createCode
: Takes a new (optional)session
parameterconsumeCode
:- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- It now also returns
consumedDevice
if the code was successfully consumed
- Takes a new (optional)
- Changed the signature of overrideable APIs, adding a new (optional) session parameter:
createCodePOST
resendCodePOST
consumeCodePOST
- Session claims:
- The
build
function and thefetchValue
callback of session claims now take a newcurrentPayload
param.- This affects built-in claims:
EmailVerificationClaim
,UserRoleClaim
,PermissionClaim
,AllowedDomainsClaim
. - This will affect all custom claims as well built on our base classes.
- This affects built-in claims:
- The
ThirdParty
:- Changed the signature of the following functions:
manuallyCreateOrUpdateUser
:- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- Takes a new (optional)
- Changed the signature of the following overrideable functions:
signInUp
:- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- Takes a new (optional)
manuallyCreateOrUpdateUser
- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- Takes a new (optional)
- Changed the signature of overrideable APIs, adding a new (optional) session parameter:
signInUpPOST
- Changed the signature of the following functions:
ThirdPartyEmailPassword
:- Added new function:
emailPasswordVerifyCredentials
- Changed the signature of the following functions:
thirdPartyManuallyCreateOrUpdateUser
:- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- Takes a new (optional)
emailPasswordSignUp
- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- Takes a new (optional)
- Changed the signature of the following overrideable functions:
thirdPartySignInUp
:- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- Takes a new (optional)
thirdPartyManuallyCreateOrUpdateUser
- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- Takes a new (optional)
emailPasswordSignUp
- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- Takes a new (optional)
- Changed the signature of overrideable APIs, adding a new (optional) session parameter:
emailPasswordSignInPOST
emailPasswordSignUpPOST
thirdPartySignInUpPOST
- Added new function:
ThirdPartyPasswordless
:revokeCode
(and the related overrideable func) can now be called with eitherpreAuthSessionId
orcodeId
instead of onlycodeId
.- Changed the signature of the following functions:
thirdPartyManuallyCreateOrUpdateUser
:- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- Takes a new (optional)
passwordlessSignInUp
,createCode
: Takes a new (optional)session
parameterconsumeCode
:- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- It now also returns
consumedDevice
if the code was successfully consumed
- Takes a new (optional)
- Changed the signature of the following overrideable functions:
thirdPartySignInUp
:- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- Takes a new (optional)
thirdPartyManuallyCreateOrUpdateUser
- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- Takes a new (optional)
createCode
: Takes a new (optional)session
parameterconsumeCode
:- Takes a new (optional)
session
parameter - Can now return with
status: "LINKING_TO_SESSION_USER_FAILED"
- It now also returns
consumedDevice
if the code was successfully consumed
- Takes a new (optional)
- Changed the signature of overrideable APIs, adding a new (optional) session parameter:
thirdPartySignInUpPOST
createCodePOST
resendCodePOST
consumeCodePOST
If you use the userContext
or tenantId
parameters passed to shouldDoAutomaticAccountLinking
, please update your implementation to account for the new parameter.
Before:
AccountLinking.init({
shouldDoAutomaticAccountLinking: async (newAccountInfo, user, tenantId, userContext) => {
return {
shouldAutomaticallyLink: true,
shouldRequireVerification: true,
};
},
});
After:
AccountLinking.init({
shouldDoAutomaticAccountLinking: async (newAccountInfo, user, session, tenantId, userContext) => {
return {
shouldAutomaticallyLink: true,
shouldRequireVerification: true,
};
},
});
We've added a new optional session
parameter to many function calls. In all cases, these have been added as the last parameter before userContext
, so this should only affect you if you are using that. You only need to pass a session as a parameter if you are using account linking and want to try and link the user signing in/up to the session user.
You can get the necessary session object using verifySession
in an API call.
Here we use the example of EmailPassword.signIn
but this fits other functions with changed signatures.
Before:
const signInResp = await EmailPassword.signIn("public", "[email protected]", "testpw", { myContextVar: true });
After:
const signInResp = await EmailPassword.signIn("public", "[email protected]", "testpw", undefined, { myContextVar: true });
If you use the userContext
parameter passed to fetchValue
, please update your implementation to account for the new parameter.
Before:
const boolClaim = new BooleanClaim({
key: "asdf",
fetchValue: (userId, recipeUserId, tenantId, userContext) => {
return userContext.claimValue;
},
});
After:
const boolClaim = new BooleanClaim({
key: "asdf",
fetchValue: (userId, recipeUserId, tenantId, currentPayload, userContext) => {
return userContext.claimValue;
},
});
If you were using the build
function for custom or built-in session claims, you should update the call signature to also pass the new parameter.
Before:
Session.init({
override: {
functions: (originalImplementation) => {
return {
...originalImplementation,
createNewSession: async function (input) {
input.accessTokenPayload = {
...input.accessTokenPayload,
...(await UserRoleClaim.build(
input.userId,
input.recipeUserId,
input.tenantId,
input.userContext
)),
};
return originalImplementation.createNewSession(input);
},
};
},
},
});
After:
Session.init({
override: {
functions: (originalImplementation) => {
return {
...originalImplementation,
createNewSession: async function (input) {
input.accessTokenPayload = {
...input.accessTokenPayload,
...(await UserRoleClaim.build(
input.userId,
input.recipeUserId,
input.tenantId,
input.accessTokenPayload,
input.userContext
)),
};
return originalImplementation.createNewSession(input);
},
};
},
},
});
Since now sign in/up APIs and functions can be called with a session (e.g.: during MFA flows), you may need to add an extra check to your overrides to account for that:
Before:
// While this example uses Passwordless, all recipes require a very similar change
Passwordless.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: {
functions: (originalImplementation) => {
return {
...originalImplementation,
consumeCode: async (input) => {
// First we call the original implementation of consumeCode.
let response = await originalImplementation.consumeCode(input);
// Post sign up response, we check if it was successful
if (response.status === "OK") {
if (response.createdNewRecipeUser && response.user.loginMethods.length === 1) {
// TODO: post sign up logic
} else {
// TODO: post sign in logic
}
}
return response;
}
}
}
}
}),
After:
// While this example uses Passwordless, all recipes require a very similar change
Passwordless.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: {
functions: (originalImplementation) => {
return {
...originalImplementation,
consumeCode: async (input) => {
// First we call the original implementation of consumeCode.
let response = await originalImplementation.consumeCode(input);
// Post sign up response, we check if it was successful
if (response.status === "OK") {
if (input.session === undefined) {
if (response.createdNewRecipeUser && response.user.loginMethods.length === 1) {
// TODO: post sign up logic
} else {
// TODO: post sign in logic
}
}
}
return response;
}
}
}
}
}),
Sign in/up APIs and functions will now attempt to link the authenticating user to the session user if a session is available (depending on AccountLinking settings). You can disable this and get the old behaviour by:
Before:
// While this example uses Passwordless, all recipes require a very similar change
Passwordless.init({
contactMethod: "EMAIL", // This example will work with any contactMethod
flowType: "USER_INPUT_CODE_AND_MAGIC_LINK", // This example will work with any flowType
}),
After:
// While this example uses Passwordless, all recipes require a very similar change
Passwordless.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: {
functions: (originalImplementation) => {
return {
...originalImplementation,
consumeCode: async (input) => {
input.session = undefined;
return originalImplementation.consumeCode(input);
}
}
}
}
}),
- Adds a user friendly error screen that provides helpful information regarding Content Security Policy (CSP) issues..
- Fixes dashboard URI path. Now it returns the complete user given path instead of just the normalized connectionURI domain.
createNewSession
now defaults to the value of thest-auth-mode
header (if available) if the configuredgetTokenTransferMethod
returnsany
.
- Fixes type output of
resetPasswordUsingToken
in emailpassword and thirdpartyemailpassword recipe to not include statuses that happen based on email change.
- Add session util functions
withSession
,getSSRSession
andwithPreParsedRequestResponse
for Next.js App directory. - Previously, the custom framework's
errorHandler
callback function was invoked only upon encountering an error. This behavior has been rectified, and now the callback is invoked in both error and success cases. - Added user creation apis on dashboard recipe to create Emailpassword and Passwordless recipe users.
- Fix App dir support by removing the import of the "http" module
- Adds facebook user data by checking the scopes provided in the config
- Adds
userContext
input to thevalidate
function in form fields. You can use this to fetch the request object from theuserContext
, read the request body, and then read the other form fields from there. If doing so, keep in mind that for the email and password validators, the request object may not always be available in thevalidate
function, and even if it's available, it may not have the request body of the sign up API since thevalidate
functions are also called from other operations (like in password reset API). For custom form fields that you have added to the sign up API, the request object will always be there in theuserContext
. - Fixes support for the custom framework on node 16 by optionally using an implementation of the Headers class (from
node-fetch
)
- CI/CD changes
- Fixes connectionURI domain normalisation.
- Fixes typing of
verifySession
adding generic to extend the fastify base request.
- Fixes issue with LinkedIn OAuth (#751)
- Fixes implementation of
getBackwardsCompatibleUserInfo
to not throw an error in case of session and user id mismatch.
- Removed dependency on the
crypto
library to enable Apple OAuth usage in Cloudflare Workers.
- Added User roles and permissions feature to dashboard recipe.
- Fixes issue with
passwordReset
in emailpassword recipe for custom frameworks (#746)
- Fixes issue with
createResetPasswordLink
andsendResetPasswordEmail
in thirdpartyemailpassword recipe.
- Added
networkInterceptor
to theTypeInput
config.- This can be used to capture/modify all the HTTP requests sent to the core.
- Closes the issue - supertokens/supertokens-core#865
- Added
debug
property toTypeInput
. When set totrue
, it will enable debug logs.
- Fixes an issue where sometimes the
Access-Control-Expose-Headers
header value would contain duplicates
- Tests
null
values inProviderConfig
saved in core
getUsersNewestFirst
andgetUsersOldestFirst
will now properly filter users by tenantId.- Fixes issue with missed email verification claim update that caused the frontend pre built UI to call the email verify API multiple times.
- Handle AWS Public URLs (ending with
.amazonaws.com
) separately while extracting TLDs for SameSite attribute.
- Adds support for configuring multiple frontend domains to be used with the same backend
- Added a new
origin
property toappInfo
, this can be configured to be a function which allows you to conditionally return the value of the frontend domain. This property will replacewebsiteDomain
in a future release ofsupertokens-node
websiteDomain
insideappInfo
is now optional. Usingorigin
is recommended over usingwebsiteDomain
. This is not a breaking change and usingwebsiteDomain
will continue to work- Added a "custom" framework you can use in framework normally not supported by our SDK
- Added a next13 app router compatible request handler.
- Fixed an issue where calling signinup for thirdparty recipe would result in a "clone is not a function" error
- Using built-in fetch whenever available instead of cross-fetch
- Improved edge-function support
- Slight refactors logic to code for social providers to make it consistent across all providers
- Added
validateAccessToken
to the configuration for social login providers, this function allows you to verify the access token returned by the social provider. If you are using Github as a provider, there is a default implmentation provided for this function.
- Added
twitter
as a built-in thirdparty provider
With this release, we are introducing a new AccountLinking recipe, this will let you:
- link accounts automatically,
- implement manual account linking flows.
Check our guide for more information.
To use this you'll need compatible versions:
- Core>=7.0.0
- supertokens-node>=16.0.0 (support is pending in other backend SDKs)
- supertokens-website>=17.0.3
- supertokens-web-js>=0.8.0
- supertokens-auth-react>=0.35.0
In this release, we've removed the recipes specific user types and instead introduced a new User
class to support the "Primary user" concept introduced by account linking
- The new
User
class now provides the same interface for all recipes. - It contains an
isPrimary
field that you can use to differentiate between primary and recipe users - The
loginMethods
array contains objects that covers all props of the old (recipe specific) user types, with the exception of the id. Please check the migration section below to get the exact mapping between old and new props. - Non-primary users:
- The
loginMethods
array should contain exactly 1 element. user.id
will be the same asuser.loginMethods[0].recipeUserId.getAsString()
.user.id
will change if it is linked to another user.- They can become a primary user if, and only if there are no other primary users with the same email, third party info or phone number as this user across all the tenants that this user is a part of.
- The
- Primary users
- The
loginMethods
array can have 1 or more elements, each corresponding to a single recipe user. user.id
will not change even if other users are linked to it.- Other non-primary users can be linked to it. The user ID of the linked accounts will now be the primary users ID.
- The
- Check here for more information about differences between primary and recipe users.
Because of account linking we've introduced a new Primary user concept (see above). In most cases, you should only use the primary user id (user.id
or session.getUserId()
) if you are associating data to users. Still, in some cases you need to specifically refer to a login method, which is covered by the new RecipeUserId
class:
- You can get it:
- From a session by:
session.getRecipeUserId()
. - By finding the appropriate entry in the
loginMethods
array of aUser
object (see above):user.loginMethods[0].recipeUserId
.
- From a session by:
- It wraps a simple string value that you can get by calling
recipeUserId.getAsString()
. - We've introduced it to differentiate between primary and recipe user ids in our APIs on a type level.
- Check here for more information.
-
Now only supporting CDI 4.0. Compatible with core version >= 7.0
-
Now supporting FDI 1.18
-
Removed the recipe specific
User
type, now all functions are using the new genericUser
type.- Check here for more information.
-
The
build
function and thefetchValue
callback of session claims now take a newrecipeUserId
param.- This affects built-in claims:
EmailVerificationClaim
,UserRoleClaim
,PermissionClaim
,AllowedDomainsClaim
. - This will affect all custom claims as well built on our base classes.
- This affects built-in claims:
-
Now ignoring protected props in the payload in
createNewSession
andcreateNewSessionWithoutRequestResponse
-
createdNewUser
has been renamed tocreatedNewRecipeUser
in sign up related APIs and functions -
EmailPassword:
- removed
getUserById
,getUserByEmail
. You should usesupertokens.getUser
, andsupertokens. listUsersByAccountInfo
instead - added
consumePasswordResetToken
. This function allows the consumption of the reset password token without changing the password. It will return OK if the token was valid. - added an overrideable
createNewRecipeUser
function that is called during sign up and password reset flow (in case a new email password user is being created on the fly). This is mostly for internal use. recipeUserId
is added to the input ofgetContent
of the email delivery configemail
was added to the input ofcreateResetPasswordToken
,sendResetPasswordEmail
,createResetPasswordLink
updateEmailOrPassword
:- now takes
recipeUserId
instead ofuserId
- can return the new
EMAIL_CHANGE_NOT_ALLOWED_ERROR
status
- now takes
signIn
:- returns new
recipeUserId
prop in thestatus: OK
case
- returns new
signUp
:- returns new
recipeUserId
prop in thestatus: OK
case
- returns new
resetPasswordUsingToken
:- removed from the recipe interface, making it no longer overrideable (directly)
- the related function in the index files now call
consumePasswordResetToken
andupdateEmailOrPassword
- any necessary behaviour changes can be achieved by overriding those two function instead
signInPOST
:- can return status
SIGN_IN_NOT_ALLOWED
- can return status
signUpPOST
:- can return status
SIGN_UP_NOT_ALLOWED
- can return status
generatePasswordResetTokenPOST
:- can now return
PASSWORD_RESET_NOT_ALLOWED
- can now return
passwordResetPOST
:- now returns the
user
and theemail
whose password was reset - can now return
PASSWORD_POLICY_VIOLATED_ERROR
- now returns the
- removed
-
EmailVerification:
createEmailVerificationToken
,createEmailVerificationLink
,isEmailVerified
,revokeEmailVerificationTokens
,unverifyEmail
:- now takes
recipeUserId
instead ofuserId
- now takes
sendEmailVerificationEmail
:- now takes an additional
recipeUserId
parameter
- now takes an additional
verifyEmailUsingToken
:- now takes a new
attemptAccountLinking
parameter - returns the
recipeUserId
instead ofid
- now takes a new
sendEmail
now requires a newrecipeUserId
as part of the user infogetEmailForUserId
config option was renamed togetEmailForRecipeUserId
verifyEmailPOST
,generateEmailVerifyTokenPOST
: returns an optionalnewSession
in case the current user session needs to be updated
-
Passwordless:
- removed
getUserById
,getUserByEmail
,getUserByPhoneNumber
updateUser
:- now takes
recipeUserId
instead ofuserId
- can return
"EMAIL_CHANGE_NOT_ALLOWED_ERROR
andPHONE_NUMBER_CHANGE_NOT_ALLOWED_ERROR
statuses
- now takes
createCodePOST
andconsumeCodePOST
can now returnSIGN_IN_UP_NOT_ALLOWED
- removed
-
Session:
- access tokens and session objects now contain the recipe user id
- Support for new access token version
recipeUserId
is now added to the payload of theTOKEN_THEFT_DETECTED
errorcreateNewSession
: now takesrecipeUserId
instead ofuserId
- Removed
validateClaimsInJWTPayload
revokeAllSessionsForUser
now takes an optionalrevokeSessionsForLinkedAccounts
paramgetAllSessionHandlesForUser
now takes an optionalfetchSessionsForAllLinkedAccounts
paramregenerateAccessToken
return value now includesrecipeUserId
getGlobalClaimValidators
andvalidateClaims
now get a newrecipeUserId
param- Added
getRecipeUserId
to the session class
-
ThirdParty:
- The
signInUp
override:- gets a new
isVerified
param - can return new status:
SIGN_IN_UP_NOT_ALLOWED
- gets a new
manuallyCreateOrUpdateUser
:- gets a new
isVerified
param - can return new statuses:
EMAIL_CHANGE_NOT_ALLOWED_ERROR
,SIGN_IN_UP_NOT_ALLOWED
- gets a new
- Removed
getUserByThirdPartyInfo
,getUsersByEmail
,getUserById
signInUpPOST
can now returnSIGN_IN_UP_NOT_ALLOWED
- The
-
ThirdPartyEmailPassword:
- Removed
getUserByThirdPartyInfo
,getUsersByEmail
,getUserById
thirdPartyManuallyCreateOrUpdateUser
:- now get a new
isVerified
param - can return new statuses:
EMAIL_CHANGE_NOT_ALLOWED_ERROR
,SIGN_IN_UP_NOT_ALLOWED
- now get a new
- The
thirdPartySignInUp
override:- now get a new
isVerified
param - can return new status:
SIGN_IN_UP_NOT_ALLOWED
- now get a new
email
was added to the input ofcreateResetPasswordToken
,sendResetPasswordEmail
,createResetPasswordLink
- added an overrideable
createNewEmailPasswordRecipeUser
function that is called during email password sign up and in the “invitation link” flow - added
consumePasswordResetToken
updateEmailOrPassword
:- now takes
recipeUserId
instead ofuserId
- can return the new
EMAIL_CHANGE_NOT_ALLOWED_ERROR
status
- now takes
resetPasswordUsingToken
:- removed from the recipe interface, making it no longer overrideable (directly)
- the related function in the index files now call
consumePasswordResetToken
andupdateEmailOrPassword
- any necessary behaviour changes can be achieved by overriding those two function instead
- added an overrideable
createNewEmailPasswordRecipeUser
function that is called during sign up and in the “invitation link” flow emailPasswordSignIn
:- returns new
recipeUserId
prop in thestatus: OK
case
- returns new
emailPasswordSignUp
:- returns new
recipeUserId
prop in thestatus: OK
case
- returns new
emailPasswordSignInPOST
:- can return status
SIGN_IN_NOT_ALLOWED
- can return status
emailPasswordSignUpPOST
:- can return status
SIGN_UP_NOT_ALLOWED
- can return status
generatePasswordResetTokenPOST
:- can now return
PASSWORD_RESET_NOT_ALLOWED
- can now return
passwordResetPOST
:- now returns the
user
and theemail
whose password was reset - can now return
PASSWORD_POLICY_VIOLATED_ERROR
- now returns the
thirdPartySignInUpPOST
can now returnSIGN_IN_UP_NOT_ALLOWED
- Removed
-
ThirdPartyPasswordless:
- Removed
getUserByThirdPartyInfo
,getUsersByEmail
,getUserByPhoneNumber
,getUserById
thirdPartyManuallyCreateOrUpdateUser
:- gets a new
isVerified
param - can return new statuses:
EMAIL_CHANGE_NOT_ALLOWED_ERROR
,SIGN_IN_UP_NOT_ALLOWED
- gets a new
- The
thirdPartySignInUp
override:- gets a new
isVerified
param - can return new status:
SIGN_IN_UP_NOT_ALLOWED
- gets a new
updatePasswordlessUser
:- now takes
recipeUserId
instead ofuserId
- can return
"EMAIL_CHANGE_NOT_ALLOWED_ERROR
andPHONE_NUMBER_CHANGE_NOT_ALLOWED_ERROR
statuses
- now takes
thirdPartySignInUpPOST
can now returnSIGN_IN_UP_NOT_ALLOWED
createCodePOST
andconsumeCodePOST
can now returnSIGN_IN_UP_NOT_ALLOWED
- Removed
-
Multitenancy:
associateUserToTenant
can now returnASSOCIATION_NOT_ALLOWED_ERROR
associateUserToTenant
anddisassociateUserFromTenant
now takeRecipeUserId
instead of a string user id
- Added
RecipeUserId
and a genericUser
class - Added
getUser
,listUsersByAccountInfo
,convertToRecipeUserId
to the main exports - Updated compilation target of typescript to ES2017 to make debugging easier.
- Added account-linking recipe
We've added a generic User
class instead of the old recipe specific ones. The mapping of old props to new in case you are not using account-linking:
user.id
staysuser.id
(oruser.loginMethods[0].recipeUserId
in case you needRecipeUserId
)user.email
becomesuser.emails[0]
user.phoneNumber
becomesuser.phoneNumbers[0]
user.thirdParty
becomesuser.thirdParty[0]
user.timeJoined
is stilluser.timeJoined
user.tenantIds
is stilluser.tenantIds
Some functions now require you to pass a RecipeUserId
instead of a string user id. If you are using our auth recipes, you can find the recipeUserId as: user.loginMethods[0].recipeUserId
(you'll need to worry about selecting the right login method after enabling account linking). Alternatively, if you already have a string user id you can convert it to a RecipeUserId
using supertokens.convertToRecipeUserId(userIdString)
- In the passwordless consumeCode / social login signinup APIs, you can check if a user signed up by:
// Here res refers to the result the function/api functions mentioned above.
const isNewUser = res.createdNewRecipeUser && res.user.loginMethods.length === 1;
- In the emailpassword sign up API, you can check if a user signed up by:
const isNewUser = res.user.loginMethods.length === 1;
- We recommend that you check if the email change of a user is allowed, before calling the update function
- Check here for more information
import {isEmailChangeAllowed} from "supertokens-node/recipe/accountlinking";
/// ...
app.post("/change-email", verifySession(), async (req: SessionRequest, res: express.Response) => {
let session = req.session!;
let email = req.body.email;
// ...
if (!(await isEmailChangeAllowed(session.getRecipeUserId(), email, false))) {
// this can come here if you have enabled the account linking feature, and
// if there is a security risk in changing this user's email.
}
// Update the email
let resp = await ThirdPartyEmailPassword.updateEmailOrPassword({
recipeUserId: session.getRecipeUserId(),
email: email,
});
// ...
});
- Fixes an issue where the response for the JWKs API would contain additional properties
- The Dashboard recipe now accepts a new
admins
property which can be used to give Dashboard Users write privileges for the user dashboard.
- Dashboard APIs now return a status code
403
for all non-GET requests if the currently logged in Dashboard User is not listed in theadmins
array
- Improve edge function compatibility by removing our
raw-body
dependency.
- Added a
Cache-Control
header to/jwt/jwks.json
(getJWKSGET
) - Added
validityInSeconds
to the return value of the overrideablegetJWKS
function.- This can be used to control the
Cache-Control
header mentioned above. - It defaults to
60
or the value set in the cache-control header returned by the core - This is optional (so you are not required to update your overrides). Returning undefined means that the header is not set.
- This can be used to control the
- Fixes apple redirect
- Adds logic to retry network calls if the core returns status 429
- Fixes an issue where the user management dashboard would incorrectly show an email as unverified even if it was verified
- Passes missing
tenantId
to claim build function
- Added Multitenancy Recipe & always initialized by default.
- Adds Multitenancy support to all the recipes
- Added new Social login providers - LinkedIn
- Added new Multi-tenant SSO providers - Okta, Active Directory, Boxy SAML
- All APIs handled by Supertokens middleware can have an optional
tenantId
prefixed in the path. e.g. //signinup - Following recipe functions have been added:
EmailPassword.createResetPasswordLink
EmailPassword.sendResetPasswordEmail
EmailVerification.createEmailVerificationLink
EmailVerification.sendEmailVerificationEmail
ThirdParty.getProvider
ThirdPartyEmailPassword.thirdPartyGetProvider
ThirdPartyEmailPassword.createResetPasswordLink
ThirdPartyEmailPassword.sendResetPasswordEmail
ThirdPartyPasswordless.thirdPartyGetProvider
ThirdPartyPasswordless.createResetPasswordLink
ThirdPartyPasswordless.sendResetPasswordEmail
- Only supporting FDI 1.17
- Core must be upgraded to 6.0
getUsersOldestFirst
&getUsersNewestFirst
has mandatory parametertenantId
. Pass'public'
if not using multitenancy.- Added mandatory field
tenantId
toEmailDeliveryInterface
andSmsDeliveryInterface
. Pass'public'
if not using multitenancy. - Removed deprecated config
createAndSendCustomEmail
andcreateAndSendCustomTextMessage
. - EmailPassword recipe changes:
- Added mandatory
tenantId
field toTypeEmailPasswordPasswordResetEmailDeliveryInput
- Removed
resetPasswordUsingTokenFeature
fromTypeInput
- Added
tenantId
param tovalidate
function inTypeInputFormField
- Added mandatory
tenantId
as first parameter to the following recipe index functions:signUp
signIn
getUserByEmail
createResetPasswordToken
resetPasswordUsingToken
- Added mandatory
tenantId
in the input for the following recipe interface functions. If any of these functions are overridden, they need to be updated accordingly:signUp
signIn
getUserByEmail
createResetPasswordToken
resetPasswordUsingToken
updateEmailOrPassword
- Added mandatory
tenantId
in the input for the following API interface functions. If any of these functions are overridden, they need to be updated accordingly:emailExistsGET
generatePasswordResetTokenPOST
passwordResetPOST
signInPOST
signUpPOST
- Added mandatory
- EmailVerification recipe changes:
- Added mandatory
tenantId
field toTypeEmailVerificationEmailDeliveryInput
- Added mandatory
tenantId
as first parameter to the following recipe index functions:createEmailVerificationToken
verifyEmailUsingToken
revokeEmailVerificationTokens
- Added mandatory
tenantId
in the input for the following recipe interface functions. If any of these functions are overridden, they need to be updated accordingly:createEmailVerificationToken
verifyEmailUsingToken
revokeEmailVerificationTokens
- Added mandatory
tenantId
in the input for the following API interface functions. If any of these functions are overridden, they need to be updated accordingly:verifyEmailPOST
- Added mandatory
- Passwordless recipe changes:
- Added
tenantId
param tovalidateEmailAddress
,validatePhoneNumber
andgetCustomUserInputCode
functions inTypeInput
- Added mandatory
tenantId
field toTypePasswordlessEmailDeliveryInput
andTypePasswordlessSmsDeliveryInput
- Added mandatory
tenantId
in the input to the following recipe index functions:createCode
createNewCodeForDevice
getUserByEmail
getUserByPhoneNumber
updateUser
revokeCode
listCodesByEmail
listCodesByPhoneNumber
listCodesByDeviceId
listCodesByPreAuthSessionId
signInUp
- Added mandatory
tenantId
in the input for the following recipe interface functions. If any of these functions are overridden, they need to be updated accordingly:createCode
createNewCodeForDevice
consumeCode
getUserByEmail
getUserByPhoneNumber
revokeAllCodes
revokeCode
listCodesByEmail
listCodesByPhoneNumber
listCodesByDeviceId
listCodesByPreAuthSessionId
- Added mandatory
tenantId
in the input for the following API interface functions. If any of these functions are overridden, they need to be updated accordingly:createCodePOST
resendCodePOST
consumeCodePOST
emailExistsGET
phoneNumberExistsGET
- Added
- ThirdParty recipe changes
- The providers array in
signInUpFeature
accepts[]ProviderInput
instead of[]TypeProvider
. TypeProvider interface is re-written. Refer migration section for more info. - Removed
signInUp
and addedmanuallyCreateOrUpdateUser
instead in the recipe index functions. - Added
manuallyCreateOrUpdateUser
to recipe interface which is being called by the function mentioned above.manuallyCreateOrUpdateUser
recipe interface function should not be overridden as it is not going to be called by the SDK in the sign in/up flow.signInUp
recipe interface functions is not removed and is being used by the sign in/up flow.
- Added mandatory
tenantId
as first parameter to the following recipe index functions:getUsersByEmail
getUserByThirdPartyInfo
- Added mandatory
tenantId
in the input for the following recipe interface functions. If any of these functions are overridden, they need to be updated accordingly:getUsersByEmail
getUserByThirdPartyInfo
signInUp
- Added mandatory
tenantId
in the input for the following API interface functions. If any of these functions are overridden, they need to be updated accordingly:authorisationUrlGET
signInUpPOST
- Updated
signInUp
recipe interface function in thirdparty with new parameters:oAuthTokens
- contains all the tokens (access_token, id_token, etc.) as returned by the providerrawUserInfoFromProvider
- contains all the user profile info as returned by the provider
- Updated
authorisationUrlGET
API- Changed: Doesn't accept
clientId
anymore and acceptsclientType
instead to determine the matching config - Added: optional
pkceCodeVerifier
in the response, to support PKCE
- Changed: Doesn't accept
- Updated
signInUpPOST
API- Removed:
clientId
,redirectURI
,authCodeResponse
andcode
from the input - Instead,
- accepts
clientType
to determine the matching config - One of redirectURIInfo (for code flow) or oAuthTokens (for token flow) is required
- accepts
- Removed:
- Updated
appleRedirectHandlerPOST
- to accept all the form fields instead of just the code
- to use redirect URI encoded in the
state
parameter instead of using the websiteDomain config. - to use HTTP 303 instead of javascript based redirection.
- The providers array in
- Session recipe changes
- Added mandatory
tenantId
as first parameter to the following recipe index functions:createNewSession
createNewSessionWithoutRequestResponse
validateClaimsInJWTPayload
- Added mandatory
tenantId
in the input for the following recipe interface functions. If any of these functions are overridden, they need to be updated accordingly:createNewSession
getGlobalClaimValidators
- Added
tenantId
andrevokeAcrossAllTenants
params torevokeAllSessionsForUser
in the recipe interface. - Added
tenantId
andfetchAcrossAllTenants
params togetAllSessionHandlesForUser
in the recipe interface. - Added
getTenantId
function toSessionContainerInterface
- Added
tenantId
tofetchValue
function inPrimitiveClaim
,PrimitiveArrayClaim
.
- Added mandatory
- UserRoles recipe changes
- Added mandatory
tenantId
as first parameter to the following recipe index functions:addRoleToUser
removeUserRole
getRolesForUser
getUsersThatHaveRole
- Added mandatory
tenantId
in the input for the following recipe interface functions. If any of these functions are overridden, they need to be updated accordingly:addRoleToUser
removeUserRole
getRolesForUser
getRolesForUser
- Added mandatory
- Similar changes in combination recipes (thirdpartyemailpassword and thirdpartypasswordless) have been made
- Even if thirdpartyemailpassword and thirdpartpasswordless recipes do not have a providers array as an input, they will still expose the third party recipe routes to the frontend.
- Returns 400 status code in emailpassword APIs if the input email or password are not of type string.
- Recipe function changes:
- Added optional
tenantIdForPasswordPolicy
param toEmailPassword.updateEmailOrPassword
,ThirdPartyEmailPassword.updateEmailOrPassword
- Added optional param
tenantId
toSession.revokeAllSessionsForUser
. If tenantId is undefined, sessions are revoked across all tenants - Added optional param
tenantId
toSession.getAllSessionHandlesForUser
. If tenantId is undefined, sessions handles across all tenants are returned
- Added optional
- Adds optional param
tenantId
togetUserCount
which returns total count across all tenants if not passed. - Adds protected prop
tId
to the accessToken payload - Adds
includesAny
claim validator toPrimitiveArrayClaim
- Fixed an issue where certain Dashboard API routes would return a 404 for Hapi
-
To call any recipe function that has
tenantId
added to it, pass'public
'Before:
EmailPassword.signUp("[email protected]", "password");
After:
EmailPassword.signUp("public", "[email protected]", "password");
-
Input for provider array change as follows:
Before:
let googleProvider = thirdParty.Google({ clientID: "...", clientSecret: "...", });
After:
let googleProvider = { config: { thirdPartyId: "google", clients: [{ clientId: "...", clientSecret: "..." }], }, };
-
Single instance with multiple clients of each provider instead of multiple instances of them. Also use
clientType
to differentiate them.clientType
passed from the frontend will be used to determine the right config.isDefault
option has been removed andclientType
is expected to be passed when there are more than one client. If there is only one client,clientType
is optional and will be used by default.Before:
let providers = [ thirdParty.Google({ isDefault: true, clientID: "clientid1", clientSecret: "...", }), thirdParty.Google({ clientID: "clientid2", clientSecret: "...", }), ];
After:
let providers = [ { config: { thirdPartyId: "google", clients: [ { clientType: "web", clientId: "clientid1", clientSecret: "..." }, { clientType: "mobile", clientId: "clientid2", clientSecret: "..." }, ], }, }, ];
-
Change in the implementation of custom providers
- All config is part of
ProviderInput
- To provide implementation for
getProfileInfo
- either use
userInfoEndpoint
,userInfoEndpointQueryParams
anduserInfoMap
to fetch the user info from the provider - or specify custom implementation in an override for
getUserInfo
(override example in the next section)
- either use
Before:
let customProvider = { id: "custom", get: (redirectURI, authCodeFromRequest) => { return { accessTokenAPI: { url: "...", params: {}, }, authorisationRedirect: { url: "...", params: {}, }, getClientId: () => { return "..."; }, getProfileInfo: async (accessTokenAPIResponse) => { return { id: "...", email: { id: "...", isVerified: true, }, }; }, }; }, };
After:
let customProvider = { config: { thirdPartyId: "custom", clients: [ { clientId: "...", clientSecret: "...", }, ], authorizationEndpoint: "...", authorizationEndpointQueryParams: {}, tokenEndpoint: "...", tokenEndpointBodyParams: {}, userInfoEndpoint: "...", userInfoEndpointQueryParams: {}, userInfoMap: { fromUserInfoAPI: { userId: "id", email: "email", emailVerified: "email_verified", }, }, }, };
Also, if the custom provider supports openid, it can automatically discover the endpoints
let customProvider = { config: { thirdPartyId: "custom", clients: [ { clientId: "...", clientSecret: "...", }, ], oidcDiscoveryEndpoint: "...", userInfoMap: { fromUserInfoAPI: { userId: "id", email: "email", emailVerified: "email_verified", }, }, }, };
Note: The SDK will fetch the oauth2 endpoints from the provider's OIDC discovery endpoint. No need to
/.well-known/openid-configuration
to theoidcDiscoveryEndpoint
config. For eg. ifoidcDiscoveryEndpoint
is set to"https://accounts.google.com/"
, the SDK will fetch the endpoints from"https://accounts.google.com/.well-known/openid-configuration"
- All config is part of
-
Any of the functions in the TypeProvider can be overridden for custom implementation
- Overrides can do the following:
- update params, headers dynamically for the authorization redirect url or in the exchange of code to tokens
- add custom logic to exchange code to tokens
- add custom logic to get the user info
let customProvider = { config: { thirdPartyId: "custom", clients: [ { clientId: "...", clientSecret: "...", }, ], oidcDiscoveryEndpoint: "...", userInfoMap: { fromUserInfoAPI: { userId: "id", email: "email", emailVerified: "email_verified", }, }, }, override: (originalImplementation) => { return { ...originalImplementation, getAuthorisationRedirectURL: async (input) => { let result = await originalImplementation.getAuthorisationRedirectURL(input); // ... return result; }, exchangeAuthCodeForOAuthTokens: async (input) => { let result = await originalImplementation.exchangeAuthCodeForOAuthTokens(input); // ... return result; }, getUserInfo: async (input) => { let result = await originalImplementation.getUserInfo(input); // ... return result; }, }; }, };
- Overrides can do the following:
-
To get access token and raw user info from the provider, override the signInUp function
ThirdParty.init({ override: { functions: (oI) => { return { ...oI, signInUp: async (input) => { let result = await oI.signInUp(input); // result.oAuthTokens.access_token // result.oAuthTokens.id_token // result.rawUserInfoFromProvider.fromUserInfoAPI // result.rawUserInfoFromProvider.fromIdTokenPayload return result; }, }; }, }, });
-
Request body of thirdparty signinup API has changed
-
If using auth code:
Before:
{ "thirdPartyId": "...", "clientId": "...", "redirectURI": "...", // optional "code": "..." }
After:
{ "thirdPartyId": "...", "clientType": "...", "redirectURIInfo": { "redirectURIOnProviderDashboard": "...", // required "redirectURIQueryParams": { "code": "...", "state": "..." // ... all callback query params }, "pkceCodeVerifier": "..." // optional, use this if using PKCE flow } }
-
If using tokens:
Before:
{ "thirdPartyId": "...", "clientId": "...", "redirectURI": "...", "authCodeResponse": { "access_token": "...", // required "id_token": "..." } }
After:
{ "thirdPartyId": "...", "clientType": "...", "oAuthTokens": { "access_token": "...", // now optional "id_token": "..." // rest of the oAuthTokens as returned by the provider } }
-
- Compatible with Core>=6.0.0 (CDI 4.0)
- Compatible with frontend SDKs:
- Updated/replaced dependencies & refactored to be compatible with vercel edge runtimes.
- Now properly ignoring missing anti-csrf tokens in optional session validation
- Fixed email templates to fix an issue with styling on some email clients
- Minor internal refactors & additional tests
- Now assuming latest token version if the claim is missing from the header
- Make
verifySession
send the appropriate response instead of throwing (and sending 500) if session validation fails in koa, hapi and loopback (already happening in other frameworks).
- Adds additional debug logs whenever the SDK throws a
TRY_REFRESH_TOKEN
orUNAUTHORISED
error to make debugging easier
- Added a new
getRequestFromUserContext
function that can be used to read the original network request from the user context in overridden APIs and recipe functions
- Made the access token string optional in the overrideable
getSession
function - Moved checking if the access token is defined into the overrideable
getSession
function
- Fixes an issue where API key based login with dashboard would return invalid API key even if the entered API key was valid
- Added support for CDI version
2.21
- Dropped support for CDI version
2.8
-2.20
- Changed the interface and configuration of the Session recipe, see below for details. If you do not use the Session recipe directly and do not provide custom configuration, then no migration is necessary.
getAccessTokenPayload
will now return standard (sub
,iat
,exp
) claims and some SuperTokens specific claims along the user defined ones ingetAccessTokenPayload
.- Some claim names are now prohibited in the root level of the access token payload
- They are:
sub
,iat
,exp
,sessionHandle
,parentRefreshTokenHash1
,refreshTokenHash1
,antiCsrfToken
- If you used these in the root level of the access token payload, then you'll need to migrate your sessions or they will be logged out during the next refresh
- These props should be renamed (e.g., by adding a prefix) or moved inside an object in the access token payload
- You can migrate these sessions by updating their payload to match your new structure, by calling
mergeIntoAccessTokenPayload
- They are:
- New access tokens are valid JWTs now
- They can be used directly (i.e.: by calling
getAccessToken
on the session) if you need a JWT - The
jwt
prop in the access token payload is removed
- They can be used directly (i.e.: by calling
- Changed the Session recipe interface - createNewSession, getSession and refreshSession overrides now do not take response and request and return status instead of throwing
- Renamed
accessTokenPayload
tocustomClaimsInAccessTokenPayload
inSessionInformation
(the return value ofgetSessionInformation
). This reflects the fact that it doesn't contain some default claims (sub
,iat
, etc.)
- Added
useDynamicAccessTokenSigningKey
(defaults totrue
) option to the Session recipe config - Added
exposeAccessTokenToFrontendInCookieBasedAuth
(defaults tofalse
) option to the Session recipe config - JWT and OpenId related configuration has been removed from the Session recipe config. If necessary, they can be added by initializing the OpenId recipe before the Session recipe.
- Renamed
getSessionData
togetSessionDataFromDatabase
to clarify that it always hits the DB - Renamed
updateSessionData
toupdateSessionDataInDatabase
- Renamed
sessionData
tosessionDataInDatabase
inSessionInformation
and the input tocreateNewSession
- Added new
checkDatabase
param toverifySession
andgetSession
- Removed
status
fromgetJWKS
output (function & API) - Added new optional
useStaticSigningKey
param tocreateJWT
- Removed deprecated
updateAccessTokenPayload
andregenerateAccessToken
from the Session recipe interface - Removed
getAccessTokenLifeTimeMS
andgetRefreshTokenLifeTimeMS
functions
- The Session recipe now always initializes the OpenID recipe if it hasn't been initialized.
- Refactored how access token validation is done
- Removed the handshake call to improve start-up times
- Added support for new access token version
- Added optional password policy check in
updateEmailOrPassword
- Added
createNewSessionWithoutRequestResponse
,getSessionWithoutRequestResponse
,refreshSessionWithoutRequestResponse
to the Session recipe. - Added
getAllSessionTokensDangerously
to session objects (SessionContainerInterface
) - Added
attachToRequestResponse
to session objects (SessionContainerInterface
)
- You need to update the core version
- There are manual migration steps needed. Check out the core changelogs for more details.
- Add
exposeAccessTokenToFrontendInCookieBasedAuth: true
to the Session recipe config on the backend if you need to access the JWT on the frontend. - Choose a prop from the following list. We'll use
sub
in the code below, but you can replace it with another from the list if you used it in a custom access token payload.sub
iat
exp
sessionHandle
- On the frontend where you accessed the JWT before by:
(await Session.getAccessTokenPayloadSecurely()).jwt
update to:
let jwt = null;
const accessTokenPayload = await Session.getAccessTokenPayloadSecurely();
if (accessTokenPayload.sub !== undefined) {
jwt = await Session.getAccessToken();
} else {
// This branch is only required if there are valid access tokens created before the update
// It can be removed after the validity period ends
jwt = accessTokenPayload.jwt;
}
- On the backend if you accessed the JWT before by
session.getAccessTokenPayload().jwt
please update to:
let jwt = null;
const accessTokenPayload = await session.getAccessTokenPayload();
if (accessTokenPayload.sub !== undefined) {
jwt = await session.getAccessToken();
} else {
// This branch is only required if there are valid access tokens created before the update
// It can be removed after the validity period ends
jwt = accessTokenPayload.jwt;
}
- You can add an issuer claim to access tokens by overriding the
createNewSession
function in the session recipe init.- Check out https://supertokens.com/docs/passwordless/common-customizations/sessions/claims/access-token-payload#during-session-creation for more information
- You can add an issuer claim to JWTs created by the JWT recipe by passing the
iss
claim as part of the payload. - You can set the OpenId discovery configuration as follows:
Before:
import SuperTokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "...",
},
recipeList: [
Session.init({
jwt: {
enable: true,
issuer: "...",
},
}),
],
});
After:
import SuperTokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "...",
},
recipeList: [
Session.init({
getTokenTransferMethod: () => "header",
override: {
openIdFeature: {
functions: originalImplementation => ({
...originalImplementation,
getOpenIdDiscoveryConfiguration: async (input) => ({
issuer: "your issuer",
jwks_uri: "https://your.api.domain/auth/jwt/jwks.json",
status: "OK"
}),
})
}
}
});
],
});
Related functions/prop names have changes (sessionData
became sessionDataFromDatabase
):
- Renamed
getSessionData
togetSessionDataFromDatabase
to clarify that it always hits the DB - Renamed
updateSessionData
toupdateSessionDataInDatabase
- Renamed
sessionData
tosessionDataInDatabase
inSessionInformation
and the input tocreateNewSession
- You should now set
checkDatabase
to true in the verifySession params.
- You should now set
useDynamicAccessTokenSigningKey
in the Session recipe config.
- Update you application logic to rename those props (e.g., by adding a prefix)
- Update the session recipe config (in this example
sub
is the protected property we are updating by adding theapp
prefix):
Before:
Session.init({
override: {
functions: (oI) => ({
...oI,
createNewSession: async (input) => {
return oI.createNewSession({
...input,
accessTokenPayload: {
...input.accessTokenPayload,
sub: input.userId + "!!!",
},
});
},
}),
},
});
After:
Session.init({
override: {
functions: (oI) => ({
...oI,
getSession: async (input) => {
const result = await oI.getSession(input);
if (result) {
const origPayload = result.getAccessTokenPayload();
if (origPayload.appSub === undefined) {
await result.mergeIntoAccessTokenPayload({ appSub: origPayload.sub, sub: null });
}
}
return result;
},
createNewSession: async (input) => {
return oI.createNewSession({
...input,
accessTokenPayload: {
...input.accessTokenPayload,
appSub: input.userId + "!!!",
},
});
},
}),
},
});
This example uses getSession
, but the changes required for the other ones are very similar. Before:
Session.init({
override: {
functions: (oI) => ({
...oI,
getSession: async (input) => {
const req = input.req;
console.log(req);
try {
const session = await oI.getSession(input);
console.log(session);
return session;
} catch (error) {
console.log(error);
throw error;
}
},
}),
},
});
After:
Session.init({
override: {
functions: (oI) => ({
...oI,
getSession: async (input) => {
const req = input.userContext._default.request;
console.log(req);
const resp = await oI.getSession(input);
if (resp.status === "OK") {
console.log(resp.session);
} else {
console.log(resp.status);
console.log(resp.error);
}
return resp;
},
}),
},
});
- Added missing arguments from
getUsersNewestFirst
andgetUsersOldestFirst
- Adds new config to change the access token's path
- Modified email templates to make them render fine in gmail.
- Modified email templates to make them render fine in outlook.
- Adds APIs to enable search functionality to the dashboard recipe
- Adds a telemetry API to the dashboard recipe
- Updates the example app to also initialise the dashboard
- Login with bitbucket and gitlab (single tenant only)
- Fixed an issue where BaseRequest implmentations for frameworks such as AWS Lambda would not consider case sensitivity when fetching request headers
- Fixes an issue where dashboard recipe APIs would return 404 for Hapi
- Fixes an issue where importing recipes without importing the package index file would cause crashes
- The dashboard recipe is no longer intialised automatically
- Fixed request parsing issue during third-party (Apple) sign in in NextJS
- Refactor dashboard recipe to use auth mode instead of manually checking for api key
- Adds APIs and logic to the dashboard recipe to enable email password based login
- Package version update for twilio to ^4.7.2 and verify-apple-id-token to ^3.0.1
- Package typescript version changed to 4.2
- Email template updates
- The frontend SDK should be updated to a version supporting the header-based sessions!
- supertokens-auth-react: >= 0.31.0
- supertokens-web-js: >= 0.5.0
- supertokens-website: >= 16.0.0
- supertokens-react-native: >= 4.0.0
- supertokens-ios >= 0.2.0
- supertokens-android >= 0.3.0
- supertokens-flutter >= 0.1.0
createNewSession
now requires passing the request as well as the response.- This only requires a change if you manually created sessions (e.g.: during testing)
- There is a migration example added below. It uses express, but the same principle applies for other supported frameworks.
- Only supporting FDI 1.16
- Added support for authorizing requests using the
Authorization
header instead of cookies- Added
getTokenTransferMethod
config option - Check out https://supertokens.com/docs/thirdpartyemailpassword/common-customizations/sessions/token-transfer-method for more information
- Added
This example uses express, but the same principle applies for other supported frameworks.
Before:
const app = express();
app.post("/create", async (req, res) => {
await Session.createNewSession(res, "testing-userId", {}, {});
res.status(200).json({ message: true });
});
After the update:
const app = express();
app.post("/create", async (req, res) => {
await Session.createNewSession(req, res, "testing-userId", {}, {});
res.status(200).json({ message: true });
});
- Updates jsonwebtoken dependency to version 9.0.0 to fix vulnerability in it's
verify
function.
- Fixes Content-type header in AWS lambda framework
- Updates dashboard version
- Updates user GET API for the dashboard recipe
- Updates some dependencies cause of
npm audit
- Fixes issue where if sendEmail is overridden with a different email, it will reset that email.
- Fixed an issue with importing the wrong recipe in the dashboard APIs
- Adds APIs for user details to the dashboard recipe
- Updates dashboard version to 0.2
- Adds updating of session claims in email verification token generation API in case the session claims are outdated.
- Fixed mergeIntoAccessTokenPayload not updating the JWT payload
- Updated google token endpoint.
- Removed default defaultMaxAge from session claim base classes
- Added a 5 minute defaultMaxAge to UserRoleClaim, PermissionClaim and EmailVerificationClaim
- clear cookies logic refactored for unauthorised error response
- Properly rethrowing generic errors in email verification endpoints.
- Email verification endpoints will now clear the session if called by a deleted/unknown user
- Makes
SuperTokensError
extend the built-inError
class to fix serialization issues.
- Made the
email
parameter option inunverifyEmail
,revokeEmailVerificationTokens
,isEmailVerified
,verifyEmailUsingToken
,createEmailVerificationToken
of theEmailVerification
recipe.
- Support for FDI 1.15
- Added support for session claims with related interfaces and classes.
- Added
onInvalidClaim
optional error handler to send InvalidClaim error responses. - Added
INVALID_CLAIMS
toSessionErrors
. - Added
invalidClaimStatusCode
optional config to set the status code of InvalidClaim errors. - Added
overrideGlobalClaimValidators
to options ofgetSession
andverifySession
. - Added
mergeIntoAccessTokenPayload
to the Session recipe and session objects which should be preferred to the now deprecatedupdateAccessTokenPayload
. - Added
EmailVerificationClaim
,UserRoleClaim
andPermissionClaim
. These claims are now added to the access token payload by default by their respective recipes. - Added
assertClaims
,validateClaimsForSessionHandle
,validateClaimsInJWTPayload
to the Session recipe to support validation of the newly added claims. - Added
fetchAndSetClaim
,getClaimValue
,setClaimValue
andremoveClaim
to the Session recipe to manage claims. - Added
assertClaims
,fetchAndSetClaim
,getClaimValue
,setClaimValue
andremoveClaim
to session objects to manage claims. - Added session to the input of
generateEmailVerifyTokenPOST
,verifyEmailPOST
,isEmailVerifiedGET
. - Adds default userContext for verifySession calls that contains the request object.
- Removes support for FDI < 1.15
- Changed
signInUp
third party recipe function to accept an email string instead of an object that takes{id: string, isVerified: boolean}
. - Renames
STMP
toSMTP
everywhere (typo). - The frontend SDK should be updated to a version supporting session claims!
- supertokens-auth-react: >= 0.25.0
- supertokens-web-js: >= 0.2.0
EmailVerification
recipe is now not initialized as part of auth recipes, it should be added to therecipeList
directly instead.- Email verification related overrides (
emailVerificationFeature
prop ofoverride
) moved from auth recipes into theEmailVerification
recipe config. - Email verificitaion related configs (
emailVerificationFeature
props) moved from auth recipes into theEmailVerification
config object root. - ThirdParty recipe no longer takes emailDelivery config -> use emailverification recipe's emailDelivery instead.
- Moved email verification related configs from the
emailDelivery
config of auth recipes into a separateEmailVerification
email delivery config. - Updated return type of
getEmailForUserId
in theEmailVerification
recipe config. It should now return an object with status. - Removed
getResetPasswordURL
,getEmailVerificationURL
,getLinkDomainAndPath
. Changing these urls can be done in the email delivery configs instead. - Removed
unverifyEmail
,revokeEmailVerificationTokens
,isEmailVerified
,verifyEmailUsingToken
andcreateEmailVerificationToken
from auth recipes. These should be called on theEmailVerification
recipe instead. - Changed function signature for email verification APIs to accept a session as an input.
- Changed Session API interface functions:
refreshPOST
now returns a Session container object.signOutPOST
now takes in an optional session object as a parameter.
Before:
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "...",
},
recipeList: [
EmailPassword.init({
emailVerificationFeature: {
// these options should be moved into the config of the EmailVerification recipe
},
override: {
emailVerificationFeature: {
// these overrides should be moved into the overrides of the EmailVerification recipe
}
}
})
]
})
After the update:
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "...",
},
recipeList: [
EmailVerification.init({
// all config should be moved here from the emailVerificationFeature prop of the EmailPassword recipe config
override: {
// move the overrides from the emailVerificationFeature prop of the override config in the EmailPassword init here
}
}),
EmailPassword.init()
]
})
If you turn on email verification your email-based passwordless users may be redirected to an email verification screen in their existing session. Logging out and logging in again will solve this problem or they could click the link in the email to verify themselves.
You can avoid this by running a script that will:
- list all users of passwordless
- create an emailverification token for each of them if they have email addresses
- user the token to verify their address
Something similar to this script:
const SuperTokens = require("supertokens-node");
const Session = require("supertokens-node/recipe/session");
const Passwordless = require("supertokens-node/recipe/passwordless");
const EmailVerification = require("supertokens-node/recipe/emailverification");
SuperTokens.init({
supertokens: {
// TODO: This is a core hosted for demo purposes. You can use this, but make sure to change it to your core instance URI eventually.
connectionURI: "https://try.supertokens.com",
apiKey: "<REQUIRED FOR MANAGED SERVICE, ELSE YOU CAN REMOVE THIS FIELD>",
},
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "...",
},
recipeList: [
EmailVerification.init({
mode: "REQUIRED",
}),
Passwordless.init({
contactMethod: "EMAIL_OR_PHONE",
flowType: "USER_INPUT_CODE_AND_MAGIC_LINK",
}),
Session.init(),
],
});
async function main() {
let paginationToken = undefined;
let done = false;
while (!done) {
const userList = await SuperTokens.getUsersNewestFirst({
includeRecipeIds: ["passwordless"],
limit: 100,
paginationToken,
});
for (const { recipeId, user } of userList.users) {
if (recipeId === "passwordless" && user.email) {
const tokenResp = await EmailVerification.createEmailVerificationToken(user.id, user.email);
if (tokenResp.status === "OK") {
await EmailVerification.verifyEmailUsingToken(tokenResp.token);
}
}
}
done = userList.nextPaginationToken !== undefined;
if (!done) {
paginationToken = userList.nextPaginationToken;
}
}
}
main().then(console.log, console.error);
The UserRoles recipe now adds role and permission information into the access token payload by default. If you are already doing this manually, this will result in duplicate data in the access token.
- You can disable this behaviour by setting
skipAddingRolesToAccessToken
andskipAddingPermissionsToAccessToken
to true in the recipe init. - Check how to use the new claims in our user roles docs on our website.
- Since a new exception type has been added, there is a required change in SRR (
getServerSideProps
). You should handle the new (INVALID_CLAIMS
) exception in the same way as you handleUNAUTHORISED
- Please check our updated guide on our website
- The new exception type and error code requires changes if you are using SuperTokens as as an Authorizer in API Gateways.
- You need to handle the new exception type in the authorizer code.
- You need to configure the "Access Denied" response.
- Please check our updated guide on our website
authUsername
option in smtp config for when email is different than the username for auth.
- Adds a Dashboard recipe
- Makes
userContext
optional insendEmail
andsendSms
function in all recipe exposed functions.
- Adds missing
force
param fromcreateUserIdMapping
anddeleteUserIdMapping
functions
- UserId Mapping functionality and compatibility with CDI 2.15
- Adds
createUserIdMapping
,getUserIdMapping
,deleteUserIdMapping
,updateOrDeleteUserIdMappingInfo
functions
- Fixes overrides not applying correctly in methods called on SessionContainer instances
- Solves the issue of request getting stuck in non returning state while parsing form data for nextjs request
- Fixed fastify issue where same cookie was getting set multiple times on the response object
- Improved type definitions for
SessionWrapper.getSession
.
- Changes session function recipe interfaces to not throw an UNAUTHORISED error when the input is a sessionHandle: https://github.com/supertokens/backend/issues/83
getSessionInformation
now returnsundefined
is the session does not existupdateSessionData
now returnsfalse
if the inputsessionHandle
does not exist.updateAccessTokenPayload
now returnsfalse
if the inputsessionHandle
does not exist.regenerateAccessToken
now returnsundefined
if the input access token'ssessionHandle
does not exist.- The sessionClass functions have not changed in behaviour and still throw UNAUTHORISED. This works cause the sessionClass works on the current session and not some other session.
- Clears cookies when revokeSession is called using the session container, even if the session did not exist from before: #343
- Fixed handling of unicode characters in usermetadata (and emails, roles, session/access token payload data)
- Adds default userContext for API calls that contains the request object. It can be used in APIs / functions override like so:
signIn: async function (input) {
if (input.userContext._default && input.userContext._default.request) {
// do something here with the request object
}
}
- #220
- Adds
{status: "GENERAL_ERROR", message: string}
as a possible output to all the APIs. - Changes
FIELD_ERROR
output status in third party recipe API to beGENERAL_ERROR
. - Replaced
FIELD_ERROR
status type in third party signinup API withGENERAL_ERROR
. - Removed
FIELD_ERROR
status type from third party signinup recipe function.
- Adds
- If sms or email sending failed in passwordless recipe APIs, we now throw a regular JS error from the API as opposed to returning a
GENERAL_ERROR
to the client. - If there is an error whilst getting the profile info about a user from a third party provider (in /signinup POST API), then we throw a regular JS error instead of returning a
GENERAL_ERROR
to the client. - Changes SuperTokensSMS service to take an API key directly as opposed to take an object that takes an API key
- Passes only base request and base response objects to session recipe implementation functions. Normalisation of raw res and raw response is now done in the session's index.ts file
- Removes support for faunadb session recipe modifier.
- Removes support for FDI < 1.14
- Fixes Cookie sameSite config validation.
- Fixes a few typos
- Changes
getEmailForUserIdForEmailVerification
function inside thirdpartypasswordless to take into account passwordless emails and return an empty string in case a passwordless email doesn't exist. This helps situations where the dev wants to customise the email verification functions in the thirdpartypasswordless recipe.
- Fixes email undefined error when resending the passwordless login email.
- Adds User Roles recipe and compatibility with CDI 2.14
emailDelivery
user config for Emailpassword, Thirdparty, ThirdpartyEmailpassword, Passwordless and ThirdpartyPasswordless recipes.smsDelivery
user config for Passwordless and ThirdpartyPasswordless recipes.Twilio
service integartion for smsDelivery ingredient.SMTP
service integration for emailDelivery ingredient.Supertokens
service integration for smsDelivery ingredient.
- For Emailpassword recipe input config,
resetPasswordUsingTokenFeature.createAndSendCustomEmail
andemailVerificationFeature.createAndSendCustomEmail
have been deprecated. - For Thirdparty recipe input config,
emailVerificationFeature.createAndSendCustomEmail
has been deprecated. - For ThirdpartyEmailpassword recipe input config,
resetPasswordUsingTokenFeature.createAndSendCustomEmail
andemailVerificationFeature.createAndSendCustomEmail
have been deprecated. - For Passwordless recipe input config,
createAndSendCustomEmail
andcreateAndSendCustomTextMessage
have been deprecated. - For ThirdpartyPasswordless recipe input config,
createAndSendCustomEmail
,createAndSendCustomTextMessage
andemailVerificationFeature.createAndSendCustomEmail
have been deprecated.
Following is an example of ThirdpartyPasswordless recipe migration. If your existing code looks like
import SuperTokens from "supertokens-auth-react";
import ThirdpartyPasswordless from "supertokens-auth-react/recipe/thirdpartypasswordless";
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "...",
},
recipeList: [
ThirdpartyPasswordless.init({
contactMethod: "EMAIL_OR_PHONE",
createAndSendCustomEmail: async (input, userContext) => {
// some custom logic
},
createAndSendCustomTextMessage: async (input, userContext) => {
// some custom logic
},
flowType: "...",
emailVerificationFeature: {
createAndSendCustomEmail: async (user, emailVerificationURLWithToken, userContext) => {
// some custom logic
},
},
}),
],
});
After migration to using new emailDelivery
and smsDelivery
config, your code would look like:
import SuperTokens from "supertokens-auth-react";
import ThirdpartyPasswordless from "supertokens-auth-react/recipe/thirdpartypasswordless";
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
ThirdpartyPasswordless.init({
contactMethod: "EMAIL_OR_PHONE",
emailDelivery: {
service: {
sendEmail: async (input) => {
let userContext = input.userContext;
if(input.type === "EMAIL_VERIFICATION") {
// some custom logic
} else if (input.type === "PASSWORDLESS_LOGIN") {
// some custom logic
}
}
}
},
smsDelivery: {
service: {
sendSms: async (input) => {
// some custom logic for sending passwordless login SMS
}
}
}
flowType: "..."
})
]
})
- Changes
getUserMetadata
to returnany
type for metadata so that it's easier to use.
- Calling the setImmediate function inside assertThatBodyParserHasBeenUsedForExpressLikeRequest only if the function is getting executed in NextJS env. Fixes #313
- Fixes the routes issue for Hapi framework plugin
- Adds UserMetadata recipe
- Fixes debug log statement when custom header is not passed during refresh session
- Adds debug logging functionality
- removed jsonschema dependency
- Changes Github and Discord providers to check if email is
undefined
or not before assigning the email object to the profile info.
- Added
ThirdPartyPasswordless
recipe + tests
- Fixes #269. The json body parser will additionally be used to parse the request body if the request body is of type
{}
init
function will throw error if there are empty items in recipeList when passing the config
- Adds user context to all functions exposed to the user, and to API and Recipe interface functions. This is a non breaking change for User exposed function calls, but a breaking change if you are using the Recipe or APIs override feature
- Returns session from API interface functions that create a session
- Renames functions in ThirdPartyEmailPassword recipe (#219):
- Recipe Interface:
signInUp
->thirdPartySignInUp
signUp
->emailPasswordSignUp
signIn
->emailPasswordSignIn
- API Interface:
emailExistsGET
->emailPasswordEmailExistsGET
- User exposed functions (in
recipe/thirdpartyemailpassword/index.ts
)signInUp
->thirdPartySignInUp
signUp
->emailPasswordSignUp
signIn
->emailPasswordSignIn
- Recipe Interface:
- Uses recipe interface inside session class so that any modification to those get reflected in the session class functions too.
- Removes unused property from session recipe
- Added userId as an optional property to the response of
recipe/user/password/reset
(compatibility with CDI 2.12). - Fixes #244 - throws an error if a user tries to update email / password of a third party login user.
- Adds ability to give a path for each of the hostnames in the connectionURI: #252
- add workflow to verify if pr title follows conventional commits
- Added
regenerateAccessToken
as a new recipe function for the session recipe.
- Allows passing of custom user context everywhere: #215
- Returns session object from API interface functions which create a new session: #215
- Adds passwordless recipe
- Adds compatibility with FDI 1.12 and CDI 2.11
- Adds passwordless tests
- Delete user functionality
- Exposes all essential
types
files. Fixes #230
- The ability to enable JWT creation with session management, this allows easier integration with services that require JWT based authentication: supertokens/supertokens-core#250
- Removes use of apiGatewayPath from apple's redirect URI since that is already there in the apiBasePath
- Sign in with Discord, Google workspaces.
- If
getProfileInfo
throws an error, then it is sent as a FIELD_ERROR to the frontend
- Changes `sendJSONResponse to not allow setting of result if it has already been set
- AWS lambda middleware will return
404
response if the API route is not served by the middleware and user has not passed a handler.
- Uses supertokens-js-override from npm
- When routing, ignores
rid
value"anti-csrf"
: #202
- Support for FDI 1.10:
- Allow thirdparty
/signinup POST
API to takeauthCodeResponse
XORcode
so that it can supprt OAuth via PKCE - Adds apple sign in callback API
- Allow thirdparty
- Optional
getRedirectURI
function added to social providers in case we set theredirect_uri
on the backend. - Adds optional
isDefault
param to auth providers so that they can be reused with different credentials. - Verifies ID Token sent for sign in with apple as per https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/verifying_a_user
sendHTMLResponse
andgetFormData
functions for frameworks
- Uses
accessTokenPayload
instead ofjwtPayload
when creating SessionInformation object
- Removes
SessionRequest
as an exported member of session recipe's index file
- Uses non arrow functions in api and recipe interface impl to allow for "true" inheritance in override: #199
- Uses
bind(this)
when calling original implementation
- Trying to handle errors closer to the source in middlewares instead of relying on the global error handler.
- Removes
signInUpPost
from thirdpartyemailpassword API interface and replaces it with three APIs:emailPasswordSignInPOST
,emailPasswordSignUpPOST
andthirdPartySignInUpPOST
: #192 - Removes all deprecated functions
- Renames all "JWT" related functions in session recipe to use "AccessToken" instead
- Removes support for CDI 2.7 (which used some of the new deprecated APIs in the core)
- Changes implementation such that actual client IDs are not in the SDK, removes imports for OAuth dev related code.
- URL protocol is being taken into account when determining the value of cookie same site: supertokens/supertokens-golang#36
- Adds OAuth development keys for Google and Github for faster recipe implementation.
- Updated dependencies.
- JWT recipe to create signed JWT tokens
- New API to fetch keys used for JWT verification using JWKS
- Support for multiple access token signing keys: supertokens/supertokens-core#305
- Supporting CDI 2.9
- Header
"content-type": "application/json; charset=utf-8"
when querying the core
- Unnecessary serverless optimisation
- fixes issue #180 where user was required to have all frameworks as depedencies or else use
compilerOptions.skipLibCheck
in their tsconfig.json verifySession
middleware ts issue fix for Hapi framework- ts import for
verifySession
fix for koa
- Removed redwood support
- fixes issue #175 regarding making error handlers async, session error callabacks async and making VerifySessionOptions optional for verifySession middleware.
- Multiple framework support. Currently supporting express, koa, hapi, fastify, awsLambda and loopback
- BaseRequest and BaseResponse interface added which will be used inside recipe instead of previously used express.Request and express.Response
framework
config option. Default value isexpress
.- basic tests for all frameworks.
- Following functions are changed in default SuperTokens class (supertokens.ts):
- middleware: instead of taking no option and returning an express middleware, it now takes 2 parameters: BaseRequest and BaseResponse and returns a boolean. If response was send by the middleware, it returns true, else false
- handleAPI: no longer take
next
parameter. Also the request and response parameter will be of type BaseRequest and BaseResponse. - errorHandler: instead of taking no option and returning an express error middleware, it now takes 3 parameters: error object, BaseRequest and BaseResponse
- Cookie and Header handling will part be delegated to specific framework.
- Request and Response parameters passwed in functions
createNewSession
,getSession
andrefreshSession
can by of any type and notexpress.Request
andexpress.Response
. - middleware, errorHandler should be imported from specific framework (i.e.
import {middleware, errorHandler} from "supertokens-node/framework/express"
). Also, errorHandler may not be there for few frameworksas it may not be required. - verifySession should be imported from specific framework, from session recipe (i.e.
import {verifySession} from "supertokens-node/recipe/session/framework/express"
). handleAPIRequest
in recipe modules will no longer takenext
parameter. Also the request and response parameter will be of type BaseRequest and BaseResponse.handleAPIRequest
in recipe modules will return boolean. If the response is sent fromhandleAPIRequest
, the function will return true else it will return false.handleError
in recipe modules will no longer takenext
parameter. Also the request and response parameter will be of type BaseRequest and BaseResponse. If error is not handled by the function, it will rethrow the error.- All the API implementation functions should return a boolean. If response is sent,
true
will be returned else false. verifySession
which was defined inmiddleware.ts
file is now removed.- Changed
UNKNOWN_USER_ID
toUNKNOWN_USER_ID_ERROR
to make it more consistent with other status types: #166
- middleware, errorHandler imported directly from supertokens-node (i.e.
import {middleware, errorHandler} from "supertokens-node"
) - verifySession imported directly from session recipe (i.e.
import {verifySession} from "supertokens-node/recipe/session"
)
- In
ThirdParty
recipe, for typeTypeProviderGetResponse
, the fieldauthorisationRedirect.params
will be of type{ [key: string]: string | ((request: BaseRequest) => string) }
. Earlier, the request was of type express.Request. - For all the recipes'
APIOptions
, their will be nonext
parameter. Also the request and response parameter will be of type BaseRequest and BaseResponse. - Updated minimum Oauth scopes required for various thirdparty providers.
- For thirdparty providers, if the scope array is passed by the user, the default scopes will not be used.
- Changes to emailpassword, emailverification, thirdpartyemailpassword and thirdparty functions to not return errors implicitly: #167
- The req and res objects in the error handlers config for session recipe are not of type express anymore, but are of type BaseResponse and BaseRequest
- updated function
getUserByEmail
inrecipe/thirdpartyemailpassword/recipeImplementation/emailPasswordRecipeImplementation.ts
to usegetUsersByEmail
instead ofgetUserByEmail
- To how pagination and use count is done: supertokens/supertokens-core#259
- Deprecates (instead, use
supertokens.getUserCount
,supertokens.getUsersNewestFirst
orsupertokens.getUsersOldestFirst
):ThirdParty.getUserCount()
,ThirdParty.getUsersNewestFirst()
,ThirdParty.getUsersOldestFirst
EmailPassword.getUserCount()
,EmailPassword.getUsersNewestFirst()
,EmailPassword.getUsersOldestFirst
ThirdPartyEmailPassword.getUserCount()
,ThirdPartyEmailPassword.getUsersNewestFirst()
,ThirdPartyEmailPassword.getUsersOldestFirst
- Deprecates (instead use
Session.getSessionInformation()
)Session.getSessionData()
,Session.getJWTPayload()
- Adds email verification function calls in thirdparty sign in up API as per supertokens/supertokens-core#295
- Adds
emailVerificationRecipeImplementation
in all auth recipeAPIOptions
so that APIs can access the email verification implementation. - Add recipe function to fetch third party users supertokens/supertokens-core#277
- Deprecates
getUserByEmail
in thirdpartyemailpassword and replaces it withgetUsersByEmail
. - Adds
updateEmailOrPassword
recipe function to emailpassword and thirdpartyemailpassword recipes: supertokens/supertokens-core#275 - Adds emailverification recipe functions to all recipes: supertokens/supertokens-core#270
- Fixes typescript issue with default imports. (Related to supertokens/supertokens-auth-react#297)
- signInUpPOST default implementation will return accessToken api response data instead of axios response
- Uses
getSession
function instead ofverifySession
middleware in prebuilt APIs - Refactor code to use recipeImplementations that can be override by the user
getSession
third param is no longer a boolean- Provides FaunaDB's session implementation as a modification to the original session recipe.
- Removes deprecated
handleCustomFormFieldsPostSignUp
. - Removes
superTokensMiddleware
from NextJS as it is no longer needed and was deprecated. - Fixes NextJS type for
superTokensNextWrapper
function setJwtPayload
andsetSessionData
get allformFields
param- Adds API interfaces to all recipes
- Provides a way to override API logic easily.
- Replaces
disableDefaultImplementation
with setting functions inoverride > apis
toundefined
. - Removes explicit post API callback functions since now users can override apis and emulate post api callbacks easily.
- Removes the use of GENERAL_ERROR and throws a normal JS Error instead.
- Allows recipes to be passed in constructor so that child recipes do not create multiple instances of the same recipe.
- Removes checking of duplicate APIs since we are now using interfaces for APIs which won't allow for duplicates anyway...
- Removes duplicate signout APIs from all auth recipes since it's already exposed from the session recipe.
- Marked
setJwtPayload
andsetSessionData
as deprecated.
- #135: In serverless env, waits for email to be sent before returning the response cause sometimes, serverless envs quite the process early on.
- #127: In serverless env, sends telemetry with a 30% probability.
- #122: Calling verifySession in another file (via router), before the init function is called throws a not initialized error.
- Uses custom header as a measure to prevent CSRF attacks - unless the user explicitly enables anti-csrf tokens.
- new FDI 1.8
- changes
enableAntiCsrf
config toantiCsrf
. - removes deprecated
apiWebProxyPath
config. UseappInfo -> apiGatewayPath
instead.
- Runs JSON body parser only if
req.body
isundefined
or if it is buffer
apiGatewayPath
inappInfo
duringinit
. This deprecatesapiWebProxyPath
.
- Fixes case when bodyParser is not used in serverless functions - We now attempt to use bodyParser even if
req.body
is notundefined
- as long as it's not a valid JSON.
- Complies with FDI 1.7.1 for issue supertokens/supertokens-core#233
- Issue #113: If the
idRefreshToken
is present in the request, but the refresh token is missing, we clear theidRefreshToken
as well.
- verifySession now accepts an object as a parameter. Two valid parameters are sessionRequired and antiCsrfCheck. sessionRequired can be given by users if they intend to make the session requirement optional for an API.
- updated type of handlePostSignIn parameter in signInFeature for thirdpartyemailpassword
- handlePostSignUp parameter in signUpFeature for emailpassword recipe.
- deprecation warning for handleCustomFormFieldsPostSignUp parameter.
- handlePostSignIn parameter in signInFeature for emailpassword recipe.
- Optimization for serverless execution
- Config to enable serverless optimisation
- apiWebProxyPath config added. This will allow user to config proxy path which would be used by browser while making request to the api-server. This enables to set correct value for the refreshTokenPath.
- allowing empty string to be passed in request body
- doAntiCsrfCheck parameter for getSession in FaunaDB is now optional
- Sign out API for session recipe
- verifySession now accepts an object as a parameter. Two valid parameters are sessionRequired and antiCsrfCheck. sessionRequired can be by user if they intends to make the session requirement optional for the API.
- Allows ";" at the end of connectionURI to core
- Fixes bug in NextJS wrapper which called resolve even though there was an error
- Fix Domain normalisation with "/.netlify/functions/api"
- Fix Path normalisation with "/.netlify/functions/api"
- ThirdartyEmailpassword recipe added
- sessionFeature config that allows user to set jwtPayload and sessionData during signup or signin
- Changed error handling
- Type of authorisationRedirect params to include a function
- using jsonschema to validate user config input (#73)
- Fixed #77
- Extracts email verification into its own recipe
- Implements thirdparty recipe
- Sends telemetryId for telemetry
- Telemetry as per #85
- Allow users to pass FaunaDB client directly when using Session.init
- Fixes #83
- enableAntiCsrf as config parameter in session recipe
- enableAntiCsrf boolean in session create,verify and refresh APIs if CDI version is 2.6
- cookieSecure to true by default if the apiDomain has https
- if the apiDomain and websiteDomain values are different (no common top level domain), then cookieSameSite will be set to none by default, else set it to lax
- Fixed #63
- Always sets httpOnly flag to be true for session cookies regardless of if secure flag is on or off.
- Update superTokensNextWrapper to add a return value.
- Email verification feature
- Change the User object to include timeJoined
- Sends emails to our APIs only if not testing mode
- Add superTokensNextWrapper generic express middleware wrapper
- getUsersNewestFirst, getUsersOldestFirst and getUserCount functions
- Bump axios from 0.19 to 0.21 to fix Critical Dependency
- Removes the need for Proxy in NextJS so that if a session is created manually by the user, it still works
- Fixes bug for missing return in nextjs helper
- Changed name from supertokenMiddleware to superTokensMiddleware
- Add NextJS helper
- If
init
is called multiple times, it does not throw an error
- Added changes as per new FDI: supertokens/frontend-driver-interface#3
- API to check if an email exists
- EmailPassword login features
- FaunaDB integration
- Issue #17 - Do not clear cookies if they do not exist in the first place
- Support for CDI 2.3 and FDI 1.2
- Fixes issue #7
- Remove compatibility with CDI 1.0
- auth0Handler function
getCORSAllowedHeaders
function to be used bycors
middleware- Automatically adds a refresh API if the user calls the
init
function insideapp.use()
- Support for CDI 2.2
- Fixes #2 - Prevents duplicate
Access-Control-Allow-Credentials
header value
- Fixed typo in exported typescript type
- Support for API key
- Compatibility with CDI 2.1
- config changes and code refactor
- Middleware for verification, refreshing and error handling
revokeMultipleSessions
functionupdateJWTPayload
function
- Code refactor
- Changed
revokeSessionUsingSessionHandle
=>revokeSession
- Support for CDI version 2.0