UNPKG

supertokens-node

Version:
480 lines (425 loc) 19.1 kB
## [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