From 9f82220f4ef54430c0512f1c6ca30671ae4c52bb Mon Sep 17 00:00:00 2001 From: Tuan Dang <dangtony98@gmail.com> Date: Fri, 9 Dec 2022 10:59:54 -0500 Subject: [PATCH] Remove frontend/backend sync operation for envars to integrations in favor of bot --- .../src/controllers/integrationController.ts | 51 ------------- backend/src/routes/integration.ts | 14 ---- .../utilities/secrets/pushKeysIntegration.js | 74 ------------------- .../integrations/ChangeHerokuConfigVars.js | 25 ------- frontend/pages/dashboard/[id].js | 24 ------ frontend/pages/integrations/[id].js | 25 +------ 6 files changed, 2 insertions(+), 211 deletions(-) delete mode 100644 frontend/components/utilities/secrets/pushKeysIntegration.js delete mode 100644 frontend/pages/api/integrations/ChangeHerokuConfigVars.js diff --git a/backend/src/controllers/integrationController.ts b/backend/src/controllers/integrationController.ts index df3fa5026..f6f1aa3a2 100644 --- a/backend/src/controllers/integrationController.ts +++ b/backend/src/controllers/integrationController.ts @@ -49,57 +49,6 @@ export const getIntegrations = async (req: Request, res: Response) => { }); }; -/** - * Sync secrets [secrets] to integration with id [integrationId] - * @param req - * @param res - * @returns - */ -export const syncIntegration = async (req: Request, res: Response) => { - // NOTE TO ALL DEVS: THIS FUNCTION IS BEING DEPRECATED. IGNORE IT BUT KEEP IT FOR NOW. - - return; - - try { - const { key, secrets }: { key: Key; secrets: PushSecret[] } = req.body; - const symmetricKey = decryptAsymmetric({ - ciphertext: key.encryptedKey, - nonce: key.nonce, - publicKey: req.user.publicKey, - privateKey: PRIVATE_KEY - }); - - // decrypt secrets with symmetric key - const content = decryptSecrets({ - secrets, - key: symmetricKey, - format: 'object' - }); - - // TODO: make integration work for other integrations as well - const res = await axios.patch( - `https://api.heroku.com/apps/${req.integration.app}/config-vars`, - content, - { - headers: { - Accept: 'application/vnd.heroku+json; version=3', - Authorization: 'Bearer ' + req.accessToken - } - } - ); - } catch (err) { - Sentry.setUser(null); - Sentry.captureException(err); - return res.status(400).send({ - message: 'Failed to sync secrets with integration' - }); - } - - return res.status(200).send({ - message: 'Successfully synced secrets with integration' - }); -}; - /** * Change environment or name of integration with id [integrationId] * @param req diff --git a/backend/src/routes/integration.ts b/backend/src/routes/integration.ts index 38b774ecb..0808973f7 100644 --- a/backend/src/routes/integration.ts +++ b/backend/src/routes/integration.ts @@ -11,20 +11,6 @@ import { integrationController } from '../controllers'; router.get('/integrations', requireAuth, integrationController.getIntegrations); -router.post( // TODO: deprecate - '/:integrationId/sync', - requireAuth, - requireIntegrationAuth({ - acceptedRoles: [ADMIN, MEMBER], - acceptedStatuses: [GRANTED] - }), - param('integrationId').exists().trim(), - body('key').exists(), - body('secrets').exists(), - validateRequest, - integrationController.syncIntegration -); - router.patch( '/:integrationId', requireAuth, diff --git a/frontend/components/utilities/secrets/pushKeysIntegration.js b/frontend/components/utilities/secrets/pushKeysIntegration.js deleted file mode 100644 index 5b08748e7..000000000 --- a/frontend/components/utilities/secrets/pushKeysIntegration.js +++ /dev/null @@ -1,74 +0,0 @@ -import publicKeyInfical from "~/pages/api/auth/publicKeyInfisical"; -import changeHerokuConfigVars from "~/pages/api/integrations/ChangeHerokuConfigVars"; - -const crypto = require("crypto"); -const { - encryptSymmetric, - encryptAssymmetric, -} = require("../cryptography/crypto"); -const nacl = require("tweetnacl"); -nacl.util = require("tweetnacl-util"); - -const pushKeysIntegration = async ({ obj, integrationId }) => { - const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY"); - - let randomBytes = crypto.randomBytes(16).toString("hex"); - - const secrets = Object.keys(obj).map((key) => { - // encrypt key - const { - ciphertext: ciphertextKey, - iv: ivKey, - tag: tagKey, - } = encryptSymmetric({ - plaintext: key, - key: randomBytes, - }); - - // encrypt value - const { - ciphertext: ciphertextValue, - iv: ivValue, - tag: tagValue, - } = encryptSymmetric({ - plaintext: obj[key], - key: randomBytes, - }); - - const visibility = "shared"; - - return { - ciphertextKey, - ivKey, - tagKey, - hashKey: crypto.createHash("sha256").update(key).digest("hex"), - ciphertextValue, - ivValue, - tagValue, - hashValue: crypto.createHash("sha256").update(obj[key]).digest("hex"), - type: visibility, - }; - }); - - // obtain public keys of all receivers (i.e. members in workspace) - let publicKeyInfisical = await publicKeyInfical(); - - publicKeyInfisical = (await publicKeyInfisical.json()).publicKey; - - // assymmetrically encrypt key with each receiver public keys - - const { ciphertext, nonce } = encryptAssymmetric({ - plaintext: randomBytes, - publicKey: publicKeyInfisical, - privateKey: PRIVATE_KEY, - }); - - const key = { - encryptedKey: ciphertext, - nonce, - }; - - changeHerokuConfigVars({ integrationId, key, secrets }); -}; - -export default pushKeysIntegration; diff --git a/frontend/pages/api/integrations/ChangeHerokuConfigVars.js b/frontend/pages/api/integrations/ChangeHerokuConfigVars.js deleted file mode 100644 index 118848ae6..000000000 --- a/frontend/pages/api/integrations/ChangeHerokuConfigVars.js +++ /dev/null @@ -1,25 +0,0 @@ -import SecurityClient from "~/utilities/SecurityClient"; - -const changeHerokuConfigVars = ({ integrationId, key, secrets }) => { - return SecurityClient.fetchCall( - "/api/v1/integration/" + integrationId + "/sync", - { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - key, - secrets, - }), - } - ).then(async (res) => { - if (res.status == 200) { - return res; - } else { - console.log("Failed to sync secrets to Heroku"); - } - }); -}; - -export default changeHerokuConfigVars; diff --git a/frontend/pages/dashboard/[id].js b/frontend/pages/dashboard/[id].js index bec6849ad..aa99a91ed 100644 --- a/frontend/pages/dashboard/[id].js +++ b/frontend/pages/dashboard/[id].js @@ -32,7 +32,6 @@ import DropZone from "~/components/dashboard/DropZone"; import NavHeader from "~/components/navigation/NavHeader"; import getSecretsForProject from "~/components/utilities/secrets/getSecretsForProject"; import pushKeys from "~/components/utilities/secrets/pushKeys"; -import pushKeysIntegration from "~/components/utilities/secrets/pushKeysIntegration"; import guidGenerator from "~/utilities/randomId"; import { envMapping } from "../../public/data/frequentConstants"; @@ -401,29 +400,6 @@ export default function Dashboard() { setButtonReady(false); pushKeys({ obj, workspaceId: router.query.id, env }); - /** - * Check which integrations are active for this project and environment - * If there are any, update environment variables for those integrations - */ - let integrations = await getWorkspaceIntegrations({ - workspaceId: router.query.id, - }); - integrations.map(async (integration) => { - if ( - envMapping[env] == integration.environment && - integration.isActive == true - ) { - let objIntegration = Object.assign( - {}, - ...data.map((row) => ({ [row[2]]: row[3] })) - ); - await pushKeysIntegration({ - obj: objIntegration, - integrationId: integration._id, - }); - } - }); - // If this user has never saved environment variables before, show them a prompt to read docs if (!hasUserEverPushed) { setCheckDocsPopUpVisible(true); diff --git a/frontend/pages/integrations/[id].js b/frontend/pages/integrations/[id].js index a5603985d..de5af1e4d 100644 --- a/frontend/pages/integrations/[id].js +++ b/frontend/pages/integrations/[id].js @@ -14,7 +14,6 @@ import Button from "~/components/basic/buttons/Button"; import ListBox from "~/components/basic/Listbox"; import NavHeader from "~/components/navigation/NavHeader"; import getSecretsForProject from "~/components/utilities/secrets/getSecretsForProject"; -import pushKeysIntegration from "~/components/utilities/secrets/pushKeysIntegration"; import guidGenerator from "~/utilities/randomId"; import { @@ -126,27 +125,7 @@ const Integration = ({ projectIntegration }) => { environment: envMapping[integrationEnvironment], appName: integrationApp, }); - if (result?.status == 200) { - let currentSecrets = await getSecretsForProject({ - env: integrationEnvironment, - setFileState, - setIsKeyAvailable, - setData, - workspaceId: router.query.id, - }); - - let obj = Object.assign( - {}, - ...currentSecrets.map((row) => ({ - [row[2]]: row[3], - })) - ); - await pushKeysIntegration({ - obj, - integrationId: projectIntegration._id, - }); - router.reload(); - } + router.reload(); }} color="mineshaft" size="md" @@ -331,7 +310,7 @@ export default function Integrations() { <a href={`${ ["Heroku"].includes(integrations[integration].name) - ? `https://id.heroku.com/oauth/authorize?client_id=bc132901-935a-4590-b010-f1857efc380d&response_type=code&scope=write-protected&state=${csrfToken}` + ? `https://id.heroku.com/oauth/authorize?client_id=7b1311a1-1cb2-4938-8adf-f37a399ec41b&response_type=code&scope=write-protected&state=${csrfToken}` : "#" }`} rel="noopener"