diff --git a/frontend/components/integrations/CloudIntegration.tsx b/frontend/components/integrations/CloudIntegration.tsx index 4bdad9cf5..f3e598852 100644 --- a/frontend/components/integrations/CloudIntegration.tsx +++ b/frontend/components/integrations/CloudIntegration.tsx @@ -28,7 +28,6 @@ const CloudIntegration = ({ deleteIntegrationAuth, authorizations }: CloudIntegration) => { - console.log('cio', integration); return ( <div className={`relative ${ diff --git a/frontend/components/utilities/secrets/getSecretsForProject.ts b/frontend/components/utilities/secrets/getSecretsForProject.ts index 5a57baed8..284b8bee1 100644 --- a/frontend/components/utilities/secrets/getSecretsForProject.ts +++ b/frontend/components/utilities/secrets/getSecretsForProject.ts @@ -48,13 +48,8 @@ const getSecretsForProject = async ({ publicKey: file.key.sender.publicKey, privateKey: PRIVATE_KEY }); -<<<<<<< HEAD:frontend/components/utilities/secrets/getSecretsForProject.js - - file.secrets.map((secretPair) => { -======= file.secrets.map((secretPair: any) => { ->>>>>>> 158c51ff3cbcd9a8eab6c44e728232d79a1cbab9:frontend/components/utilities/secrets/getSecretsForProject.ts // decrypt .env file with symmetric key const plainTextKey = decryptSymmetric({ ciphertext: secretPair.secretKey.ciphertext, diff --git a/frontend/pages/api/bot/getBot.js b/frontend/pages/api/bot/getBot.ts similarity index 71% rename from frontend/pages/api/bot/getBot.js rename to frontend/pages/api/bot/getBot.ts index 465f2d189..6621dbe2f 100644 --- a/frontend/pages/api/bot/getBot.js +++ b/frontend/pages/api/bot/getBot.ts @@ -1,4 +1,8 @@ -import SecurityClient from "~/utilities/SecurityClient.js"; +import SecurityClient from "~/utilities/SecurityClient"; + +interface Props { + workspaceId: string; +} /** * This function fetches the bot for a project @@ -6,7 +10,7 @@ import SecurityClient from "~/utilities/SecurityClient.js"; * @param {String} obj.workspaceId * @returns */ -const getBot = async ({ workspaceId }) => { +const getBot = async ({ workspaceId }: Props) => { return SecurityClient.fetchCall( "/api/v1/bot/" + workspaceId, { @@ -16,7 +20,7 @@ const getBot = async ({ workspaceId }) => { } } ).then(async (res) => { - if (res.status == 200) { + if (res && res.status == 200) { return await res.json(); } else { console.log("Failed to get bot for project"); diff --git a/frontend/pages/api/bot/setBotActiveStatus.js b/frontend/pages/api/bot/setBotActiveStatus.js deleted file mode 100644 index 8e1b51f24..000000000 --- a/frontend/pages/api/bot/setBotActiveStatus.js +++ /dev/null @@ -1,31 +0,0 @@ -import SecurityClient from "~/utilities/SecurityClient.js"; - -/** - * This function fetches the bot for a project - * @param {Object} obj - * @param {String} obj.workspaceId - * @returns - */ -const setBotActiveStatus = async ({ botId, isActive, botKey }) => { - return SecurityClient.fetchCall( - "/api/v1/bot/" + botId + "/active", - { - method: "PATCH", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - isActive, - botKey - }) - } - ).then(async (res) => { - if (res.status == 200) { - return await res.json(); - } else { - console.log("Failed to get bot for project"); - } - }); -}; - -export default setBotActiveStatus; \ No newline at end of file diff --git a/frontend/pages/api/bot/setBotActiveStatus.ts b/frontend/pages/api/bot/setBotActiveStatus.ts new file mode 100644 index 000000000..e85ed3c77 --- /dev/null +++ b/frontend/pages/api/bot/setBotActiveStatus.ts @@ -0,0 +1,46 @@ +import SecurityClient from "~/utilities/SecurityClient"; + +interface BotKey { + encryptedKey: string; + nonce: string; +} + +interface Props { + botId: string; + isActive: Boolean; + botKey: BotKey; +} + +/** + * This function sets the active status of a bot and shares a copy of + * the project key (encrypted under the bot's public key) with the + * project's bot + * @param {Object} obj + * @param {String} obj.botId + * @param {String} obj.isActive + * @param {Object} obj.botKey + * @returns + */ +const setBotActiveStatus = async ({ botId, isActive, botKey }: Props) => { + return SecurityClient.fetchCall( + "/api/v1/bot/" + botId + "/active", + { + method: "PATCH", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + isActive, + botKey + }) + } + ).then(async (res) => { + if (res && res.status == 200) { + return await res.json(); + } else { + console.log("Failed to get bot for project"); + } + }); +}; + +export default setBotActiveStatus; \ No newline at end of file diff --git a/frontend/pages/dashboard/[id].js b/frontend/pages/dashboard/[id].js index c6cd4c98a..050193b1b 100644 --- a/frontend/pages/dashboard/[id].js +++ b/frontend/pages/dashboard/[id].js @@ -18,30 +18,6 @@ import { faPerson, faPlus, faShuffle, -<<<<<<< HEAD - faX, -} from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Menu, Transition } from "@headlessui/react"; - -import Button from "~/components/basic/buttons/Button"; -import ListBox from "~/components/basic/Listbox"; -import BottonRightPopup from "~/components/basic/popups/BottomRightPopup"; -import { useNotificationContext } from "~/components/context/Notifications/NotificationProvider"; -import DashboardInputField from "~/components/dashboard/DashboardInputField"; -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 guidGenerator from "~/utilities/randomId"; - -import { envMapping } from "../../public/data/frequentConstants"; -import getWorkspaceIntegrations from "../api/integrations/getWorkspaceIntegrations"; -import getUser from "../api/user/getUser"; -import checkUserAction from "../api/userActions/checkUserAction"; -import registerUserAction from "../api/userActions/registerUserAction"; -import getWorkspaces from "../api/workspace/getWorkspaces"; -======= faX } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -65,7 +41,6 @@ import getUser from '../api/user/getUser'; import checkUserAction from '../api/userActions/checkUserAction'; import registerUserAction from '../api/userActions/registerUserAction'; import getWorkspaces from '../api/workspace/getWorkspaces'; ->>>>>>> 158c51ff3cbcd9a8eab6c44e728232d79a1cbab9 /** * This component represent a single row for an environemnt variable on the dashboard @@ -426,32 +401,6 @@ export default function Dashboard() { setButtonReady(false); pushKeys({ obj, workspaceId: router.query.id, env }); -<<<<<<< HEAD -======= - /** - * 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 - }); - } - }); - ->>>>>>> 158c51ff3cbcd9a8eab6c44e728232d79a1cbab9 // 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/heroku.js b/frontend/pages/heroku.js index 82947b1b9..42e915ba4 100644 --- a/frontend/pages/heroku.js +++ b/frontend/pages/heroku.js @@ -5,6 +5,7 @@ const queryString = require("query-string"); import AuthorizeIntegration from "./api/integrations/authorizeIntegration"; export default function Heroku() { + console.log('HEROKU PAGE'); const router = useRouter(); const parsedUrl = queryString.parse(router.asPath.split("?")[1]); const code = parsedUrl.code; @@ -16,7 +17,11 @@ export default function Heroku() { // eslint-disable-next-line react-hooks/exhaustive-deps useEffect(async () => { try { + console.log('A'); + console.log(state); + console.log(localStorage.getItem('latestCSRFToken')); if (state == localStorage.getItem("latestCSRFToken")) { + console.log('B'); await AuthorizeIntegration({ workspaceId: localStorage.getItem("projectData.id"), code, @@ -25,6 +30,7 @@ export default function Heroku() { router.push("/integrations/" + localStorage.getItem("projectData.id")); } } catch (error) { + console.error(error); console.log("Error - Not logged in yet"); } // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/frontend/pages/integrations/[id].js b/frontend/pages/integrations/[id].js index d6363d089..a301deda7 100644 --- a/frontend/pages/integrations/[id].js +++ b/frontend/pages/integrations/[id].js @@ -74,38 +74,38 @@ export default function Integrations() { * 4. Send encrypted project key to backend and set bot status to active */ const handleBotActivate = async () => { + let botKey; try { - const key = await getLatestFileKey({ workspaceId: router.query.id }); if (bot) { // case: there is a bot - const PRIVATE_KEY = localStorage.getItem('PRIVATE_KEY'); - - const WORKSPACE_KEY = decryptAssymmetric({ - ciphertext: key.latestKey.encryptedKey, - nonce: key.latestKey.nonce, - publicKey: key.latestKey.sender.publicKey, - privateKey: PRIVATE_KEY - }); + const key = await getLatestFileKey({ workspaceId: router.query.id }); + const PRIVATE_KEY = localStorage.getItem('PRIVATE_KEY'); + + const WORKSPACE_KEY = decryptAssymmetric({ + ciphertext: key.latestKey.encryptedKey, + nonce: key.latestKey.nonce, + publicKey: key.latestKey.sender.publicKey, + privateKey: PRIVATE_KEY + }); - const { ciphertext, nonce } = encryptAssymmetric({ - plaintext: WORKSPACE_KEY, - publicKey: bot.publicKey, - privateKey: PRIVATE_KEY - }); + const { ciphertext, nonce } = encryptAssymmetric({ + plaintext: WORKSPACE_KEY, + publicKey: bot.publicKey, + privateKey: PRIVATE_KEY + }); - botKey = { - encryptedKey: ciphertext, - nonce - } - - // case: bot is not active - setBot((await setBotActiveStatus({ - botId: bot._id, - isActive: bot.isActive ? false : true, - botKey - })).bot); + botKey = { + encryptedKey: ciphertext, + nonce } + + setBot((await setBotActiveStatus({ + botId: bot._id, + isActive: bot.isActive ? false : true, + botKey + })).bot); + } } catch (err) { console.error(err); } @@ -115,6 +115,9 @@ export default function Integrations() { * Start integration for a given integration option [integrationOption] * @param {Object} obj * @param {Object} obj.integrationOption - an integration option + * @param {String} obj.name + * @param {String} obj.type + * @param {String} obj.docsLink * @returns */ const handleIntegrationOption = async ({ integrationOption }) => { @@ -122,20 +125,23 @@ export default function Integrations() { // generate CSRF token for OAuth2 code-token exchange integrations const csrfToken = crypto.randomBytes(16).toString("hex"); + localStorage.setItem('latestCSRFToken', csrfToken); switch (integrationOption.name) { case 'Heroku': window.location = `https://id.heroku.com/oauth/authorize?client_id=7b1311a1-1cb2-4938-8adf-f37a399ec41b&response_type=code&scope=write-protected&state=${csrfToken}`; return; } - } - + /** - * Call [handleIntegrationOption] if bot is active, else open dialog for user to grant - * permission to share secretes with Infisical prior to starting any integration + * Open dialog to activate bot if bot is not active. + * Otherwise, start integration [integrationOption] * @param {Object} obj - * @param {String} obj.integrationOption - an integration option + * @param {Object} obj.integrationOption - an integration option + * @param {String} obj.name + * @param {String} obj.type + * @param {String} obj.docsLink * @returns */ const integrationOptionPress = ({ integrationOption }) => {