Skip to content

Commit

Permalink
chore: Fix tests and refactor Github provider to not use cross-fetch …
Browse files Browse the repository at this point in the history
…directly (#709)

* Use utils functions instead of fetch directly

* Update provider test

* Add redirect method to BaseResponse

* Update provider test

* Update provider test

* Dont use cross fetch in provider directly

* Change signature for get request helper

* Change signature for get request helper

* Change signature for post request helper

* Change signature for get request helper

* Update version and CHANGELOG
  • Loading branch information
nkshah2 authored Oct 6, 2023
1 parent 6d93571 commit 37235ea
Show file tree
Hide file tree
Showing 20 changed files with 396 additions and 135 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html)

## [16.2.1] - 2023-10-06

- Slight refactors logic to code for social providers to make it consistent across all providers

## [16.2.0] - 2023-09-29

### Changes
Expand Down
31 changes: 28 additions & 3 deletions lib/build/recipe/thirdparty/providers/bitbucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ var __importDefault =
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("./utils");
const custom_1 = __importDefault(require("./custom"));
const logger_1 = require("../../../logger");
function Bitbucket(input) {
if (input.config.name === undefined) {
input.config.name = "Bitbucket";
Expand Down Expand Up @@ -63,16 +64,40 @@ function Bitbucket(input) {
undefined,
headers
);
rawUserInfoFromProvider.fromUserInfoAPI = userInfoFromAccessToken;
if (userInfoFromAccessToken.status >= 400) {
logger_1.logDebugMessage(
`Received response with status ${
userInfoFromAccessToken.status
} and body ${await userInfoFromAccessToken.response.clone().text()}`
);
throw new Error(
`Received response with status ${
userInfoFromAccessToken.status
} and body ${await userInfoFromAccessToken.response.clone().text()}`
);
}
rawUserInfoFromProvider.fromUserInfoAPI = userInfoFromAccessToken.response;
const userInfoFromEmail = await utils_1.doGetRequest(
"https://api.bitbucket.org/2.0/user/emails",
undefined,
headers
);
rawUserInfoFromProvider.fromUserInfoAPI.email = userInfoFromEmail;
if (userInfoFromEmail.status >= 400) {
logger_1.logDebugMessage(
`Received response with status ${
userInfoFromEmail.status
} and body ${await userInfoFromEmail.response.clone().text()}`
);
throw new Error(
`Received response with status ${
userInfoFromEmail.status
} and body ${await userInfoFromEmail.response.clone().text()}`
);
}
rawUserInfoFromProvider.fromUserInfoAPI.email = userInfoFromEmail.response;
let email = undefined;
let isVerified = false;
for (const emailInfo of userInfoFromEmail.values) {
for (const emailInfo of userInfoFromEmail.response.values) {
if (emailInfo.is_primary) {
email = emailInfo.email;
isVerified = emailInfo.is_confirmed;
Expand Down
30 changes: 28 additions & 2 deletions lib/build/recipe/thirdparty/providers/custom.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const utils_1 = require("./utils");
const pkce_challenge_1 = __importDefault(require("pkce-challenge"));
const configUtils_1 = require("./configUtils");
const jose_1 = require("jose");
const logger_1 = require("../../../logger");
const DEV_OAUTH_AUTHORIZATION_URL = "https://supertokens.io/dev/oauth/redirect-to-provider";
exports.DEV_OAUTH_REDIRECT_URL = "https://supertokens.io/dev/oauth/redirect-to-app";
// If Third Party login is used with one of the following development keys, then the dev authorization url and the redirect url will be used.
Expand Down Expand Up @@ -250,7 +251,20 @@ function NewProvider(input) {
accessTokenAPIParams["redirect_uri"] = exports.DEV_OAUTH_REDIRECT_URL;
}
/* Transformation needed for dev keys END */
return await utils_1.doPostRequest(tokenAPIURL, accessTokenAPIParams);
const tokenResponse = await utils_1.doPostRequest(tokenAPIURL, accessTokenAPIParams);
if (tokenResponse.status >= 400) {
logger_1.logDebugMessage(
`Received response with status ${
tokenResponse.status
} and body ${await tokenResponse.response.clone().text()}`
);
throw new Error(
`Received response with status ${
tokenResponse.status
} and body ${await tokenResponse.response.clone().text()}`
);
}
return tokenResponse.response;
},
getUserInfo: async function ({ oAuthTokens, userContext }) {
const accessToken = oAuthTokens["access_token"];
Expand Down Expand Up @@ -313,7 +327,19 @@ function NewProvider(input) {
queryParams,
headers
);
rawUserInfoFromProvider.fromUserInfoAPI = userInfoFromAccessToken;
if (userInfoFromAccessToken.status >= 400) {
logger_1.logDebugMessage(
`Received response with status ${
userInfoFromAccessToken.status
} and body ${await userInfoFromAccessToken.response.clone().text()}`
);
throw new Error(
`Received response with status ${
userInfoFromAccessToken.status
} and body ${await userInfoFromAccessToken.response.clone().text()}`
);
}
rawUserInfoFromProvider.fromUserInfoAPI = userInfoFromAccessToken.response;
}
const userInfoResult = getSupertokensUserInfoResultFromRawUserInfo(impl.config, rawUserInfoFromProvider);
return {
Expand Down
57 changes: 22 additions & 35 deletions lib/build/recipe/thirdparty/providers/github.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,8 @@ var __importDefault =
return mod && mod.__esModule ? mod : { default: mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
*
* This software is licensed under the Apache License, Version 2.0 (the
* "License") as published by the Apache Software Foundation.
*
* You may not use this file except in compliance with the License. You may
* obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
const cross_fetch_1 = __importDefault(require("cross-fetch"));
const custom_1 = __importDefault(require("./custom"));
const utils_1 = require("./utils");
function getSupertokensUserInfoFromRawUserInfoResponseForGithub(rawUserInfoResponse) {
if (rawUserInfoResponse.fromUserInfoAPI === undefined) {
throw new Error("rawUserInfoResponse.fromUserInfoAPI is not available");
Expand Down Expand Up @@ -58,24 +44,23 @@ function Github(input) {
const basicAuthToken = Buffer.from(
`${clientConfig.clientId}:${clientConfig.clientSecret === undefined ? "" : clientConfig.clientSecret}`
).toString("base64");
const applicationsResponse = await cross_fetch_1.default(
const applicationResponse = await utils_1.doPostRequest(
`https://api.github.com/applications/${clientConfig.clientId}/token`,
{
headers: {
Authorization: `Basic ${basicAuthToken}`,
"Content-Type": "application/json",
},
method: "POST",
body: JSON.stringify({
access_token: accessToken,
}),
access_token: accessToken,
},
{
Authorization: `Basic ${basicAuthToken}`,
"Content-Type": "application/json",
}
);
if (applicationsResponse.status !== 200) {
if (applicationResponse.status !== 200) {
throw new Error("Invalid access token");
}
const body = await applicationsResponse.json();
if (body.app === undefined || body.app.client_id !== clientConfig.clientId) {
if (
applicationResponse.response.app === undefined ||
applicationResponse.response.app.client_id !== clientConfig.clientId
) {
throw new Error("Access token does not belong to your application");
}
};
Expand All @@ -96,18 +81,20 @@ function Github(input) {
Accept: "application/vnd.github.v3+json",
};
const rawResponse = {};
const emailInfoResp = await cross_fetch_1.default("https://api.github.com/user/emails", { headers });
const emailInfoResp = await utils_1.doGetRequest("https://api.github.com/user/emails", undefined, headers);
if (emailInfoResp.status >= 400) {
throw new Error(`Getting userInfo failed with ${emailInfoResp.status}: ${await emailInfoResp.text()}`);
throw new Error(
`Getting userInfo failed with ${emailInfoResp.status}: ${await emailInfoResp.response.text()}`
);
}
const emailInfo = await emailInfoResp.json();
rawResponse.emails = emailInfo;
const userInfoResp = await cross_fetch_1.default("https://api.github.com/user", { headers });
rawResponse.emails = emailInfoResp.response;
const userInfoResp = await utils_1.doGetRequest("https://api.github.com/user", undefined, headers);
if (userInfoResp.status >= 400) {
throw new Error(`Getting userInfo failed with ${userInfoResp.status}: ${await userInfoResp.text()}`);
throw new Error(
`Getting userInfo failed with ${userInfoResp.status}: ${await userInfoResp.response.text()}`
);
}
const userInfo = await userInfoResp.json();
rawResponse.user = userInfo;
rawResponse.user = userInfoResp.response;
const rawUserInfoFromProvider = {
fromUserInfoAPI: rawResponse,
fromIdTokenPayload: {},
Expand Down
48 changes: 44 additions & 4 deletions lib/build/recipe/thirdparty/providers/linkedin.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ var __importDefault =
return mod && mod.__esModule ? mod : { default: mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
*
* This software is licensed under the Apache License, Version 2.0 (the
* "License") as published by the Apache Software Foundation.
*
* You may not use this file except in compliance with the License. You may
* obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
const logger_1 = require("../../../logger");
const custom_1 = __importDefault(require("./custom"));
const utils_1 = require("./utils");
function Linkedin(input) {
Expand Down Expand Up @@ -44,19 +59,44 @@ function Linkedin(input) {
undefined,
headers
);
rawUserInfoFromProvider.fromUserInfoAPI = userInfoFromAccessToken;
rawUserInfoFromProvider.fromUserInfoAPI = userInfoFromAccessToken.response;
if (userInfoFromAccessToken.status >= 400) {
logger_1.logDebugMessage(
`Received response with status ${
userInfoFromAccessToken.status
} and body ${await userInfoFromAccessToken.response.clone().text()}`
);
throw new Error(
`Received response with status ${
userInfoFromAccessToken.status
} and body ${await userInfoFromAccessToken.response.clone().text()}`
);
}
const emailAPIURL = "https://api.linkedin.com/v2/emailAddress";
const userInfoFromEmail = await utils_1.doGetRequest(
emailAPIURL,
{ q: "members", projection: "(elements*(handle~))" },
headers
);
if (userInfoFromEmail.elements && userInfoFromEmail.elements.length > 0) {
rawUserInfoFromProvider.fromUserInfoAPI.email = userInfoFromEmail.elements[0]["handle~"].emailAddress;
if (userInfoFromEmail.status >= 400) {
logger_1.logDebugMessage(
`Received response with status ${
userInfoFromEmail.status
} and body ${await userInfoFromEmail.response.clone().text()}`
);
throw new Error(
`Received response with status ${
userInfoFromEmail.status
} and body ${await userInfoFromEmail.response.clone().text()}`
);
}
if (userInfoFromEmail.response.elements && userInfoFromEmail.response.elements.length > 0) {
rawUserInfoFromProvider.fromUserInfoAPI.email =
userInfoFromEmail.response.elements[0]["handle~"].emailAddress;
}
rawUserInfoFromProvider.fromUserInfoAPI = Object.assign(
Object.assign({}, rawUserInfoFromProvider.fromUserInfoAPI),
userInfoFromEmail
userInfoFromEmail.response
);
return {
thirdPartyUserId: rawUserInfoFromProvider.fromUserInfoAPI.id,
Expand Down
38 changes: 35 additions & 3 deletions lib/build/recipe/thirdparty/providers/twitter.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,21 @@ var __importStar =
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
/* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
*
* This software is licensed under the Apache License, Version 2.0 (the
* "License") as published by the Apache Software Foundation.
*
* You may not use this file except in compliance with the License. You may
* obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
const logger_1 = require("../../../logger");
const custom_1 = __importStar(require("./custom"));
const utils_1 = require("./utils");
function Twitter(input) {
Expand Down Expand Up @@ -101,9 +116,26 @@ function Twitter(input) {
},
originalImplementation.config.tokenEndpointBodyParams
);
return await utils_1.doPostRequest(originalImplementation.config.tokenEndpoint, twitterOauthTokenParams, {
Authorization: `Basic ${basicAuthToken}`,
});
const tokenResponse = await utils_1.doPostRequest(
originalImplementation.config.tokenEndpoint,
twitterOauthTokenParams,
{
Authorization: `Basic ${basicAuthToken}`,
}
);
if (tokenResponse.status >= 400) {
logger_1.logDebugMessage(
`Received response with status ${
tokenResponse.status
} and body ${await tokenResponse.response.clone().text()}`
);
throw new Error(
`Received response with status ${
tokenResponse.status
} and body ${await tokenResponse.response.clone().text()}`
);
}
return tokenResponse.response;
};
if (oOverride !== undefined) {
originalImplementation = oOverride(originalImplementation);
Expand Down
10 changes: 8 additions & 2 deletions lib/build/recipe/thirdparty/providers/utils.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ export declare function doGetRequest(
headers?: {
[key: string]: string;
}
): Promise<any>;
): Promise<{
response: any;
status: number;
}>;
export declare function doPostRequest(
url: string,
params: {
Expand All @@ -18,7 +21,10 @@ export declare function doPostRequest(
headers?: {
[key: string]: string;
}
): Promise<any>;
): Promise<{
response: any;
status: number;
}>;
export declare function verifyIdTokenFromJWKSEndpointAndGetPayload(
idToken: string,
jwks: jose.JWTVerifyGetKey,
Expand Down
Loading

0 comments on commit 37235ea

Please sign in to comment.