/* eslint-disable no-unexpected-multiline */ /* eslint-disable react-hooks/exhaustive-deps */ import { useEffect, useMemo, useState } from "react"; import Link from "next/link"; import { useRouter } from "next/router"; import { useTranslation } from "next-i18next"; import { faBookOpen, faFileLines, faGear, faKey, faMobile, faPlug, faUser, } from "@fortawesome/free-solid-svg-icons"; import { faPlus } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import getOrganizations from "~/pages/api/organization/getOrgs"; import getOrganizationUserProjects from "~/pages/api/organization/GetOrgUserProjects"; import getOrganizationUsers from "~/pages/api/organization/GetOrgUsers"; import getUser from "~/pages/api/user/getUser"; import addUserToWorkspace from "~/pages/api/workspace/addUserToWorkspace"; import createWorkspace from "~/pages/api/workspace/createWorkspace"; import getWorkspaces from "~/pages/api/workspace/getWorkspaces"; import uploadKeys from "~/pages/api/workspace/uploadKeys"; import NavBarDashboard from "../navigation/NavBarDashboard"; import onboardingCheck from "../utilities/checks/OnboardingCheck"; import { tempLocalStorage } from "../utilities/checks/tempLocalStorage"; import { decryptAssymmetric, encryptAssymmetric, } from "../utilities/cryptography/crypto"; import Button from "./buttons/Button"; import AddWorkspaceDialog from "./dialog/AddWorkspaceDialog"; import Listbox from "./Listbox"; interface LayoutProps { children: React.ReactNode; } const crypto = require("crypto"); export default function Layout({ children }: LayoutProps) { const router = useRouter(); const [workspaceList, setWorkspaceList] = useState([]); const [workspaceMapping, setWorkspaceMapping] = useState([{ "1": "2" }]); const [workspaceSelected, setWorkspaceSelected] = useState("∞"); const [newWorkspaceName, setNewWorkspaceName] = useState(""); const [isOpen, setIsOpen] = useState(false); const [loading, setLoading] = useState(false); const [error, setError] = useState(false); const [totalOnboardingActionsDone, setTotalOnboardingActionsDone] = useState(0); const { t } = useTranslation(); function closeModal() { setIsOpen(false); } function openModal() { setIsOpen(true); } // TODO: what to do about the fact that 2ids can have the same name /** * When a user creates a new workspace, redirect them to the page of the new workspace. * @param {*} workspaceName */ async function submitModal(workspaceName: string, addAllUsers: boolean) { setLoading(true); // timeout code. setTimeout(() => setLoading(false), 1500); try { const workspaces = await getWorkspaces(); const currentWorkspaces = workspaces.map((workspace) => workspace.name); if (!currentWorkspaces.includes(workspaceName)) { const newWorkspace = await createWorkspace({ workspaceName, organizationId: tempLocalStorage("orgData.id"), }); const newWorkspaceId = newWorkspace._id; const randomBytes = crypto.randomBytes(16).toString("hex"); const PRIVATE_KEY = String(localStorage.getItem("PRIVATE_KEY")); const myUser = await getUser(); const { ciphertext, nonce } = encryptAssymmetric({ plaintext: randomBytes, publicKey: myUser.publicKey, privateKey: PRIVATE_KEY, }) as { ciphertext: string; nonce: string }; await uploadKeys( newWorkspaceId, myUser._id, ciphertext, nonce ); if (addAllUsers) { console.log('adding other users') const orgUsers = await getOrganizationUsers({ orgId: tempLocalStorage("orgData.id"), }); orgUsers.map(async (user: any) => { if (user.status == "accepted" && user.email != myUser.email) { const result = await addUserToWorkspace( user.user.email, newWorkspaceId ); if (result?.invitee && result?.latestKey) { const PRIVATE_KEY = tempLocalStorage("PRIVATE_KEY"); // assymmetrically decrypt symmetric key with local private key const key = decryptAssymmetric({ ciphertext: result.latestKey.encryptedKey, nonce: result.latestKey.nonce, publicKey: result.latestKey.sender.publicKey, privateKey: PRIVATE_KEY, }); const { ciphertext, nonce } = encryptAssymmetric({ plaintext: key, publicKey: result.invitee.publicKey, privateKey: PRIVATE_KEY, }) as { ciphertext: string; nonce: string }; uploadKeys( newWorkspaceId, result.invitee._id, ciphertext, nonce ); } } }); } router.push("/dashboard/" + newWorkspaceId); setIsOpen(false); setNewWorkspaceName(""); } else { console.error("A project with this name already exists."); setError(true); setLoading(false); } } catch (err) { console.error(err); setError(true); setLoading(false); } } const menuItems = useMemo( () => [ { href: "/dashboard/" + workspaceMapping[workspaceSelected as any], title: t("nav:menu.secrets"), emoji: , }, { href: "/users/" + workspaceMapping[workspaceSelected as any], title: t("nav:menu.members"), emoji: , }, { href: "/integrations/" + workspaceMapping[workspaceSelected as any], title: t("nav:menu.integrations"), emoji: , }, { href: '/activity/' + workspaceMapping[workspaceSelected as any], title: 'Activity Logs', emoji: }, { href: "/settings/project/" + workspaceMapping[workspaceSelected as any], title: t("nav:menu.project-settings"), emoji: , }, ], [t, workspaceMapping, workspaceSelected] ); useEffect(() => { // Put a user in a workspace if they're not in one yet const putUserInWorkSpace = async () => { if (tempLocalStorage("orgData.id") === "") { const userOrgs = await getOrganizations(); localStorage.setItem("orgData.id", userOrgs[0]._id); } const orgUserProjects = await getOrganizationUserProjects({ orgId: tempLocalStorage("orgData.id"), }); const userWorkspaces = orgUserProjects; if ( userWorkspaces.length == 0 && router.asPath != "/noprojects" && !router.asPath.includes("home")&& !router.asPath.includes("settings") ) { router.push("/noprojects"); } else if (router.asPath != "/noprojects") { const intendedWorkspaceId = router.asPath .split("/") [router.asPath.split("/").length - 1].split("?")[0]; if ( !["heroku", "vercel", "github", "netlify"].includes(intendedWorkspaceId) ) { localStorage.setItem("projectData.id", intendedWorkspaceId); } // If a user is not a member of a workspace they are trying to access, just push them to one of theirs if ( !["heroku", "vercel", "github", "netlify"].includes(intendedWorkspaceId) && !userWorkspaces .map((workspace: { _id: string }) => workspace._id) .includes(intendedWorkspaceId) ) { router.push("/dashboard/" + userWorkspaces[0]._id); } else { setWorkspaceList( userWorkspaces.map((workspace: any) => workspace.name) ); setWorkspaceMapping( Object.fromEntries( userWorkspaces.map((workspace: any) => [ workspace.name, workspace._id, ]) ) as any ); setWorkspaceSelected( Object.fromEntries( userWorkspaces.map((workspace: any) => [ workspace._id, workspace.name, ]) )[ router.asPath .split("/") [router.asPath.split("/").length - 1].split("?")[0] ] ); } } }; putUserInWorkSpace(); onboardingCheck({ setTotalOnboardingActionsDone }); }, []); useEffect(() => { try { if ( workspaceMapping[workspaceSelected as any] && `${workspaceMapping[workspaceSelected as any]}` !== router.asPath .split("/") [router.asPath.split("/").length - 1].split("?")[0] ) { localStorage.setItem( "projectData.id", `${workspaceMapping[workspaceSelected as any]}` ); router.push( "/dashboard/" + workspaceMapping[workspaceSelected as any] ); } } catch (error) { console.log(error); } }, [workspaceSelected]); return ( <>
{children}

{` ${t("common:no-mobile")} `}

); }