From 200bb12ad8057073a57bd9ac0d12412724c2cb53 Mon Sep 17 00:00:00 2001 From: Tuan Dang Date: Sun, 18 Dec 2022 16:10:58 -0500 Subject: [PATCH] Move CLIENT_ID envars to be fetched from backend for (cloud) integration options --- backend/src/config/index.ts | 2 + .../controllers/integrationAuthController.ts | 11 ++- backend/src/routes/integrationAuth.ts | 6 ++ backend/src/variables/index.ts | 6 +- backend/src/variables/integration.ts | 81 +++++++++++++++++++ docker-compose.dev.yml | 2 - docker-compose.yml | 2 - .../api/integrations/GetIntegrationOptions.ts | 21 +++++ frontend/pages/integrations/[id].js | 25 ++++-- frontend/public/data/cloudIntegrations.js | 81 ------------------- frontend/public/json/cloudIntegrations.json | 75 ----------------- 11 files changed, 141 insertions(+), 171 deletions(-) create mode 100644 frontend/pages/api/integrations/GetIntegrationOptions.ts delete mode 100644 frontend/public/data/cloudIntegrations.js delete mode 100644 frontend/public/json/cloudIntegrations.json diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 7c23bee4a..09d384771 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -11,6 +11,7 @@ const JWT_SIGNUP_SECRET = process.env.JWT_SIGNUP_SECRET!; const MONGO_URL = process.env.MONGO_URL!; const NODE_ENV = process.env.NODE_ENV! || 'production'; const CLIENT_SECRET_HEROKU = process.env.CLIENT_SECRET_HEROKU!; +const CLIENT_ID_HEROKU = process.env.CLIENT_ID_HEROKU!; const CLIENT_ID_VERCEL = process.env.CLIENT_ID_VERCEL!; const CLIENT_ID_NETLIFY = process.env.CLIENT_ID_NETLIFY!; const CLIENT_SECRET_VERCEL = process.env.CLIENT_SECRET_VERCEL!; @@ -49,6 +50,7 @@ export { JWT_SIGNUP_SECRET, MONGO_URL, NODE_ENV, + CLIENT_ID_HEROKU, CLIENT_ID_VERCEL, CLIENT_ID_NETLIFY, CLIENT_SECRET_HEROKU, diff --git a/backend/src/controllers/integrationAuthController.ts b/backend/src/controllers/integrationAuthController.ts index fc2767e0a..c242c239a 100644 --- a/backend/src/controllers/integrationAuthController.ts +++ b/backend/src/controllers/integrationAuthController.ts @@ -3,10 +3,19 @@ import * as Sentry from '@sentry/node'; import axios from 'axios'; import { readFileSync } from 'fs'; import { IntegrationAuth, Integration } from '../models'; -import { INTEGRATION_SET, ENV_DEV } from '../variables'; +import { INTEGRATION_SET, INTEGRATION_OPTIONS, ENV_DEV } from '../variables'; import { IntegrationService } from '../services'; import { getApps, revokeAccess } from '../integrations'; +export const getIntegrationOptions = async ( + req: Request, + res: Response +) => { + return res.status(200).send({ + integrationOptions: INTEGRATION_OPTIONS + }); +} + /** * Perform OAuth2 code-token exchange as part of integration [integration] for workspace with id [workspaceId] * @param req diff --git a/backend/src/routes/integrationAuth.ts b/backend/src/routes/integrationAuth.ts index 159d31934..ef80a2dcc 100644 --- a/backend/src/routes/integrationAuth.ts +++ b/backend/src/routes/integrationAuth.ts @@ -10,6 +10,12 @@ import { import { ADMIN, MEMBER, GRANTED } from '../variables'; import { integrationAuthController } from '../controllers'; +router.get( + '/integration-options', + requireAuth, + integrationAuthController.getIntegrationOptions +); + router.post( '/oauth-token', requireAuth, diff --git a/backend/src/variables/index.ts b/backend/src/variables/index.ts index 362635806..b21324423 100644 --- a/backend/src/variables/index.ts +++ b/backend/src/variables/index.ts @@ -16,7 +16,8 @@ import { INTEGRATION_NETLIFY_TOKEN_URL, INTEGRATION_HEROKU_API_URL, INTEGRATION_VERCEL_API_URL, - INTEGRATION_NETLIFY_API_URL + INTEGRATION_NETLIFY_API_URL, + INTEGRATION_OPTIONS } from './integration'; import { OWNER, @@ -73,5 +74,6 @@ export { INTEGRATION_NETLIFY_API_URL, EVENT_PUSH_SECRETS, EVENT_PULL_SECRETS, - ACTION_PUSH_TO_HEROKU + ACTION_PUSH_TO_HEROKU, + INTEGRATION_OPTIONS }; \ No newline at end of file diff --git a/backend/src/variables/integration.ts b/backend/src/variables/integration.ts index 1dd721a11..c02a2389f 100644 --- a/backend/src/variables/integration.ts +++ b/backend/src/variables/integration.ts @@ -1,3 +1,8 @@ +import { + CLIENT_ID_HEROKU, + CLIENT_ID_NETLIFY +} from '../config'; + // integrations const INTEGRATION_HEROKU = 'heroku'; const INTEGRATION_VERCEL = 'vercel'; @@ -21,6 +26,81 @@ const INTEGRATION_HEROKU_API_URL = 'https://api.heroku.com'; const INTEGRATION_VERCEL_API_URL = 'https://api.vercel.com'; const INTEGRATION_NETLIFY_API_URL = 'https://api.netlify.com'; +const INTEGRATION_OPTIONS = [ + { + name: 'Heroku', + slug: 'heroku', + image: 'Heroku', + isAvailable: true, + type: 'oauth2', + clientId: CLIENT_ID_HEROKU, + docsLink: '' + }, + { + name: 'Vercel', + slug: 'vercel', + image: 'Vercel', + isAvailable: true, + type: 'vercel', + clientId: '', + docsLink: '' + }, + { + name: 'Netlify', + slug: 'netlify', + image: 'Netlify', + isAvailable: true, + type: 'oauth2', + clientId: CLIENT_ID_NETLIFY, + docsLink: '' + }, + { + name: 'Google Cloud Platform', + slug: 'gcp', + image: 'Google Cloud Platform', + isAvailable: false, + type: '', + clientId: '', + docsLink: '' + }, + { + name: 'Amazon Web Services', + slug: 'aws', + image: 'Amazon Web Services', + isAvailable: false, + type: '', + clientId: '', + docsLink: '' + }, + { + name: 'Microsoft Azure', + slug: 'azure', + image: 'Microsoft Azure', + isAvailable: false, + type: '', + clientId: '', + docsLink: '' + }, + { + name: 'Travis CI', + slug: 'travisci', + image: 'Travis CI', + isAvailable: false, + type: '', + clientId: '', + docsLink: '' + }, + { + name: 'Circle CI', + slug: 'circleci', + image: 'Circle CI', + isAvailable: false, + type: '', + clientId: '', + docsLink: '' + } +] + export { INTEGRATION_HEROKU, INTEGRATION_VERCEL, @@ -33,4 +113,5 @@ export { INTEGRATION_HEROKU_API_URL, INTEGRATION_VERCEL_API_URL, INTEGRATION_NETLIFY_API_URL, + INTEGRATION_OPTIONS } \ No newline at end of file diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 2a21e7ed3..15a200783 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -54,8 +54,6 @@ services: - INFISICAL_TELEMETRY_ENABLED=${TELEMETRY_ENABLED} - NEXT_PUBLIC_STRIPE_PRODUCT_PRO=${STRIPE_PRODUCT_PRO} - NEXT_PUBLIC_STRIPE_PRODUCT_STARTER=${STRIPE_PRODUCT_STARTER} - - NEXT_PUBLIC_CLIENT_ID_HEROKU=${CLIENT_ID_HEROKU} - - NEXT_PUBLIC_CLIENT_ID_NETLIFY=${CLIENT_ID_NETLIFY} networks: - infisical-dev diff --git a/docker-compose.yml b/docker-compose.yml index 9fce7010a..bd9022cef 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,8 +41,6 @@ services: - INFISICAL_TELEMETRY_ENABLED=${TELEMETRY_ENABLED} - NEXT_PUBLIC_STRIPE_PRODUCT_PRO=${STRIPE_PRODUCT_PRO} - NEXT_PUBLIC_STRIPE_PRODUCT_STARTER=${STRIPE_PRODUCT_STARTER} - - NEXT_PUBLIC_CLIENT_ID_HEROKU=${CLIENT_ID_HEROKU} - - NEXT_PUBLIC_CLIENT_ID_NETLIFY=${CLIENT_ID_NETLIFY} networks: - infisical diff --git a/frontend/pages/api/integrations/GetIntegrationOptions.ts b/frontend/pages/api/integrations/GetIntegrationOptions.ts new file mode 100644 index 000000000..caf0c8626 --- /dev/null +++ b/frontend/pages/api/integrations/GetIntegrationOptions.ts @@ -0,0 +1,21 @@ +import SecurityClient from '~/utilities/SecurityClient'; + +const getIntegrationOptions = () => { + return SecurityClient.fetchCall( + '/api/v1/integration-auth/integration-options', + { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + } + } + ).then(async (res) => { + if (res && res.status == 200) { + return (await res.json()).integrationOptions; + } else { + console.log('Failed to get (cloud) integration options'); + } + }); +}; + +export default getIntegrationOptions; diff --git a/frontend/pages/integrations/[id].js b/frontend/pages/integrations/[id].js index 734df7d95..eb367f6c7 100644 --- a/frontend/pages/integrations/[id].js +++ b/frontend/pages/integrations/[id].js @@ -8,10 +8,9 @@ import FrameworkIntegrationSection from "~/components/integrations/FrameworkInte import CloudIntegrationSection from "~/components/integrations/CloudIntegrationSection"; import IntegrationSection from "~/components/integrations/IntegrationSection"; import frameworkIntegrationOptions from "../../public/json/frameworkIntegrations.json"; -// import cloudIntegrationOptions from "../../public/json/cloudIntegrations.json"; -import { cloudIntegrationOptions } from "../../public/data/cloudIntegrations"; import getWorkspaceAuthorizations from "../api/integrations/getWorkspaceAuthorizations"; import getWorkspaceIntegrations from "../api/integrations/getWorkspaceIntegrations"; +import getIntegrationOptions from "../api/integrations/GetIntegrationOptions"; import getBot from "../api/bot/getBot"; import setBotActiveStatus from "../api/bot/setBotActiveStatus"; import getLatestFileKey from "../api/workspace/getLatestFileKey"; @@ -26,6 +25,7 @@ const crypto = require("crypto"); import axios from "axios"; export default function Integrations() { + const [cloudIntegrationOptions, setCloudIntegrationOptions] = useState([]); const [integrationAuths, setIntegrationAuths] = useState([]); const [integrations, setIntegrations] = useState([]); const [bot, setBot] = useState(null); @@ -37,6 +37,11 @@ export default function Integrations() { useEffect(async () => { try { + // get cloud integration options + setCloudIntegrationOptions( + await getIntegrationOptions() + ); + // get project integration authorizations setIntegrationAuths( await getWorkspaceAuthorizations({ @@ -201,12 +206,16 @@ export default function Integrations() { handleIntegrationOption={handleIntegrationOption} /> */} - + {cloudIntegrationOptions.length > 0 ? ( + + ) : ( +
+ )} diff --git a/frontend/public/data/cloudIntegrations.js b/frontend/public/data/cloudIntegrations.js deleted file mode 100644 index 694b4d519..000000000 --- a/frontend/public/data/cloudIntegrations.js +++ /dev/null @@ -1,81 +0,0 @@ -import { - CLIENT_ID_HEROKU, - CLIENT_ID_NETLIFY -} from '../../components/utilities/config'; - -const cloudIntegrationOptions = [ - { - name: 'Heroku', - slug: 'heroku', - image: 'Heroku', - isAvailable: true, - type: 'oauth2', - clientId: CLIENT_ID_HEROKU, - docsLink: '' - }, - { - name: 'Vercel', - slug: 'vercel', - image: 'Vercel', - isAvailable: true, - type: 'vercel', - clientId: '', - docsLink: '' - }, - { - name: 'Netlify', - slug: 'netlify', - image: 'Netlify', - isAvailable: true, - type: 'oauth2', - clientId: CLIENT_ID_NETLIFY, - docsLink: '' - }, - { - name: 'Google Cloud Platform', - slug: 'gcp', - image: 'Google Cloud Platform', - isAvailable: false, - type: '', - clientId: '', - docsLink: '' - }, - { - name: 'Amazon Web Services', - slug: 'aws', - image: 'Amazon Web Services', - isAvailable: false, - type: '', - clientId: '', - docsLink: '' - }, - { - name: 'Microsoft Azure', - slug: 'azure', - image: 'Microsoft Azure', - isAvailable: false, - type: '', - clientId: '', - docsLink: '' - }, - { - name: 'Travis CI', - slug: 'travisci', - image: 'Travis CI', - isAvailable: false, - type: '', - clientId: '', - docsLink: '' - }, - { - name: 'Circle CI', - slug: 'circleci', - image: 'Circle CI', - isAvailable: false, - type: '', - clientId: '', - docsLink: '' - } -] - -export { cloudIntegrationOptions }; \ No newline at end of file diff --git a/frontend/public/json/cloudIntegrations.json b/frontend/public/json/cloudIntegrations.json deleted file mode 100644 index e932879d8..000000000 --- a/frontend/public/json/cloudIntegrations.json +++ /dev/null @@ -1,75 +0,0 @@ -[ - { - "name": "Heroku", - "slug": "heroku", - "image": "Heroku", - "isAvailable": true, - "type": "oauth2", - "clientId": "7b1311a1-1cb2-4938-8adf-f37a399ec41b", - "docsLink": "" - }, - { - "name": "Vercel", - "slug": "vercel", - "image": "Vercel", - "isAvailable": true, - "type": "vercel", - "clientId": "", - "docsLink": "" - }, - { - "name": "Netlify", - "slug": "netlify", - "image": "Netlify", - "isAvailable": true, - "type": "oauth2", - "clientId": "fYWBhD3gt0pT62UIwYrlGRcy--pPVLYIQad6ORrES9o", - "redirectURL": "http://localhost:8080/netlify", - "docsLink": "" - }, - { - "name": "Google Cloud Platform", - "slug": "gcp", - "image": "Google Cloud Platform", - "isAvailable": false, - "type": "", - "clientId": "", - "docsLink": "" - }, - { - "name": "Amazon Web Services", - "slug": "aws", - "image": "Amazon Web Services", - "isAvailable": false, - "type": "", - "clientId": "", - "docsLink": "" - }, - { - "name": "Microsoft Azure", - "slug": "azure", - "image": "Microsoft Azure", - "isAvailable": false, - "type": "", - "clientId": "", - "docsLink": "" - }, - { - "name": "Travis CI", - "slug": "travisci", - "image": "Travis CI", - "isAvailable": false, - "type": "", - "clientId": "", - "docsLink": "" - }, - { - "name": "Circle CI", - "slug": "circleci", - "image": "Circle CI", - "isAvailable": false, - "type": "", - "clientId": "", - "docsLink": "" - } -] \ No newline at end of file