import { ActionIcon, Box, Code, Grid, LoadingOverlay, Space, Title, Tooltip } from '@mantine/core'; import { Navigate, useNavigate, useParams } from 'react-router-dom'; 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'; 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(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(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(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 <> <Box className="center-flex"> <MdDoubleArrow /><Space w="sm" />{serviceInfo.name} </Box> {isMedium?null:} {serviceInfo.status} :{serviceInfo.port} Edit service } onClick={()=>setEditModal(true)}>Service Settings } onClick={()=>setRenameModal(true)}>Change service name Danger zone } onClick={()=>setDeleteModal(true)}>Delete Service setOpenLogModal(true)} loading={buttonLoading} variant="filled"> {isMedium?null:} {serviceInfo.edited_packets} {serviceInfo.blocked_packets} {serviceInfo.n_filters} {isMedium?:} {serviceInfo.ip_int} on {serviceInfo.proto} {isMedium?null:} navigate("/")} size="xl" radius="md" variant="filled" aria-describedby="tooltip-back-id"> {filterCode.data?<> <FaPython style={{ marginBottom: -3 }} size={30} /><Space w="xs" />Filter code : null} {(!filtersList.data || filtersList.data.length == 0)?<> No filters found! Edit the proxy file, install the firegex client:<Space w="xs" /><Code mb={-4} >pip install fgex</Code> Then create a new filter file with the following syntax and upload it here (using the button above) Before upload the filter you can test it using the fgex command installed by the python lib :<>{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("")} /> }