/* eslint-disable no-nested-ternary */ /* eslint-disable no-unexpected-multiline */ /* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable vars-on-top */ /* eslint-disable no-var */ /* eslint-disable func-names */ // @ts-nocheck import crypto from "crypto"; import { useEffect } from "react"; import { Controller, useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; import Image from "next/image"; import Link from "next/link"; import { useRouter } from "next/router"; import { faGithub, faSlack } from "@fortawesome/free-brands-svg-icons"; import { faAngleDown, faArrowLeft, faArrowUpRightFromSquare, faBook, faCheck, faEnvelope, faInfinity, faInfo, faMobile, faPlus, faQuestion } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { yupResolver } from "@hookform/resolvers/yup"; import { DropdownMenuTrigger } from "@radix-ui/react-dropdown-menu"; import * as yup from "yup"; import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; import { OrgPermissionCan } from "@app/components/permissions"; import { tempLocalStorage } from "@app/components/utilities/checks/tempLocalStorage"; import { encryptAssymmetric } from "@app/components/utilities/cryptography/crypto"; import { Button, Checkbox, DropdownMenu, DropdownMenuContent, DropdownMenuItem, FormControl, Input, Menu, MenuItem, Modal, ModalContent, Select, SelectItem, UpgradePlanModal } from "@app/components/v2"; import { OrgPermissionActions, OrgPermissionSubjects, useOrganization, useSubscription, useUser, useWorkspace } from "@app/context"; import { usePopUp } from "@app/hooks"; import { fetchOrgUsers, useAddUserToWs, useCreateWorkspace, useGetOrgTrialUrl, useGetSecretApprovalRequestCount, useGetUserAction, useLogoutUser, useRegisterUserAction, useUploadWsKey } from "@app/hooks/api"; import { CreateOrgModal } from "@app/views/Org/components"; interface LayoutProps { children: React.ReactNode; } const supportOptions = [ [ , "Support Forum", "https://infisical.com/slack" ], [ , "Read Docs", "https://infisical.com/docs/documentation/getting-started/introduction" ], [ , "GitHub Issues", "https://github.com/Infisical/infisical/issues" ], [ , "Email Support", "mailto:support@infisical.com" ] ]; const formSchema = yup.object({ name: yup.string().required().label("Project Name").trim(), addMembers: yup.bool().required().label("Add Members") }); type TAddProjectFormData = yup.InferType; export const AppLayout = ({ children }: LayoutProps) => { const router = useRouter(); const { createNotification } = useNotificationContext(); const { mutateAsync } = useGetOrgTrialUrl(); // eslint-disable-next-line prefer-const const { workspaces, currentWorkspace } = useWorkspace(); const { orgs, currentOrg } = useOrganization(); const { user } = useUser(); const { subscription } = useSubscription(); const workspaceId = currentWorkspace?._id || ""; const { data: updateClosed } = useGetUserAction("september_update_closed"); const { data: secretApprovalReqCount } = useGetSecretApprovalRequestCount({ workspaceId }); const isAddingProjectsAllowed = subscription?.workspaceLimit ? subscription.workspacesUsed < subscription.workspaceLimit : true; const createWs = useCreateWorkspace(); const uploadWsKey = useUploadWsKey(); const addWsUser = useAddUserToWs(); const infisicalPlatformVersion = process.env.NEXT_PUBLIC_INFISICAL_PLATFORM_VERSION; const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([ "addNewWs", "upgradePlan", "createOrg" ] as const); const { control, formState: { isSubmitting }, reset, handleSubmit } = useForm({ resolver: yupResolver(formSchema) }); const { t } = useTranslation(); const registerUserAction = useRegisterUserAction(); const closeUpdate = async () => { await registerUserAction.mutateAsync("september_update_closed"); }; const logout = useLogoutUser(); const logOutUser = async () => { try { console.log("Logging out..."); await logout.mutateAsync(); router.push("/login"); } catch (error) { console.error(error); } }; const changeOrg = async (orgId) => { localStorage.setItem("orgData.id", orgId); router.push(`/org/${orgId}/overview`); }; // TODO(akhilmhdh): This entire logic will be rechecked and will try to avoid // Placing the localstorage as much as possible // Wait till tony integrates the azure and its launched useEffect(() => { // Put a user in an org if they're not in one yet const putUserInOrg = async () => { if (tempLocalStorage("orgData.id") === "") { localStorage.setItem("orgData.id", orgs[0]?._id); } if ( currentOrg && ((workspaces?.length === 0 && router.asPath.includes("project")) || router.asPath.includes("/project/undefined") || (!orgs?.map((org) => org._id)?.includes(router.query.id) && !router.asPath.includes("project") && !router.asPath.includes("personal") && !router.asPath.includes("integration"))) ) { router.push(`/org/${currentOrg?._id}/overview`); } // else if (!router.asPath.includes("org") && !router.asPath.includes("project") && !router.asPath.includes("integrations") && !router.asPath.includes("personal-settings")) { // const pathSegments = router.asPath.split("/").filter((segment) => segment.length > 0); // let intendedWorkspaceId; // if (pathSegments.length >= 2 && pathSegments[0] === "dashboard") { // [, intendedWorkspaceId] = pathSegments; // } else if (pathSegments.length >= 3 && pathSegments[0] === "settings") { // [, , intendedWorkspaceId] = pathSegments; // } else { // const lastPathSegments = router.asPath.split("/").pop(); // if (lastPathSegments !== undefined) { // [intendedWorkspaceId] = lastPathSegments.split("?"); // } // } // if (!intendedWorkspaceId) return; // if (!["callback", "create", "authorize"].includes(intendedWorkspaceId)) { // localStorage.setItem("projectData.id", intendedWorkspaceId); // } // } }; putUserInOrg(); }, [router.query.id]); const onCreateProject = async ({ name, addMembers }: TAddProjectFormData) => { // type check if (!currentOrg?._id) return; try { const { data: { workspace: { _id: newWorkspaceId } } } = await createWs.mutateAsync({ organizationId: currentOrg?._id, workspaceName: name }); const randomBytes = crypto.randomBytes(16).toString("hex"); const PRIVATE_KEY = String(localStorage.getItem("PRIVATE_KEY")); const { ciphertext, nonce } = encryptAssymmetric({ plaintext: randomBytes, publicKey: user.publicKey, privateKey: PRIVATE_KEY }); await uploadWsKey.mutateAsync({ encryptedKey: ciphertext, nonce, userId: user?._id, workspaceId: newWorkspaceId }); if (addMembers) { // not using hooks because need at this point only const orgUsers = await fetchOrgUsers(currentOrg._id); orgUsers.forEach(({ status, user: orgUser }) => { // skip if status of org user is not accepted // this orgUser is the person who created the ws if (status !== "accepted" || user.email === orgUser.email) return; addWsUser.mutate({ email: orgUser.email, workspaceId: newWorkspaceId }); }); } createNotification({ text: "Workspace created", type: "success" }); handlePopUpClose("addNewWs"); router.push(`/project/${newWorkspaceId}/secrets/overview`); } catch (err) { console.error(err); createNotification({ text: "Failed to create workspace", type: "error" }); } }; return ( <>
{ handlePopUpToggle("addNewWs", isModalOpen); reset(); }} >
( )} />
( {(isAllowed) => (
Add all members of my organization to this project
)}
)} />
handlePopUpToggle("upgradePlan", isOpen)} text="You have exceeded the number of projects allowed on the free plan." /> handlePopUpToggle("createOrg", false)} />
{children}

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

); };