diff --git a/README.md b/README.md index aa4bc3a..1e4e8b5 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ This means that firegex is projected to avoid any possibility to have the servic Initiially the project was based only on regex filters, and also now the main function uses regexes, but firegex have and will have also other filtering tools. # Credits -- Copyright (c) 2022 Pwnzer0tt1 +- Copyright (c) 2022-2025 Pwnzer0tt1 ## Star History diff --git a/frontend/bun.lock b/frontend/bun.lock index 01d62fd..526f399 100644 --- a/frontend/bun.lock +++ b/frontend/bun.lock @@ -141,17 +141,17 @@ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="], - "@mantine/core": ["@mantine/core@7.16.2", "", { "dependencies": { "@floating-ui/react": "^0.26.28", "clsx": "^2.1.1", "react-number-format": "^5.4.3", "react-remove-scroll": "^2.6.2", "react-textarea-autosize": "8.5.6", "type-fest": "^4.27.0" }, "peerDependencies": { "@mantine/hooks": "7.16.2", "react": "^18.x || ^19.x", "react-dom": "^18.x || ^19.x" } }, "sha512-6dwFz+8HrOqFan7GezgpoWyZSCxedh10S8iILGVsc3GXiD4gzo+3VZndZKccktkYZ3GVC9E3cCS3SxbiyKSAVw=="], + "@mantine/core": ["@mantine/core@7.16.3", "", { "dependencies": { "@floating-ui/react": "^0.26.28", "clsx": "^2.1.1", "react-number-format": "^5.4.3", "react-remove-scroll": "^2.6.2", "react-textarea-autosize": "8.5.6", "type-fest": "^4.27.0" }, "peerDependencies": { "@mantine/hooks": "7.16.3", "react": "^18.x || ^19.x", "react-dom": "^18.x || ^19.x" } }, "sha512-cxhIpfd2i0Zmk9TKdejYAoIvWouMGhzK3OOX+VRViZ5HEjnTQCGl2h3db56ThqB6NfVPCno6BPbt5lwekTtmuQ=="], - "@mantine/form": ["@mantine/form@7.16.2", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "klona": "^2.0.6" }, "peerDependencies": { "react": "^18.x || ^19.x" } }, "sha512-JZkLbZ7xWAZndPrxObkf10gjHj57x8yvI/vobjDhfWN3zFPTSWmSSF6yBE1FpITseOs3oR03hlkqG6EclK6g+g=="], + "@mantine/form": ["@mantine/form@7.16.3", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "klona": "^2.0.6" }, "peerDependencies": { "react": "^18.x || ^19.x" } }, "sha512-GqomUG2Ri5adxYsTU1S5IhKRPcqTG5JkPvMERns8PQAcUz/lvzsnk3wY1v4K5CEbCAdpimle4bSsZTM9g697vg=="], - "@mantine/hooks": ["@mantine/hooks@7.16.2", "", { "peerDependencies": { "react": "^18.x || ^19.x" } }, "sha512-ZFHQhDi9T+r6VR5NEeE47gigPPIAHVIKDOCWsCsbCqHc3yz5l8kiO2RdfUmsTKV2KD/AiXnAw4b6pjQEP58GOg=="], + "@mantine/hooks": ["@mantine/hooks@7.16.3", "", { "peerDependencies": { "react": "^18.x || ^19.x" } }, "sha512-B94FBWk5Sc81tAjV+B3dGh/gKzfqzpzVC/KHyBRWOOyJRqeeRbI/FAaJo4zwppyQo1POSl5ArdyjtDRrRIj2SQ=="], - "@mantine/modals": ["@mantine/modals@7.16.2", "", { "peerDependencies": { "@mantine/core": "7.16.2", "@mantine/hooks": "7.16.2", "react": "^18.x || ^19.x", "react-dom": "^18.x || ^19.x" } }, "sha512-REwAV53Fcz021EE3zLyYdkdFlfG+b24y279Y+eA1jCCH9VMLivXL+gacrox4BcpzREsic9nGVInSNv3VJwPlAQ=="], + "@mantine/modals": ["@mantine/modals@7.16.3", "", { "peerDependencies": { "@mantine/core": "7.16.3", "@mantine/hooks": "7.16.3", "react": "^18.x || ^19.x", "react-dom": "^18.x || ^19.x" } }, "sha512-BJuDzRugK6xLbuFTTo8NLJumVvVmSYsNVcEtmlXOWTE3NkDGktBXGKo8V1B0XfJ9/d/rZw7HCE0p4i76MtA+bQ=="], - "@mantine/notifications": ["@mantine/notifications@7.16.2", "", { "dependencies": { "@mantine/store": "7.16.2", "react-transition-group": "4.4.5" }, "peerDependencies": { "@mantine/core": "7.16.2", "@mantine/hooks": "7.16.2", "react": "^18.x || ^19.x", "react-dom": "^18.x || ^19.x" } }, "sha512-U342XWiiRI1NvOlLsI6PH/pSNe0rxNClJ2w5orvjOMXvaAfDe52mhnzRmtzRxYENp06++3b/G7MjPH+466rF9Q=="], + "@mantine/notifications": ["@mantine/notifications@7.16.3", "", { "dependencies": { "@mantine/store": "7.16.3", "react-transition-group": "4.4.5" }, "peerDependencies": { "@mantine/core": "7.16.3", "@mantine/hooks": "7.16.3", "react": "^18.x || ^19.x", "react-dom": "^18.x || ^19.x" } }, "sha512-wtEME9kSYfXWYmAmQUZ8c+rwNmhdWRBaW1mlPdQsPkzMqkv4q6yy0IpgwcnuHStSG9EHaQBXazmVxMZJdEAWBQ=="], - "@mantine/store": ["@mantine/store@7.16.2", "", { "peerDependencies": { "react": "^18.x || ^19.x" } }, "sha512-9dEGLosrYSePlAwhfx3CxTLcWu2M98TtuYnelAiHEdNEkyafirvZxNt4paMoFXLKR1XPm5wdjDK7bdTaE0t7Og=="], + "@mantine/store": ["@mantine/store@7.16.3", "", { "peerDependencies": { "react": "^18.x || ^19.x" } }, "sha512-6M2M5+0BrRtnVv+PUmr04tY1RjPqyapaHplo90uK1NMhP/1EIqrwTL9KoEtCNCJ5pog1AQtu0bj0QPbqUvxwLg=="], "@rollup/pluginutils": ["@rollup/pluginutils@5.1.4", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ=="], @@ -205,7 +205,7 @@ "@types/jest": ["@types/jest@27.5.2", "", { "dependencies": { "jest-matcher-utils": "^27.0.0", "pretty-format": "^27.0.0" } }, "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA=="], - "@types/node": ["@types/node@20.17.16", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-vOTpLduLkZXePLxHiHsBLp98mHGnl8RptV4YAO3HfKO5UHjDvySGbxKtpYfy8Sx5+WKcgc45qNreJJRVM3L6mw=="], + "@types/node": ["@types/node@20.17.17", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-/WndGO4kIfMicEQLTi/mDANUu/iVUhT7KboZPdEqqHQ4aTS+3qT3U5gIqWDFV+XouorjfgGqvKILJeHhuQgFYg=="], "@types/prop-types": ["@types/prop-types@15.7.14", "", {}, "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ=="], diff --git a/frontend/package.json b/frontend/package.json index 8a0cba7..071420d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -5,14 +5,14 @@ "private": true, "dependencies": { "@hello-pangea/dnd": "^16.6.0", - "@mantine/core": "^7.16.2", - "@mantine/form": "^7.16.2", - "@mantine/hooks": "^7.16.2", - "@mantine/modals": "^7.16.2", - "@mantine/notifications": "^7.16.2", + "@mantine/core": "^7.16.3", + "@mantine/form": "^7.16.3", + "@mantine/hooks": "^7.16.3", + "@mantine/modals": "^7.16.3", + "@mantine/notifications": "^7.16.3", "@tanstack/react-query": "^4.36.1", "@types/jest": "^27.5.2", - "@types/node": "^20.17.16", + "@types/node": "^20.17.17", "@types/react": "^18.3.18", "@types/react-dom": "^18.3.5", "buffer": "^6.0.3", diff --git a/frontend/src/components/NFRegex/AddNewService.tsx b/frontend/src/components/NFRegex/AddNewService.tsx index f0dbc17..f88f7a9 100644 --- a/frontend/src/components/NFRegex/AddNewService.tsx +++ b/frontend/src/components/NFRegex/AddNewService.tsx @@ -86,16 +86,16 @@ function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void }) /> - + - - {error?<> - } color="red" onClose={()=>{setError(null)}}> - Error: {error} - :null} + + } color="red" onClose={()=>{setError(null)}}> + Error: {error} + + :null} diff --git a/frontend/src/components/NFRegex/ServiceRow/RenameForm.tsx b/frontend/src/components/NFRegex/ServiceRow/RenameForm.tsx index 412be2c..a643bec 100644 --- a/frontend/src/components/NFRegex/ServiceRow/RenameForm.tsx +++ b/frontend/src/components/NFRegex/ServiceRow/RenameForm.tsx @@ -49,16 +49,16 @@ function RenameForm({ opened, onClose, service }:{ opened:boolean, onClose:()=>v placeholder="Awesome Service Name!" {...form.getInputProps('name')} /> - + - - {error?<> - } color="red" onClose={()=>{setError(null)}}> - Error: {error} - :null} + + } color="red" onClose={()=>{setError(null)}}> + Error: {error} + + :null} diff --git a/frontend/src/components/NFRegex/ServiceRow/index.tsx b/frontend/src/components/NFRegex/ServiceRow/index.tsx index 0ec16a2..d8167bc 100644 --- a/frontend/src/components/NFRegex/ServiceRow/index.tsx +++ b/frontend/src/components/NFRegex/ServiceRow/index.tsx @@ -2,7 +2,7 @@ import { ActionIcon, Badge, Box, Divider, Grid, Menu, Space, Title, Tooltip } fr import { useState } from 'react'; import { FaPlay, FaStop } from 'react-icons/fa'; import { nfregex, Service, serviceQueryKey } from '../utils'; -import { MdOutlineArrowForwardIos } from "react-icons/md" +import { MdDoubleArrow, MdOutlineArrowForwardIos } from "react-icons/md" import YesNoModal from '../../YesNoModal'; import { errorNotify, isMediumScreen, okNotify, regex_ipv4 } from '../../../js/utils'; import { BsTrashFill } from 'react-icons/bs'; @@ -10,8 +10,10 @@ import { BiRename } from 'react-icons/bi' import RenameForm from './RenameForm'; import { MenuDropDownWithButton } from '../../MainLayout'; import { useQueryClient } from '@tanstack/react-query'; +import { FaFilter } from "react-icons/fa"; +import { VscRegex } from "react-icons/vsc"; -function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void }) { +export default function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void }) { let status_color = "gray"; switch(service.status){ @@ -72,36 +74,34 @@ function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void }) return <> - - - - - + <Box className="firegex__nfregex__row" style={{width:"100%", flexDirection: isMedium?"row":"column"}}> + <Box> + <Box className="center-flex" style={{ justifyContent: "flex-start" }}> + <MdDoubleArrow size={30} style={{color: "white"}}/> + <Title className="firegex__nfregex__name" ml="xs"> {service.name} - - Status: {service.status} - - :{service.port} - - - {isMedium?null:} - + + {service.status} + + :{service.port} + + + {isMedium?null:} + - - - - - + - Connections Blocked: {service.n_packets} - - Regex: {service.n_regex} - {service.ip_int} on {service.proto} + + + {service.n_packets} + + {service.n_regex} + - {isMedium?:} + {isMedium?:} Rename service @@ -129,14 +129,12 @@ function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void }) {isMedium?:} - {onClick? + {onClick? :null} - {isMedium?:null} - - - + + void }) /> } - -export default ServiceRow; diff --git a/frontend/src/components/PortHijack/AddNewService.tsx b/frontend/src/components/PortHijack/AddNewService.tsx index b685672..44622be 100644 --- a/frontend/src/components/PortHijack/AddNewService.tsx +++ b/frontend/src/components/PortHijack/AddNewService.tsx @@ -94,16 +94,16 @@ function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void }) /> - + - - {error?<> - } color="red" onClose={()=>{setError(null)}}> - Error: {error} - :null} + + } color="red" onClose={()=>{setError(null)}}> + Error: {error} + + :null} diff --git a/frontend/src/components/PortHijack/ServiceRow/ChangeDestination.tsx b/frontend/src/components/PortHijack/ServiceRow/ChangeDestination.tsx index e4f2bef..8d135e9 100644 --- a/frontend/src/components/PortHijack/ServiceRow/ChangeDestination.tsx +++ b/frontend/src/components/PortHijack/ServiceRow/ChangeDestination.tsx @@ -53,15 +53,16 @@ function ChangeDestination({ opened, onClose, service }:{ opened:boolean, onClos
- + - {error?<> - } color="red" onClose={()=>{setError(null)}}> - Error: {error} - :null} + + } color="red" onClose={()=>{setError(null)}}> + Error: {error} + + :null} diff --git a/frontend/src/components/PortHijack/ServiceRow/RenameForm.tsx b/frontend/src/components/PortHijack/ServiceRow/RenameForm.tsx index 84f9fba..4d75c42 100644 --- a/frontend/src/components/PortHijack/ServiceRow/RenameForm.tsx +++ b/frontend/src/components/PortHijack/ServiceRow/RenameForm.tsx @@ -49,16 +49,16 @@ function RenameForm({ opened, onClose, service }:{ opened:boolean, onClose:()=>v placeholder="Awesome Service Name!" {...form.getInputProps('name')} /> - + - - {error?<> - } color="red" onClose={()=>{setError(null)}}> - Error: {error} - :null} + + } color="red" onClose={()=>{setError(null)}}> + Error: {error} + + :null} diff --git a/frontend/src/components/PortHijack/ServiceRow/index.tsx b/frontend/src/components/PortHijack/ServiceRow/index.tsx index d481f75..2f4a136 100644 --- a/frontend/src/components/PortHijack/ServiceRow/index.tsx +++ b/frontend/src/components/PortHijack/ServiceRow/index.tsx @@ -8,11 +8,11 @@ import { BsArrowRepeat, BsTrashFill } from 'react-icons/bs'; import { BiRename } from 'react-icons/bi' import RenameForm from './RenameForm'; import ChangeDestination from './ChangeDestination'; -import PortInput from '../../PortInput'; import { useForm } from '@mantine/form'; import { MenuDropDownWithButton } from '../../MainLayout'; +import { MdDoubleArrow } from "react-icons/md"; -function ServiceRow({ service }:{ service:Service }) { +export default function ServiceRow({ service }:{ service:Service }) { let status_color = service.active ? "teal": "red" @@ -72,40 +72,36 @@ function ServiceRow({ service }:{ service:Service }) { return <> - - - - + <Box className="firegex__nfregex__row" style={{width:"100%", flexDirection: isMedium?"row":"column"}}> + <Box> + <Box className="center-flex" style={{ justifyContent: "flex-start" }}> + <MdDoubleArrow size={30} style={{color: "white"}}/> + <Title className="firegex__nfregex__name" ml="xs"> {service.name} - - Status: {service.active?"ENABLED":"DISABLED"} - - {service.proto} - - - {isMedium?null:} - + + {service.active?"ENABLED":"DISABLED"} + + {service.proto} + + + {isMedium?null:} + - - - - - - + - - FROM {service.ip_src} : {service.public_port} + + FROM {service.ip_src} :{service.public_port} - + - TO {service.ip_dst} : service.proxy_port + TO {service.ip_dst} :{service.proxy_port} - {isMedium?:} + {isMedium?:} Rename service @@ -134,14 +130,10 @@ function ServiceRow({ service }:{ service:Service }) { - - {isMedium?:null} - - - + + - } - -export default ServiceRow; diff --git a/frontend/src/components/RegexView/index.tsx b/frontend/src/components/RegexView/index.tsx index 20b9d18..e5b0821 100644 --- a/frontend/src/components/RegexView/index.tsx +++ b/frontend/src/components/RegexView/index.tsx @@ -1,18 +1,19 @@ -import { Grid, Text, Title, Badge, Space, ActionIcon, Tooltip, Box } from '@mantine/core'; +import { Text, Title, Badge, Space, ActionIcon, Tooltip, Box } from '@mantine/core'; import { useState } from 'react'; import { RegexFilter } from '../../js/models'; -import { b64decode, errorNotify, getapiobject, okNotify } from '../../js/utils'; +import { b64decode, errorNotify, getapiobject, isMediumScreen, okNotify } from '../../js/utils'; import { BsTrashFill } from "react-icons/bs" import YesNoModal from '../YesNoModal'; import { FaPause, FaPlay } from 'react-icons/fa'; import { useClipboard } from '@mantine/hooks'; - +import { FaFilter } from "react-icons/fa"; +import { VscRegex } from "react-icons/vsc"; function RegexView({ regexInfo }:{ regexInfo:RegexFilter }) { const mode_string = regexInfo.mode === "C"? "C -> S": regexInfo.mode === "S"? "S -> C": - regexInfo.mode === "B"? "S <-> C": "🤔" + regexInfo.mode === "B"? "C <-> S": "🤔" let regex_expr = b64decode(regexInfo.regex); @@ -20,6 +21,7 @@ function RegexView({ regexInfo }:{ regexInfo:RegexFilter }) { const [deleteTooltipOpened, setDeleteTooltipOpened] = useState(false); const [statusTooltipOpened, setStatusTooltipOpened] = useState(false); const clipboard = useClipboard({ timeout: 500 }); + const isMedium = isMediumScreen(); const deleteRegex = () => { getapiobject().regexdelete(regexInfo.id).then(res => { @@ -42,57 +44,39 @@ function RegexView({ regexInfo }:{ regexInfo:RegexFilter }) { } return - - - Regex: - - + + { clipboard.copy(regex_expr) okNotify("Regex copied to clipboard!",`The regex '${regex_expr}' has been copied to the clipboard!`) }}>{regex_expr} - - setStatusTooltipOpened(false)} onBlur={() => setStatusTooltipOpened(false)} - onMouseEnter={() => setStatusTooltipOpened(true)} onMouseLeave={() => setStatusTooltipOpened(false)} + onFocus={() => setStatusTooltipOpened(false)} onBlur={() => setStatusTooltipOpened(false)} + onMouseEnter={() => setStatusTooltipOpened(true)} onMouseLeave={() => setStatusTooltipOpened(false)} >{regexInfo.active?:} setDeleteModal(true)} size="xl" radius="md" variant="filled" - onFocus={() => setDeleteTooltipOpened(false)} onBlur={() => setDeleteTooltipOpened(false)} - onMouseEnter={() => setDeleteTooltipOpened(true)} onMouseLeave={() => setDeleteTooltipOpened(false)} + onFocus={() => setDeleteTooltipOpened(false)} onBlur={() => setDeleteTooltipOpened(false)} + onMouseEnter={() => setDeleteTooltipOpened(true)} onMouseLeave={() => setDeleteTooltipOpened(false)} > - - - - - - - Service: {regexInfo.service_id} - - {regexInfo.active?"ACTIVE":"DISABLED"} - - ID: {regexInfo.id} - - - - - - Case: {regexInfo.is_case_sensitive?"SENSIIVE":"INSENSITIVE"} - - Packets filtered: {regexInfo.n_packets} - - Mode: {mode_string} - - - + + + {regexInfo.n_packets} + + {regexInfo.active?"ACTIVE":"DISABLED"} + + {regexInfo.is_case_sensitive?"Strict":"Loose"} + + {mode_string} + + {description} - +