diff --git a/lib/build/recipe/thirdparty/api/implementation.js b/lib/build/recipe/thirdparty/api/implementation.js index d397f26bd..1b53ba141 100644 --- a/lib/build/recipe/thirdparty/api/implementation.js +++ b/lib/build/recipe/thirdparty/api/implementation.js @@ -63,13 +63,6 @@ function getAPIInterface() { } else { throw Error("should never come here"); } - if (provider.config.validateAccessToken !== undefined) { - yield provider.config.validateAccessToken({ - accessToken: oAuthTokensToUse.access_token, - clientConfig: provider.config, - userContext, - }); - } const userInfo = yield provider.getUserInfo({ oAuthTokens: oAuthTokensToUse, userContext }); if (userInfo.email === undefined && provider.config.requireEmail === false) { userInfo.email = { diff --git a/lib/build/recipe/thirdparty/providers/custom.js b/lib/build/recipe/thirdparty/providers/custom.js index 5637f2aec..05f58e611 100644 --- a/lib/build/recipe/thirdparty/providers/custom.js +++ b/lib/build/recipe/thirdparty/providers/custom.js @@ -347,6 +347,18 @@ function NewProvider(input) { ); rawUserInfoFromProvider.fromUserInfoAPI = userInfoFromAccessToken; } + /** + * This is intentionally not part of the above if block. This is because the user may want to validate the access + * token payload even if the user info API has not been provided by the provider. In this case they would get an + * empty object and they can fail if they always expect a non-empty object. + */ + if (impl.config.validateAccessToken !== undefined) { + yield impl.config.validateAccessToken({ + accessTokenPayload: rawUserInfoFromProvider.fromUserInfoAPI, + clientConfig: impl.config, + userContext, + }); + } const userInfoResult = getSupertokensUserInfoResultFromRawUserInfo( impl.config, rawUserInfoFromProvider diff --git a/lib/build/recipe/thirdparty/types.d.ts b/lib/build/recipe/thirdparty/types.d.ts index fd51d8d07..a5b666382 100644 --- a/lib/build/recipe/thirdparty/types.d.ts +++ b/lib/build/recipe/thirdparty/types.d.ts @@ -80,7 +80,9 @@ declare type CommonProviderConfig = { * @param input.userContext Refer to https://supertokens.com/docs/thirdparty/advanced-customizations/user-context */ validateAccessToken?: (input: { - accessToken: string; + accessTokenPayload: { + [key: string]: any; + }; clientConfig: ProviderConfigForClientType; userContext: any; }) => Promise; diff --git a/lib/ts/recipe/thirdparty/api/implementation.ts b/lib/ts/recipe/thirdparty/api/implementation.ts index c13458414..f2765d6ce 100644 --- a/lib/ts/recipe/thirdparty/api/implementation.ts +++ b/lib/ts/recipe/thirdparty/api/implementation.ts @@ -31,14 +31,6 @@ export default function getAPIInterface(): APIInterface { throw Error("should never come here"); } - if (provider.config.validateAccessToken !== undefined) { - await provider.config.validateAccessToken({ - accessToken: oAuthTokensToUse.access_token, - clientConfig: provider.config, - userContext, - }); - } - const userInfo = await provider.getUserInfo({ oAuthTokens: oAuthTokensToUse, userContext }); if (userInfo.email === undefined && provider.config.requireEmail === false) { diff --git a/lib/ts/recipe/thirdparty/providers/custom.ts b/lib/ts/recipe/thirdparty/providers/custom.ts index f485d2ad0..6b5fc9531 100644 --- a/lib/ts/recipe/thirdparty/providers/custom.ts +++ b/lib/ts/recipe/thirdparty/providers/custom.ts @@ -335,6 +335,19 @@ export default function NewProvider(input: ProviderInput): TypeProvider { rawUserInfoFromProvider.fromUserInfoAPI = userInfoFromAccessToken; } + /** + * This is intentionally not part of the above if block. This is because the user may want to validate the access + * token payload even if the user info API has not been provided by the provider. In this case they would get an + * empty object and they can fail if they always expect a non-empty object. + */ + if (impl.config.validateAccessToken !== undefined) { + await impl.config.validateAccessToken({ + accessTokenPayload: rawUserInfoFromProvider.fromUserInfoAPI, + clientConfig: impl.config, + userContext, + }); + } + const userInfoResult = getSupertokensUserInfoResultFromRawUserInfo(impl.config, rawUserInfoFromProvider); return { diff --git a/lib/ts/recipe/thirdparty/types.ts b/lib/ts/recipe/thirdparty/types.ts index 750d44d3d..30a659fec 100644 --- a/lib/ts/recipe/thirdparty/types.ts +++ b/lib/ts/recipe/thirdparty/types.ts @@ -77,7 +77,7 @@ type CommonProviderConfig = { * @param input.userContext Refer to https://supertokens.com/docs/thirdparty/advanced-customizations/user-context */ validateAccessToken?: (input: { - accessToken: string; + accessTokenPayload: { [key: string]: any }; clientConfig: ProviderConfigForClientType; userContext: any; }) => Promise;