/* eslint-disable @typescript-eslint/no-unused-vars */ import { useState } from 'react'; import { useTranslation } from 'next-i18next'; import { plans } from 'public/data/frequentConstants'; import { useNotificationContext } from '@app/components/context/Notifications/NotificationProvider'; import NavHeader from '@app/components/navigation/NavHeader'; import { decryptAssymmetric, encryptAssymmetric } from '@app/components/utilities/cryptography/crypto'; import { useOrganization, useSubscription, useUser, useWorkspace } from '@app/context'; import { useAddIncidentContact, useAddUserToOrg, useDeleteIncidentContact, useDeleteOrgMembership, useGetOrgIncidentContact, useGetOrgUsers, useGetUserWorkspaceMemberships, useGetUserWsKey, useRenameOrg, useUpdateOrgUserRole, useUploadWsKey, } from '@app/hooks/api'; import { OrgIncidentContactsTable, OrgMembersTable, OrgNameChangeSection, OrgServiceAccountsTable } from './components'; export const OrgSettingsPage = () => { const host = window.location.origin; const { t } = useTranslation(); const { currentOrg } = useOrganization(); const { currentWorkspace } = useWorkspace(); const { user } = useUser(); const { subscriptionPlan } = useSubscription(); const { createNotification } = useNotificationContext(); const orgId = currentOrg?._id || ''; const { data: orgUsers, isLoading: isOrgUserLoading } = useGetOrgUsers(orgId); const { data: workspaceMemberships, isLoading: IsWsMembershipLoading } = useGetUserWorkspaceMemberships(orgId); const { data: wsKey } = useGetUserWsKey(currentWorkspace?._id || ''); const { data: incidentContact, isLoading: IsIncidentContactLoading } = useGetOrgIncidentContact(orgId); const renameOrg = useRenameOrg(); const removeUserOrgMembership = useDeleteOrgMembership(); const addUserToOrg = useAddUserToOrg(); const updateOrgUserRole = useUpdateOrgUserRole(); const uploadWsKey = useUploadWsKey(); const addIncidentContact = useAddIncidentContact(); const removeIncidentContact = useDeleteIncidentContact(); const [completeInviteLink, setcompleteInviteLink] = useState(''); const isMoreUsersNotAllowed = (orgUsers || []).length >= 5 && subscriptionPlan === plans.starter && host === 'https://app.infisical.com' && currentWorkspace?._id !== '63ea8121b6e2b0543ba79616'; const onRenameOrg = async (name: string) => { if (!currentOrg?._id) return; try { await renameOrg.mutateAsync({ orgId: currentOrg?._id, newOrgName: name }); createNotification({ text: 'Successfully renamed organization', type: 'success' }); } catch (error) { console.error(error); createNotification({ text: 'Failed to rename organization', type: 'error' }); } }; const onRemoveUserOrgMembership = async (membershipId: string) => { if (!currentOrg?._id) return; try { await removeUserOrgMembership.mutateAsync({ orgId: currentOrg?._id, membershipId }); createNotification({ text: 'Successfully removed user from org', type: 'success' }); } catch (error) { console.error(error); createNotification({ text: 'Failed to remove user from the organization', type: 'error' }); } }; const onAddUserToOrg = async (email: string) => { if (!currentOrg?._id) return; try { const { data } = await addUserToOrg.mutateAsync({ organizationId: currentOrg?._id, inviteeEmail: email }); setcompleteInviteLink(data?.completeInviteLink); // only show this notification when email is configured. A [completeInviteLink] will not be sent if smtp is configured if (!data.completeInviteLink) { createNotification({ text: 'Successfully invited user to the organization.', type: 'success' }); } } catch (error) { console.error(error); createNotification({ text: 'Failed to invite user to org', type: 'error' }); } }; const onUpdateOrgUserRole = async (membershipId: string, role: string) => { if (!currentOrg?._id) return; try { await updateOrgUserRole.mutateAsync({ organizationId: currentOrg?._id, membershipId, role }); createNotification({ text: 'Successfully updated user role', type: 'success' }); } catch (error) { console.error(error); createNotification({ text: 'Failed to update user role', type: 'error' }); } }; const onGrantUserAccess = async (userId: string, publicKey: string) => { try { const PRIVATE_KEY = localStorage.getItem('PRIVATE_KEY') as string; if (!PRIVATE_KEY || !wsKey) return; // assymmetrically decrypt symmetric key with local private key const key = decryptAssymmetric({ ciphertext: wsKey.encryptedKey, nonce: wsKey.nonce, publicKey: wsKey.sender.publicKey, privateKey: PRIVATE_KEY }); const { ciphertext, nonce } = encryptAssymmetric({ plaintext: key, publicKey, privateKey: PRIVATE_KEY }); await uploadWsKey.mutateAsync({ userId, nonce, encryptedKey: ciphertext, workspaceId: currentWorkspace?._id || '' }); } catch (err) { console.error(err); createNotification({ text: 'Failed to grant access to user', type: 'error' }); } }; const onAddIncidentContact = async (email: string) => { if (!currentOrg?._id) return; try { await addIncidentContact.mutateAsync({ orgId, email }); createNotification({ text: 'Successfully added incident contact', type: 'success' }); } catch (error) { console.error(error); createNotification({ text: 'Failed to add incident contact', type: 'error' }); } }; const onRemoveIncidentContact = async (email: string) => { if (!currentOrg?._id) return; try { await removeIncidentContact.mutateAsync({ orgId, email }); createNotification({ text: 'Successfully removed incident contact', type: 'success' }); } catch (error) { console.error(error); createNotification({ text: 'Failed to remove incident contact', type: 'error' }); } }; /** * This function deleted a workspace. * It first checks if there is more than one workspace available. Otherwise, it doesn't delete * It then checks if the name of the workspace to be deleted is correct. Otherwise, it doesn't delete. * It then deletes the workspace and forwards the user to another available workspace. */ // const executeDeletingWorkspace = async () => { // const userWorkspaces = await getWorkspaces(); // // if (userWorkspaces.length > 1) { // if ( // userWorkspaces.filter((workspace) => workspace._id === workspaceId)[0].name === // workspaceToBeDeletedName // ) { // await deleteWorkspace(workspaceId); // const ws = await getWorkspaces(); // router.push(`/dashboard/${ws[0]._id}`); // } // } // }; // return (

{t('settings-org:title')}

{t('settings-org:description')}

{t('section-members:org-members')}

Service Accounts

{t('section-incident:incident-contacts')}

{t('section-incident:incident-contacts-description')}

{/*

Danger Zone

As soon as you delete an organization, you will not be able to undo it. This will immediately remove all organization members and cancel your subscription. If you still want to do that, please enter the name of the organization below.

Note: You can only delete a project in case you have more than one.

*/}
); };