From 14593704582312d4ccf21d35eab5e767d5d87977 Mon Sep 17 00:00:00 2001 From: Vladyslav Matsiiako Date: Tue, 27 Dec 2022 18:22:48 -0500 Subject: [PATCH] Fixing more merge conflicts --- frontend/components/dashboard/DropZone.tsx | 6 - .../components/navigation/NavBarDashboard.tsx | 10 +- frontend/pages/dashboard/[id].js | 813 ------------------ frontend/pages/login.tsx | 12 +- frontend/pages/password-reset.tsx | 10 +- frontend/pages/settings/org/[id].js | 8 +- frontend/pages/settings/personal/[id].js | 4 - frontend/pages/signup.tsx | 13 +- frontend/pages/verify-email.tsx | 9 +- 9 files changed, 6 insertions(+), 879 deletions(-) delete mode 100644 frontend/pages/dashboard/[id].js diff --git a/frontend/components/dashboard/DropZone.tsx b/frontend/components/dashboard/DropZone.tsx index 9223f7a92..66be964cc 100644 --- a/frontend/components/dashboard/DropZone.tsx +++ b/frontend/components/dashboard/DropZone.tsx @@ -152,13 +152,7 @@ const DropZone = ({ icon={faUpload} className="text-bunker-300 text-3xl mr-6" /> -<<<<<<< HEAD

{t("common:drop-zone-keys")}

-======= -

- Drag and drop your .env file here to add more keys. -

->>>>>>> 876c5f51c2caabf92b47d5a18a9b98e601806bf4 {errorDragAndDrop ? (
diff --git a/frontend/components/navigation/NavBarDashboard.tsx b/frontend/components/navigation/NavBarDashboard.tsx index aa7d3270f..824614819 100644 --- a/frontend/components/navigation/NavBarDashboard.tsx +++ b/frontend/components/navigation/NavBarDashboard.tsx @@ -1,18 +1,10 @@ /* eslint-disable react/jsx-key */ -<<<<<<< HEAD -import React, { Fragment, useEffect, useMemo, useState } from "react"; +import { Fragment, useEffect, useMemo, useState } from "react"; import Image from "next/image"; import { useRouter } from "next/router"; import { TFunction, useTranslation } from "next-i18next"; import { faGithub, faSlack } from "@fortawesome/free-brands-svg-icons"; import { faCircleQuestion } from "@fortawesome/free-regular-svg-icons"; -======= -import { Fragment, useEffect, useState } from 'react'; -import Image from 'next/image'; -import { useRouter } from 'next/router'; -import { faGithub, faSlack } from '@fortawesome/free-brands-svg-icons'; -import { faCircleQuestion } from '@fortawesome/free-regular-svg-icons'; ->>>>>>> 876c5f51c2caabf92b47d5a18a9b98e601806bf4 import { faAngleDown, faBook, diff --git a/frontend/pages/dashboard/[id].js b/frontend/pages/dashboard/[id].js deleted file mode 100644 index a4147ef86..000000000 --- a/frontend/pages/dashboard/[id].js +++ /dev/null @@ -1,813 +0,0 @@ -import React, { Fragment, useCallback, useEffect, useState } from "react"; -import Head from "next/head"; -import Image from "next/image"; -import { useRouter } from "next/router"; -import { useTranslation } from "next-i18next"; -import { - faArrowDownAZ, - faArrowDownZA, - faCheck, - faCircleInfo, - faCopy, - faDownload, - faEllipsis, - faEye, - faEyeSlash, - faFolderOpen, - faMagnifyingGlass, - faPeopleGroup, - faPerson, - faPlus, - faShuffle, - 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 pushKeysIntegration from '~/components/utilities/secrets/pushKeysIntegration'; -import guidGenerator from '~/utilities/randomId'; -import { getTranslatedServerSideProps } from "~/utilities/withTranslateProps"; - - -import { envMapping } from '../../public/data/frequentConstants'; -import getUser from '../api/user/getUser'; -import checkUserAction from '../api/userActions/checkUserAction'; -import registerUserAction from '../api/userActions/registerUserAction'; -import getWorkspaces from '../api/workspace/getWorkspaces'; - -/** - * This component represent a single row for an environemnt variable on the dashboard - * @param {object} obj - * @param {String[]} obj.keyPair - data related to the environment variable (id, pos, key, value, public/private) - * @param {function} obj.deleteRow - a function to delete a certain keyPair - * @param {function} obj.modifyKey - modify the key of a certain environment variable - * @param {function} obj.modifyValue - modify the value of a certain environment variable - * @param {function} obj.modifyVisibility - switch between public/private visibility - * @param {boolean} obj.isBlurred - if the blurring setting is turned on - * @param {string[]} obj.duplicates - list of all the duplicates secret names on the dashboard - * @returns - */ -const KeyPair = ({ - keyPair, - deleteRow, - modifyKey, - modifyValue, - modifyVisibility, - isBlurred, - duplicates -}) => { - const [randomStringLength, setRandomStringLength] = useState(32); - const { t } = useTranslation(); - - return ( -
-
-
-
- -
-
-
-
- -
-
- -
- -
- -
-
-
- - -
- modifyVisibility( - keyPair.type == 'personal' ? 'shared' : 'personal', - keyPair.pos - ) - } - className="relative flex justify-start items-center cursor-pointer select-none py-2 px-2 rounded-md text-gray-400 hover:bg-white/10 duration-200 hover:text-gray-200 w-full" - > - -
- {keyPair[4] == "personal" - ? t("dashboard:make-shared") - : t("dashboard:make-personal")} -
-
-
{ - if (randomStringLength > 32) { - setRandomStringLength(32); - } else if (randomStringLength < 2) { - setRandomStringLength(2); - } else { - modifyValue( - [...Array(randomStringLength)] - .map(() => Math.floor(Math.random() * 16).toString(16)) - .join(''), - keyPair.pos - ); - } - }} - className="relative flex flex-row justify-start items-center cursor-pointer select-none py-2 px-2 rounded-md text-gray-400 hover:bg-white/10 duration-200 hover:text-gray-200 w-full" - > - -
-

Generate Random Hex

-

digits

-
-
-
-
{ - if (randomStringLength > 1) { - setRandomStringLength(randomStringLength - 1); - } - }} - > - - -
- - setRandomStringLength(parseInt(e.target.value)) - } - value={randomStringLength} - className="text-center z-20 peer text-sm bg-transparent w-full outline-none" - spellCheck="false" - /> -
{ - if (randomStringLength < 32) { - setRandomStringLength(randomStringLength + 1); - } - }} - > - + -
-
-
-
-
-
-
-
-
-
- ); -}; - -/** - * This is the main component for the dashboard (aka the screen with all the encironemnt variable & secrets) - * @returns - */ -export default function Dashboard() { - const [data, setData] = useState(); - const [fileState, setFileState] = useState([]); - const [buttonReady, setButtonReady] = useState(false); - const router = useRouter(); - const [workspaceId, setWorkspaceId] = useState(''); - const [blurred, setBlurred] = useState(true); - const [isKeyAvailable, setIsKeyAvailable] = useState(true); - const [env, setEnv] = useState( - router.asPath.split('?').length == 1 - ? 'Development' - : Object.keys(envMapping).includes(router.asPath.split('?')[1]) - ? router.asPath.split('?')[1] - : 'Development' - ); - const [isNew, setIsNew] = useState(false); - const [searchKeys, setSearchKeys] = useState(''); - const [errorDragAndDrop, setErrorDragAndDrop] = useState(false); - const [projectIdCopied, setProjectIdCopied] = useState(false); - const [sortMethod, setSortMethod] = useState('alphabetical'); - const [checkDocsPopUpVisible, setCheckDocsPopUpVisible] = useState(false); - const [hasUserEverPushed, setHasUserEverPushed] = useState(false); - - const { t } = useTranslation(); - - const { createNotification } = useNotificationContext(); - - // #TODO: fix save message for changing reroutes - // const beforeRouteHandler = (url) => { - // const warningText = - // "Do you want to save your results bfore leaving this page?"; - // if (!buttonReady) return; - // if (router.asPath !== url && !confirm(warningText)) { - // // router.events.emit('routeChangeError'); - // // setData(data) - // savePush(); - // throw `Route change to "${url}" was aborted (this error can be safely ignored).`; - // } else { - // setButtonReady(false); - // } - // }; - - // prompt the user if they try and leave with unsaved changes - useEffect(() => { - const warningText = - 'Do you want to save your results before leaving this page?'; - const handleWindowClose = (e) => { - if (!buttonReady) return; - e.preventDefault(); - return (e.returnValue = warningText); - }; - window.addEventListener('beforeunload', handleWindowClose); - // router.events.on('routeChangeStart', beforeRouteHandler); - return () => { - window.removeEventListener('beforeunload', handleWindowClose); - // router.events.off('routeChangeStart', beforeRouteHandler); - }; - }, [buttonReady]); - - /** - * Reorder rows alphabetically or in the opprosite order - */ - const reorderRows = (dataToReorder) => { - setSortMethod((prevSort) => - prevSort == 'alphabetical' ? '-alphabetical' : 'alphabetical' - ); - - sortValuesHandler(dataToReorder); - }; - - useEffect(() => { - (async () => { - try { - let userWorkspaces = await getWorkspaces(); - const listWorkspaces = userWorkspaces.map((workspace) => workspace._id); - if ( - !listWorkspaces.includes(router.asPath.split('/')[2].split('?')[0]) - ) { - router.push('/dashboard/' + listWorkspaces[0]); - } - - if (env != router.asPath.split('?')[1]) { - router.push(router.asPath.split('?')[0] + '?' + env); - } - setBlurred(true); - setWorkspaceId(router.query.id); - - const dataToSort = await getSecretsForProject({ - env, - setFileState, - setIsKeyAvailable, - setData, - workspaceId: router.query.id - }); - reorderRows(dataToSort); - - const user = await getUser(); - setIsNew( - (Date.parse(new Date()) - Date.parse(user.createdAt)) / 60000 < 3 - ? true - : false - ); - - let userAction = await checkUserAction({ - action: 'first_time_secrets_pushed' - }); - setHasUserEverPushed(userAction ? true : false); - } catch (error) { - console.log('Error', error); - setData([]); - } - })(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [env]); - - const addRow = () => { - setIsNew(false); - setData([ - ...data, - { - id: guidGenerator(), - pos: data.length, - key: '', - value: '', - type: 'shared' - } - ]); - }; - - const deleteRow = (id) => { - setButtonReady(true); - setData(data.filter((row) => row.id !== id)); - }; - - const modifyValue = (value, pos) => { - setData((oldData) => { - oldData[pos].value = value; - return [...oldData]; - }); - setButtonReady(true); - }; - - const modifyKey = (value, pos) => { - setData((oldData) => { - oldData[pos].key = value; - return [...oldData]; - }); - setButtonReady(true); - }; - - const modifyVisibility = (value, pos) => { - setData((oldData) => { - oldData[pos].type = value; - return [...oldData]; - }); - setButtonReady(true); - }; - - // For speed purposes and better perforamance, we are using useCallback - const listenChangeValue = useCallback((value, pos) => { - modifyValue(value, pos); - }, []); - - const listenChangeKey = useCallback((value, pos) => { - modifyKey(value, pos); - }, []); - - const listenChangeVisibility = useCallback((value, pos) => { - modifyVisibility(value, pos); - }, []); - - /** - * Save the changes of environment variables and push them to the database - */ - const savePush = async () => { - // Format the new object with environment variables - let obj = Object.assign( - {}, - ...data.map((row) => ({ [row.key]: [row.value, row.type] })) - ); - - // Checking if any of the secret keys start with a number - if so, don't do anything - const nameErrors = !Object.keys(obj) - .map((key) => !isNaN(key.charAt(0))) - .every((v) => v === false); - const duplicatesExist = - data - ?.map((item) => item.key) - .filter( - (item, index) => index !== data?.map((item) => item.key).indexOf(item) - ).length > 0; - - if (nameErrors) { - return createNotification({ - text: 'Solve all name errors before saving secrets.', - type: 'error' - }); - } - - if (duplicatesExist) { - return createNotification({ - text: 'Remove duplicated secret names before saving.', - type: 'error' - }); - } - - // Once "Save changed is clicked", disable that button - setButtonReady(false); - pushKeys({ obj, workspaceId: router.query.id, env }); - - // If this user has never saved environment variables before, show them a prompt to read docs - if (!hasUserEverPushed) { - setCheckDocsPopUpVisible(true); - await registerUserAction({ action: 'first_time_secrets_pushed' }); - } - }; - - const addData = (newData) => { - setData(data.concat(newData)); - setButtonReady(true); - }; - - const changeBlurred = () => { - setBlurred(!blurred); - }; - - const sortValuesHandler = (dataToSort) => { - const sortedData = (dataToSort != 1 ? dataToSort : data) - .sort((a, b) => - sortMethod == 'alphabetical' - ? a.key.localeCompare(b.key) - : b.key.localeCompare(a.key) - ) - .map((item, index) => { - return { - ...item, - pos: index - }; - }); - - setData(sortedData); - }; - - // This function downloads the secrets as a .env file - const download = () => { - const file = data - .map((item) => [item.key, item.value].join('=')) - .join('\n'); - const blob = new Blob([file]); - const fileDownloadUrl = URL.createObjectURL(blob); - let alink = document.createElement('a'); - alink.href = fileDownloadUrl; - alink.download = envMapping[env] + '.env'; - alink.click(); - }; - - const deleteCertainRow = (id) => { - deleteRow(id); - }; - - /** - * This function copies the project id to the clipboard - */ - function copyToClipboard() { - var copyText = document.getElementById('myInput'); - - copyText.select(); - copyText.setSelectionRange(0, 99999); // For mobile devices - - navigator.clipboard.writeText(copyText.value); - - setProjectIdCopied(true); - setTimeout(() => setProjectIdCopied(false), 2000); - } - - return data ? ( -
- - {t("common:head-title", { title: t("dashboard:title") })} - - - - - -
-
- - {checkDocsPopUpVisible && ( - - )} -
-
-

{t("dashboard:title")}

- {data?.length == 0 && ( - - )} -
-
-
-

{`${t( - "common:project-id" - )}:`}

- -
- - - {t("common:click-to-copy")} - -
-
- {(data?.length !== 0 || buttonReady) && ( -
-
- )} -
-
-
-
-
- {data?.length !== 0 && ( - <> - -
- - setSearchKeys(e.target.value)} - placeholder={t("dashboard:search-keys")} - /> -
-
-
-
-
-
-
-
-
- - )} -
-
- {data?.length !== 0 ? ( -
-
-
- {/* */} -
-

{t("dashboard:personal")}

-
- - - {t("dashboard:personal-description")} - -
-
-
-
- {data - .filter( - (keyPair) => - keyPair.key - .toLowerCase() - .includes(searchKeys.toLowerCase()) && - keyPair.type == 'personal' - ) - ?.map((keyPair) => ( - item.key) - .filter( - (item, index) => - index !== - data?.map((item) => item.key).indexOf(item) - )} - /> - ))} -
-
-
8 ? 'h-3/4' : 'h-min' - }`} - > -
- {/* */} -
-

{t("dashboard:shared")}

-
- - - {t("dashboard:shared-description")} - -
-
-
-
- {data - .filter( - (keyPair) => - keyPair.key - .toLowerCase() - .includes(searchKeys.toLowerCase()) && - keyPair.type == 'shared' - ) - ?.map((keyPair) => ( - item.key) - .filter( - (item, index) => - index !== - data?.map((item) => item.key).indexOf(item) - )} - /> - ))} -
-
-
- -
-
- ) : ( -
- {fileState.message != "There's nothing to pull" && - fileState.message != undefined && ( - - )} - {(fileState.message == "There's nothing to pull" || - fileState.message == undefined) && - isKeyAvailable && ( - - )} - {fileState.message == - 'Failed membership validation for workspace' && ( -

You are not authorized to view this project.

- )} - {fileState.message == 'Access needed to pull the latest file' || - (!isKeyAvailable && ( - <> - -

- To view this file, contact your administrator for - permission. -

-

- They need to grant you access in the team tab. -

- - ))} -
- )} -
-
-
-
- ) : ( -
-
- loading animation -
- ); -} - -Dashboard.requireAuth = true; - -export const getServerSideProps = getTranslatedServerSideProps(["dashboard"]); diff --git a/frontend/pages/login.tsx b/frontend/pages/login.tsx index 78c42e3be..9e10bbe91 100644 --- a/frontend/pages/login.tsx +++ b/frontend/pages/login.tsx @@ -1,5 +1,4 @@ -<<<<<<< HEAD -import React, { useEffect, useState } from "react"; +import { useEffect, useState } from "react"; import Head from "next/head"; import Image from "next/image"; import Link from "next/link"; @@ -7,15 +6,6 @@ import { useRouter } from "next/router"; import { useTranslation } from "next-i18next"; import { faWarning } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -======= -import { useEffect, useState } from 'react'; -import Head from 'next/head'; -import Image from 'next/image'; -import Link from 'next/link'; -import { useRouter } from 'next/router'; -import { faWarning } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; ->>>>>>> 876c5f51c2caabf92b47d5a18a9b98e601806bf4 import Button from "~/components/basic/buttons/Button"; import Error from "~/components/basic/Error"; diff --git a/frontend/pages/password-reset.tsx b/frontend/pages/password-reset.tsx index 4c76f213d..55071040b 100644 --- a/frontend/pages/password-reset.tsx +++ b/frontend/pages/password-reset.tsx @@ -1,16 +1,8 @@ -<<<<<<< HEAD -import React, { useState } from "react"; +import { useState } from "react"; import Image from "next/image"; import { useRouter } from "next/router"; import { faCheck, faX } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -======= -import { useState } from 'react'; -import Image from 'next/image'; -import { useRouter } from 'next/router'; -import { faCheck, faX } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; ->>>>>>> 876c5f51c2caabf92b47d5a18a9b98e601806bf4 import Button from "~/components/basic/buttons/Button"; import InputField from "~/components/basic/InputField"; diff --git a/frontend/pages/settings/org/[id].js b/frontend/pages/settings/org/[id].js index 340aa766d..cec025780 100644 --- a/frontend/pages/settings/org/[id].js +++ b/frontend/pages/settings/org/[id].js @@ -1,13 +1,7 @@ -<<<<<<< HEAD -import React, { useEffect, useState } from "react"; +import { useEffect, useState } from "react"; import Head from "next/head"; import { useRouter } from "next/router"; import { useTranslation } from "next-i18next"; -======= -import { useEffect, useState } from 'react'; -import Head from 'next/head'; -import { useRouter } from 'next/router'; ->>>>>>> 876c5f51c2caabf92b47d5a18a9b98e601806bf4 import { faMagnifyingGlass, faPlus, diff --git a/frontend/pages/settings/personal/[id].js b/frontend/pages/settings/personal/[id].js index 836654c8a..5eebb8328 100644 --- a/frontend/pages/settings/personal/[id].js +++ b/frontend/pages/settings/personal/[id].js @@ -1,8 +1,4 @@ -<<<<<<< HEAD -import React, { useCallback, useEffect, useState } from "react"; -======= import { useEffect, useState } from "react"; ->>>>>>> 876c5f51c2caabf92b47d5a18a9b98e601806bf4 import Head from "next/head"; import { useRouter } from "next/router"; import { useTranslation } from "next-i18next"; diff --git a/frontend/pages/signup.tsx b/frontend/pages/signup.tsx index 29ca57217..908d00abc 100644 --- a/frontend/pages/signup.tsx +++ b/frontend/pages/signup.tsx @@ -1,5 +1,4 @@ -<<<<<<< HEAD -import React, { useEffect, useState } from "react"; +import { useEffect, useState } from "react"; import ReactCodeInput from "react-code-input"; import Head from "next/head"; import Image from "next/image"; @@ -8,16 +7,6 @@ import { useRouter } from "next/router"; import { useTranslation } from "next-i18next"; import { faCheck, faWarning, faX } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -======= -import { useEffect, useState } from 'react'; -import ReactCodeInput from 'react-code-input'; -import Head from 'next/head'; -import Image from 'next/image'; -import Link from 'next/link'; -import { useRouter } from 'next/router'; -import { faCheck, faWarning, faX } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; ->>>>>>> 876c5f51c2caabf92b47d5a18a9b98e601806bf4 import Button from "~/components/basic/buttons/Button"; import Error from "~/components/basic/Error"; diff --git a/frontend/pages/verify-email.tsx b/frontend/pages/verify-email.tsx index a8f47fc81..0831a3a2e 100644 --- a/frontend/pages/verify-email.tsx +++ b/frontend/pages/verify-email.tsx @@ -1,14 +1,7 @@ -<<<<<<< HEAD -import React, { useState } from "react"; +import { useState } from "react"; import Head from "next/head"; import Image from "next/image"; import Link from "next/link"; -======= -import { useState } from 'react'; -import Head from 'next/head'; -import Image from 'next/image'; -import Link from 'next/link'; ->>>>>>> 876c5f51c2caabf92b47d5a18a9b98e601806bf4 import Button from "~/components/basic/buttons/Button"; import InputField from "~/components/basic/InputField";