From 994a842b7cc2094b386e10c4703fa54eef990e47 Mon Sep 17 00:00:00 2001 From: Siddharth Bhansali Date: Mon, 16 Jun 2025 17:30:58 +0530 Subject: [PATCH 1/4] feat: asana oauth configuration --- oauth/src/connections/asana/init.ts | 48 +++++++++++++++++++++++++ oauth/src/connections/asana/refresh.ts | 50 ++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 oauth/src/connections/asana/init.ts create mode 100644 oauth/src/connections/asana/refresh.ts diff --git a/oauth/src/connections/asana/init.ts b/oauth/src/connections/asana/init.ts new file mode 100644 index 00000000..1c95092e --- /dev/null +++ b/oauth/src/connections/asana/init.ts @@ -0,0 +1,48 @@ +import axios from 'axios'; +import qs from 'qs'; +import { DataObject, OAuthResponse } from '../../lib/types'; + +export const init = async ({ body }: DataObject): Promise => { + try { + const { + clientId: client_id, + clientSecret: client_secret, + metadata: { code, redirectUri: redirect_uri }, + } = body; + + const requestBody = { + grant_type: 'authorization_code', + code, + client_id, + client_secret, + redirect_uri, + }; + + const response = await axios({ + url: 'https://app.asana.com/-/oauth_token', + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Accept: 'application/json', + }, + data: qs.stringify(requestBody), + }); + + const { + access_token: accessToken, + refresh_token: refreshToken, + token_type: tokenType, + expires_in: expiresIn, + } = response.data; + + return { + accessToken, + refreshToken, + expiresIn, + tokenType: tokenType === 'bearer' ? 'Bearer' : tokenType, + meta: {}, + }; + } catch (error) { + throw new Error(`Error fetching access token for Asana: ${error}`); + } +}; diff --git a/oauth/src/connections/asana/refresh.ts b/oauth/src/connections/asana/refresh.ts new file mode 100644 index 00000000..1e5a8c17 --- /dev/null +++ b/oauth/src/connections/asana/refresh.ts @@ -0,0 +1,50 @@ +import axios from 'axios'; +import qs from 'qs'; +import { DataObject, OAuthResponse } from '../../lib/types'; + +export const refresh = async ({ body }: DataObject): Promise => { + try { + const { + OAUTH_CLIENT_ID: client_id, + OAUTH_CLIENT_SECRET: client_secret, + OAUTH_REFRESH_TOKEN: refresh_token, + OAUTH_METADATA: { meta }, + OAUTH_REQUEST_PAYLOAD: { redirectUri: redirect_uri }, + } = body; + + const requestBody = { + grant_type: 'refresh_token', + refresh_token, + client_id, + client_secret, + redirect_uri, + }; + + const response = await axios({ + url: 'https://app.asana.com/-/oauth_token', + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Accept: 'application/json', + }, + data: qs.stringify(requestBody), + }); + + const { + access_token: accessToken, + refresh_token: refreshToken, + token_type: tokenType, + expires_in: expiresIn, + } = response.data; + + return { + accessToken, + refreshToken, + expiresIn, + tokenType: tokenType === 'bearer' ? 'Bearer' : tokenType, + meta, + }; + } catch (error) { + throw new Error(`Error fetching access token for Asana: ${error}`); + } +}; From f267d9131d000b5bda0255a4a61be7ca53a616dd Mon Sep 17 00:00:00 2001 From: Siddharth Bhansali Date: Tue, 17 Jun 2025 16:12:43 +0530 Subject: [PATCH 2/4] fix: asana refresh --- oauth/src/connections/asana/refresh.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/oauth/src/connections/asana/refresh.ts b/oauth/src/connections/asana/refresh.ts index 1e5a8c17..2b3acb31 100644 --- a/oauth/src/connections/asana/refresh.ts +++ b/oauth/src/connections/asana/refresh.ts @@ -32,14 +32,13 @@ export const refresh = async ({ body }: DataObject): Promise => { const { access_token: accessToken, - refresh_token: refreshToken, token_type: tokenType, expires_in: expiresIn, } = response.data; return { accessToken, - refreshToken, + refreshToken: refresh_token, expiresIn, tokenType: tokenType === 'bearer' ? 'Bearer' : tokenType, meta, From aed2c4321d87776416ec0916ebbeeacd764394d2 Mon Sep 17 00:00:00 2001 From: Siddharth Bhansali Date: Thu, 19 Jun 2025 13:52:56 +0530 Subject: [PATCH 3/4] feat: jira oauth configuration --- oauth/src/connections/jira/init.ts | 41 +++++++++++++++++++++++++++ oauth/src/connections/jira/refresh.ts | 41 +++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 oauth/src/connections/jira/init.ts create mode 100644 oauth/src/connections/jira/refresh.ts diff --git a/oauth/src/connections/jira/init.ts b/oauth/src/connections/jira/init.ts new file mode 100644 index 00000000..94a9532d --- /dev/null +++ b/oauth/src/connections/jira/init.ts @@ -0,0 +1,41 @@ +import axios from 'axios'; +import { DataObject, OAuthResponse } from '../../lib/types'; + +export const init = async ({ body }: DataObject): Promise => { + try { + const { + clientId: client_id, + clientSecret: client_secret, + metadata: { code, redirectUri: redirect_uri }, + } = body; + + const response = await axios({ + url: 'https://auth.atlassian.com/oauth/token', + method: 'POST', + params: { + grant_type: 'authorization_code', + code, + client_id, + client_secret, + redirect_uri, + }, + }); + + const { + access_token: accessToken, + refresh_token: refreshToken, + token_type: tokenType, + expires_in: expiresIn, + } = response.data; + + return { + accessToken, + refreshToken, + expiresIn, + tokenType: tokenType === 'bearer' ? 'Bearer' : tokenType, + meta: {}, + }; + } catch (error) { + throw new Error(`Error fetching access token for Jira: ${error}`); + } +}; diff --git a/oauth/src/connections/jira/refresh.ts b/oauth/src/connections/jira/refresh.ts new file mode 100644 index 00000000..aeea41e4 --- /dev/null +++ b/oauth/src/connections/jira/refresh.ts @@ -0,0 +1,41 @@ +import axios from 'axios'; +import { DataObject, OAuthResponse } from '../../lib/types'; + +export const refresh = async ({ body }: DataObject): Promise => { + try { + const { + OAUTH_CLIENT_ID: client_id, + OAUTH_CLIENT_SECRET: client_secret, + OAUTH_REFRESH_TOKEN: refresh_token, + OAUTH_METADATA: { meta }, + } = body; + + const response = await axios({ + url: 'https://auth.atlassian.com/oauth/token', + method: 'POST', + params: { + grant_type: 'refresh_token', + refresh_token, + client_id, + client_secret, + }, + }); + + const { + access_token: accessToken, + refresh_token: refreshToken, + token_type: tokenType, + expires_in: expiresIn, + } = response.data; + + return { + accessToken, + refreshToken, + expiresIn, + tokenType: tokenType === 'bearer' ? 'Bearer' : tokenType, + meta, + }; + } catch (error) { + throw new Error(`Error fetching access token for Jira: ${error}`); + } +}; From 8f7e433fda857dbef9fe98a61ce7d55d660cef94 Mon Sep 17 00:00:00 2001 From: Siddharth Bhansali Date: Thu, 19 Jun 2025 14:27:50 +0530 Subject: [PATCH 4/4] feat: puzzle io oauth configuration --- oauth/src/connections/puzzleIo/init.ts | 49 +++++++++++++++++++++++ oauth/src/connections/puzzleIo/refresh.ts | 49 +++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 oauth/src/connections/puzzleIo/init.ts create mode 100644 oauth/src/connections/puzzleIo/refresh.ts diff --git a/oauth/src/connections/puzzleIo/init.ts b/oauth/src/connections/puzzleIo/init.ts new file mode 100644 index 00000000..8a8d8120 --- /dev/null +++ b/oauth/src/connections/puzzleIo/init.ts @@ -0,0 +1,49 @@ +import axios from 'axios'; +import { DataObject, OAuthResponse } from '../../lib/types'; + +export const init = async ({ body }: DataObject): Promise => { + try { + const { + clientId: client_id, + clientSecret: client_secret, + metadata: { code, redirectUri: redirect_uri, environment }, + } = body; + + const baseUrl: string = + environment === 'test' + ? 'https://staging.southparkdata.com' + : 'https://api.puzzle.io'; + + const response = await axios({ + url: `${baseUrl}/oauth/token`, + method: 'POST', + data: { + grant_type: 'authorization_code', + code, + client_id, + client_secret, + redirect_uri, + }, + }); + + const { + access_token: accessToken, + refresh_token: refreshToken, + token_type: tokenType, + expires_in: expiresIn, + } = response.data; + + return { + accessToken, + refreshToken, + expiresIn, + tokenType: tokenType === 'bearer' ? 'Bearer' : tokenType, + meta: { + environment, + PUZZLE_BASE_URL: baseUrl, + }, + }; + } catch (error) { + throw new Error(`Error fetching access token for Puzzle.io: ${error}`); + } +}; diff --git a/oauth/src/connections/puzzleIo/refresh.ts b/oauth/src/connections/puzzleIo/refresh.ts new file mode 100644 index 00000000..ecf5a3df --- /dev/null +++ b/oauth/src/connections/puzzleIo/refresh.ts @@ -0,0 +1,49 @@ +import axios from 'axios'; +import { DataObject, OAuthResponse } from '../../lib/types'; + +export const refresh = async ({ body }: DataObject): Promise => { + try { + const { + OAUTH_CLIENT_ID: client_id, + OAUTH_CLIENT_SECRET: client_secret, + OAUTH_REFRESH_TOKEN: refresh_token, + OAUTH_REQUEST_PAYLOAD: { redirectUri: redirect_uri }, + OAUTH_METADATA: { meta }, + } = body; + + const { environment } = meta; + + const baseUrl: string = + environment === 'test' + ? 'https://staging.southparkdata.com' + : 'https://api.puzzle.io'; + + const response = await axios({ + url: `${baseUrl}/oauth/token`, + method: 'POST', + data: { + grant_type: 'refresh_token', + refresh_token, + client_id, + client_secret, + redirect_uri, + }, + }); + + const { + access_token: accessToken, + token_type: tokenType, + expires_in: expiresIn, + } = response.data; + + return { + accessToken, + refreshToken: refresh_token, + expiresIn, + tokenType: tokenType === 'bearer' ? 'Bearer' : tokenType, + meta, + }; + } catch (error) { + throw new Error(`Error fetching access token for Puzzle.io: ${error}`); + } +};