import { ActionIcon, Box, Code, LoadingOverlay, Space, Stack, Title, Tooltip, Card, Group, ThemeIcon } from '@mantine/core'; import { Navigate, useNavigate, useParams } from 'react-router'; import { Badge, Divider, Menu } from '@mantine/core'; import { useEffect, useState } from 'react'; import { FaFilter, FaPencilAlt, FaPlay, FaStop } from 'react-icons/fa'; import { EXAMPLE_PYFILTER, nfproxy, nfproxyServiceFilterCodeQuery, nfproxyServicePyfiltersQuery, nfproxyServiceQuery, serviceQueryKey } from '../../components/NFProxy/utils'; import { MdDoubleArrow } from "react-icons/md" import YesNoModal from '../../components/YesNoModal'; import { errorNotify, isMediumScreen, okNotify, regex_ipv4, socketio } from '../../js/utils'; import { BsTrashFill } from 'react-icons/bs'; import { BiRename } from 'react-icons/bi' import RenameForm from '../../components/NFProxy/ServiceRow/RenameForm'; import { MenuDropDownWithButton } from '../../components/MainLayout'; import { useQueryClient } from '@tanstack/react-query'; import { FaArrowLeft } from "react-icons/fa"; import { IoSettingsSharp } from 'react-icons/io5'; import AddEditService from '../../components/NFProxy/AddEditService'; import PyFilterView from '../../components/PyFilterView'; import { TbPlugConnected } from 'react-icons/tb'; import { CodeHighlight } from '@mantine/code-highlight'; import { FaPython } from "react-icons/fa"; import { FiFileText } from "react-icons/fi"; import { ModalLog } from '../../components/ModalLog'; import { useListState } from '@mantine/hooks'; import { ExceptionWarning } from '../../components/NFProxy/ExceptionWarning'; import { DocsButton } from '../../components/DocsButton'; import TLSAssociationBadge from '../../components/TLSAssociationBadge'; export default function ServiceDetailsNFProxy() { const { srv } = useParams() const services = nfproxyServiceQuery() const serviceInfo = services.data?.find(s => s.service_id == srv) const filtersList = nfproxyServicePyfiltersQuery(srv ?? "") const [deleteModal, setDeleteModal] = useState(false) const [renameModal, setRenameModal] = useState(false) const [editModal, setEditModal] = useState(false) const [buttonLoading, setButtonLoading] = useState(false) const queryClient = useQueryClient() const filterCode = nfproxyServiceFilterCodeQuery(srv ?? "") const navigate = useNavigate() const isMedium = isMediumScreen() const [openLogModal, setOpenLogModal] = useState(false) const [logData, logDataSetters] = useListState([]); useEffect(() => { if (srv) { if (openLogModal) { logDataSetters.setState([]) socketio.emit("nfproxy-outstream-join", { service: srv }); socketio.on(`nfproxy-outstream-${srv}`, (data) => { logDataSetters.append(data) }); } else { socketio.emit("nfproxy-outstream-leave", { service: srv }); socketio.off(`nfproxy-outstream-${srv}`); logDataSetters.setState([]) } return () => { socketio.emit("nfproxy-outstream-leave", { service: srv }); socketio.off(`nfproxy-outstream-${srv}`); logDataSetters.setState([]) } } }, [openLogModal, srv]) if (services.isLoading) return if (!srv || !serviceInfo || filtersList.isError) return let status_color = "gray"; switch (serviceInfo.status) { case "stop": status_color = "red"; break; case "active": status_color = "teal"; break; } const startService = async () => { setButtonLoading(true) await nfproxy.servicestart(serviceInfo.service_id).then(res => { if (!res) { okNotify(`Service ${serviceInfo.name} started successfully!`, `The service on ${serviceInfo.port} has been started!`) queryClient.invalidateQueries({ queryKey: serviceQueryKey }) } else { errorNotify(`An error as occurred during the starting of the service ${serviceInfo.port}`, `Error: ${res}`) } }).catch(err => { errorNotify(`An error as occurred during the starting of the service ${serviceInfo.port}`, `Error: ${err}`) }) setButtonLoading(false) } const deleteService = () => { nfproxy.servicedelete(serviceInfo.service_id).then(res => { if (!res) { okNotify("Service delete complete!", `The service ${serviceInfo.name} has been deleted!`) queryClient.invalidateQueries({ queryKey: serviceQueryKey }) } else errorNotify("An error occurred while deleting a service", `Error: ${res}`) }).catch(err => { errorNotify("An error occurred while deleting a service", `Error: ${err}`) }) } const stopService = async () => { setButtonLoading(true) await nfproxy.servicestop(serviceInfo.service_id).then(res => { if (!res) { okNotify(`Service ${serviceInfo.name} stopped successfully!`, `The service on ${serviceInfo.port} has been stopped!`) queryClient.invalidateQueries({ queryKey: serviceQueryKey }) } else { errorNotify(`An error as occurred during the stopping of the service ${serviceInfo.port}`, `Error: ${res}`) } }).catch(err => { errorNotify(`An error as occurred during the stopping of the service ${serviceInfo.port}`, `Error: ${err}`) }) setButtonLoading(false); } return <> navigate("/nfproxy")}> {serviceInfo.name} {serviceInfo.status} :{serviceInfo.port} {serviceInfo.target_type === 'tls' && ( )} {serviceInfo.target_type === 'tls' ? 'decrypted traffic to ' : ''}{serviceInfo.ip_int} on {serviceInfo.proto} }> {serviceInfo.blocked_packets} }> {serviceInfo.edited_packets} }> {serviceInfo.n_filters} setOpenLogModal(true)} variant="light"> Service Tools } onClick={() => setEditModal(true)}>Service Settings } onClick={() => setRenameModal(true)}>Change Name Danger zone } onClick={() => setDeleteModal(true)}>Delete Service {filterCode.data ? <> Filter code : null} {(!filtersList.data || filtersList.data.length == 0) ? ( No filters found! Create some proxy filters, install the firegex client:<Space w="xs" /><Code mb={-4} >pip install -U fgex</Code> Read the documentation for more information<Space w="sm" /><DocsButton doc='nfproxy' /> Then create a new filter file with the following syntax and upload it here (using the button above) ) : {filtersList.data?.map((filterInfo) => )} } setDeleteModal(false)} action={deleteService} opened={deleteModal} /> setRenameModal(false)} opened={renameModal} service={serviceInfo} /> setEditModal(false)} edit={serviceInfo} /> setOpenLogModal(false)} title={`Logs for service ${serviceInfo.name}`} data={logData.join("")} /> }