supertokens-node
Version:
NodeJS driver for SuperTokens core
480 lines (425 loc) • 19.1 kB
Markdown
## [15.0.0] - 2023-07-19
### Added
- 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. <basePath>/<tenantId>/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`
### Breaking changes
- Only supporting FDI 1.17
- Core must be upgraded to 6.0
- `getUsersOldestFirst` & `getUsersNewestFirst` has mandatory parameter `tenantId`. Pass `'public'` if not using multitenancy.
- Added mandatory field `tenantId` to `EmailDeliveryInterface` and `SmsDeliveryInterface`. Pass `'public'` if not using multitenancy.
- Removed deprecated config `createAndSendCustomEmail` and `createAndSendCustomTextMessage`.
- EmailPassword recipe changes:
- Added mandatory `tenantId` field to `TypeEmailPasswordPasswordResetEmailDeliveryInput`
- Removed `resetPasswordUsingTokenFeature` from `TypeInput`
- Added `tenantId` param to `validate` function in `TypeInputFormField`
- 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`
- EmailVerification recipe changes:
- Added mandatory `tenantId` field to `TypeEmailVerificationEmailDeliveryInput`
- 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`
- Passwordless recipe changes:
- Added `tenantId` param to `validateEmailAddress`, `validatePhoneNumber` and `getCustomUserInputCode` functions in `TypeInput`
- Added mandatory `tenantId` field to `TypePasswordlessEmailDeliveryInput` and `TypePasswordlessSmsDeliveryInput`
- 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`
- 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 added `manuallyCreateOrUpdateUser` 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 provider
- `rawUserInfoFromProvider` - contains all the user profile info as returned by the provider
- Updated `authorisationUrlGET` API
- Changed: Doesn't accept `clientId` anymore and accepts `clientType` instead to determine the matching config
- Added: optional `pkceCodeVerifier` in the response, to support PKCE
- Updated `signInUpPOST` API
- Removed: `clientId`, `redirectURI`, `authCodeResponse` and `code` from the input
- Instead,
- accepts `clientType` to determine the matching config
- One of redirectURIInfo (for code flow) or oAuthTokens (for token flow) is required
- 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.
- 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` and `revokeAcrossAllTenants` params to `revokeAllSessionsForUser` in the recipe interface.
- Added `tenantId` and `fetchAcrossAllTenants` params to `getAllSessionHandlesForUser` in the recipe interface.
- Added `getTenantId` function to `SessionContainerInterface`
- Added `tenantId` to `fetchValue` function in `PrimitiveClaim`, `PrimitiveArrayClaim`.
- 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`
- 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.
### Changes
- Recipe function changes:
- Added optional `tenantIdForPasswordPolicy` param to `EmailPassword.updateEmailOrPassword`, `ThirdPartyEmailPassword.updateEmailOrPassword`
- Added optional param `tenantId` to `Session.revokeAllSessionsForUser`. If tenantId is undefined, sessions are revoked across all tenants
- Added optional param `tenantId` to `Session.getAllSessionHandlesForUser`. If tenantId is undefined, sessions handles across all tenants are returned
- Adds optional param `tenantId` to `getUserCount` which returns total count across all tenants if not passed.
- Adds protected prop `tId` to the accessToken payload
- Adds `includesAny` claim validator to `PrimitiveArrayClaim`
### Fixes
- Fixed an issue where certain Dashboard API routes would return a 404 for Hapi
### Migration
- To call any recipe function that has `tenantId` added to it, pass `'public`'
Before:
```ts
EmailPassword.signUp("test@example.com", "password");
```
After:
```ts
EmailPassword.signUp("public", "test@example.com", "password");
```
- Input for provider array change as follows:
Before:
```ts
let googleProvider = thirdParty.Google({
clientID: "...",
clientSecret: "...",
});
```
After:
```ts
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 and `clientType` 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:
```ts
let providers = [
thirdParty.Google({
isDefault: true,
clientID: "clientid1",
clientSecret: "...",
}),
thirdParty.Google({
clientID: "clientid2",
clientSecret: "...",
}),
];
```
After:
```ts
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` and `userInfoMap` to fetch the user info from the provider
- or specify custom implementation in an override for `getUserInfo` (override example in the next section)
Before:
```ts
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:
```ts
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
```ts
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 the `oidcDiscoveryEndpoint` config. For eg. if `oidcDiscoveryEndpoint` is set to `"https://accounts.google.com/"`, the SDK will fetch the endpoints from `"https://accounts.google.com/.well-known/openid-configuration"`
- 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
```ts
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;
},
};
},
};
```
- To get access token and raw user info from the provider, override the signInUp function
```ts
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:
```json
{
"thirdPartyId": "...",
"clientId": "...",
"redirectURI": "...", // optional
"code": "..."
}
```
After:
```json
{
"thirdPartyId": "...",
"clientType": "...",
"redirectURIInfo": {
"redirectURIOnProviderDashboard": "...", // required
"redirectURIQueryParams": {
"code": "...",
"state": "..."
// ... all callback query params
},
"pkceCodeVerifier": "..." // optional, use this if using PKCE flow
}
}
```
- If using tokens:
Before:
```json
{
"thirdPartyId": "...",
"clientId": "...",
"redirectURI": "...",
"authCodeResponse": {
"access_token": "...", // required
"id_token": "..."
}
}
```
After:
```json
{
"thirdPartyId": "...",
"clientType": "...",
"oAuthTokens": {
"access_token": "...", // now optional
"id_token": "..."
// rest of the oAuthTokens as returned by the provider
}
}
```
### SDK and core compatibility
- Compatible with Core>=6.0.0 (CDI 4.0)
- Compatible with frontend SDKs:
- supertokens-auth-react@0.34.0
- supertokens-web-js@0.7.0
- supertokens-website@17.0.2