diff --git a/Dockerfile b/Dockerfile
index 4fa908c..a589938 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -4,7 +4,7 @@
# Needed for start.py to detect the Dockerfile
-FROM --platform=$BUILDPLATFORM oven/bun AS frontend
+FROM --platform=$BUILDPLATFORM oven/bun AS frontend
WORKDIR /app
ADD ./frontend/package.json .
ADD ./frontend/bun.lockb .
diff --git a/backend/app.py b/backend/app.py
index e2c927b..6ba5685 100644
--- a/backend/app.py
+++ b/backend/app.py
@@ -10,6 +10,7 @@ from utils import API_VERSION, FIREGEX_PORT, JWT_ALGORITHM, get_interfaces, sock
from utils.loader import frontend_deploy, load_routers
from utils.models import ChangePasswordModel, IpInterface, PasswordChangeForm, PasswordForm, ResetRequest, StatusModel, StatusMessageModel
from contextlib import asynccontextmanager
+from fastapi.middleware.cors import CORSMiddleware
# DB init
db = SQLite('db/firegex.db')
@@ -32,6 +33,9 @@ async def lifespan(app):
app = FastAPI(debug=DEBUG, redoc_url=None, lifespan=lifespan)
utils.socketio = SocketManager(app, "/sock", socketio_path="")
+if DEBUG:
+ app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"])
+
def APP_STATUS(): return "init" if db.get("password") is None else "run"
def JWT_SECRET(): return db.get("secret")
@@ -158,7 +162,7 @@ if __name__ == '__main__':
os.chdir(os.path.dirname(os.path.realpath(__file__)))
uvicorn.run(
"app:app",
- host="0.0.0.0" if DEBUG else None,
+ host="::" if DEBUG else None,
port=FIREGEX_PORT,
reload=DEBUG,
access_log=True,
diff --git a/docs/Firegex_Screenshot.png b/docs/Firegex_Screenshot.png
index 398ff42..7960b95 100644
Binary files a/docs/Firegex_Screenshot.png and b/docs/Firegex_Screenshot.png differ
diff --git a/frontend/bun.lockb b/frontend/bun.lockb
index 2ea2843..0bc4166 100755
Binary files a/frontend/bun.lockb and b/frontend/bun.lockb differ
diff --git a/frontend/package.json b/frontend/package.json
index b127304..bbdd0a4 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -2,39 +2,33 @@
"name": "firegex-frontend",
"version": "0.1.0",
"private": true,
+ "type": "module",
"dependencies": {
- "@emotion/react": "^11.11.0",
- "@hello-pangea/dnd": "^16.3.0",
- "@mantine/core": "^6.0.21",
- "@mantine/form": "^6.0.21",
- "@mantine/hooks": "^6.0.21",
- "@mantine/modals": "^6.0.21",
- "@mantine/notifications": "^6.0.21",
- "@mantine/prism": "^6.0.21",
- "@mantine/spotlight": "^6.0.21",
- "@tanstack/react-query": "^4.35.3",
- "@testing-library/dom": "^9.3.0",
- "@testing-library/jest-dom": "^5.16.4",
- "@testing-library/react": "^13.3.0",
- "@testing-library/user-event": "^13.5.0",
+ "@hello-pangea/dnd": "^16.6.0",
+ "@mantine/core": "^7.13.2",
+ "@mantine/form": "^7.13.2",
+ "@mantine/hooks": "^7.13.2",
+ "@mantine/modals": "^7.13.2",
+ "@mantine/notifications": "^7.13.2",
+ "@tanstack/react-query": "^4.36.1",
"@types/jest": "^27.5.2",
- "@types/node": "^20.2.5",
- "@types/react": "^18.0.12",
- "@types/react-dom": "^18.0.5",
+ "@types/node": "^20.16.11",
+ "@types/react": "^18.3.11",
+ "@types/react-dom": "^18.3.1",
"buffer": "^6.0.3",
- "react": "^18.1.0",
- "react-dom": "^18.1.0",
- "react-icons": "^4.4.0",
- "react-router-dom": "^6.3.0",
- "sass": "^1.62.1",
- "socket.io-client": "^4.5.1",
- "typescript": "^4.7.3",
- "web-vitals": "^2.1.4"
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "react-icons": "^5.3.0",
+ "react-router-dom": "^6.27.0",
+ "socket.io-client": "^4.8.0",
+ "typescript": "^4.9.5",
+ "web-vitals": "^2.1.4",
+ "zustand": "^5.0.0-rc.2"
},
"scripts": {
- "start": "vite",
+ "dev": "vite",
"build": "tsc && vite build",
- "serve": "vite preview"
+ "preview": "vite preview"
},
"eslintConfig": {
"extends": [
@@ -55,10 +49,10 @@
]
},
"devDependencies": {
- "@tanstack/react-query-devtools": "^4.35.3",
- "@vitejs/plugin-react": "^4.0.0",
- "vite": "^4.3.9",
- "vite-plugin-svgr": "^3.2.0",
- "vite-tsconfig-paths": "^4.2.0"
+ "@tanstack/react-query-devtools": "^4.36.1",
+ "@vitejs/plugin-react": "^4.3.2",
+ "vite": "^4.5.5",
+ "vite-plugin-svgr": "^3.3.0",
+ "vite-tsconfig-paths": "^4.3.2"
}
}
diff --git a/frontend/public/header-logo.png b/frontend/public/header-logo.png
index 2f0bc63..67770de 100644
Binary files a/frontend/public/header-logo.png and b/frontend/public/header-logo.png differ
diff --git a/frontend/src/.dockerignore b/frontend/src/.dockerignore
new file mode 100644
index 0000000..767c392
--- /dev/null
+++ b/frontend/src/.dockerignore
@@ -0,0 +1,31 @@
+Dockerfile
+
+**/*.pyc
+**/__pycache__/
+**/.vscode/**
+**/.vscode/
+**/.mypy_cache/**
+**/.mypy_cache/
+
+**/node_modules
+**/.pnp
+**/.pnp.js
+
+# testing
+/coverage
+
+/build/
+/build/**
+/node_modules/
+
+# misc
+**/.DS_Store
+**/.env.local
+**/.env.development.local
+**/.env.test.local
+**/.env.production.local
+
+**/npm-debug.log*
+**/yarn-debug.log*
+**/yarn-error.log*
+
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index efce8fe..8a027a7 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -1,4 +1,4 @@
-import { Button, Group, Loader, LoadingOverlay, Notification, Space, PasswordInput, Title } from '@mantine/core';
+import { Button, Group, Loader, LoadingOverlay, Notification, Space, PasswordInput, Title, Box } from '@mantine/core';
import { useForm } from '@mantine/form';
import { useEffect, useState } from 'react';
import { ImCross } from 'react-icons/im';
@@ -66,15 +66,15 @@ function App() {
if (loading){
return
}else if (reqError){
- return
-
Error launching Firegex! 🔥
+ return
+ Error launching Firegex! 🔥
- Error communicating with backend
+ Error communicating with backend
Error: {reqError}
-
+
}else if (systemStatus.status === "init"){
const submitRequest = async (values:PasswordSend) => {
@@ -90,8 +90,8 @@ function App() {
}
- return
-
Setup: Choose the password for access to the firewall 🔒
+ return
+ Setup: Choose the password for access to the firewall 🔒
@@ -108,7 +108,7 @@ function App() {
} color="red" onClose={()=>{setError(null)}}>
Error: {error}
>:null}
-
+
}else if (systemStatus.status === "run" && !systemStatus.loggined){
const submitRequest = async (values:PasswordSend) => {
setLoadingBtn(true)
@@ -123,10 +123,10 @@ function App() {
}
- return
-
Welcome to Firegex 🔥
+ return
+ Welcome to Firegex 🔥
- Before you use the firewall, insert the password 🔒
+ Before you use the firewall, insert the password 🔒
@@ -143,7 +143,7 @@ function App() {
} color="red" onClose={()=>{setError(null)}}>
Error: {error}
>:null}
-
+
}else if (systemStatus.status === "run" && systemStatus.loggined){
return
}>
@@ -159,11 +159,11 @@ function App() {
}else{
- return
-
Error launching Firegex! 🔥
+ return
+ Error launching Firegex! 🔥
- Error communicating with backend
-
+ Error communicating with backend
+
}
}
diff --git a/frontend/src/_vars.scss b/frontend/src/_vars.scss
deleted file mode 100644
index 6df635d..0000000
--- a/frontend/src/_vars.scss
+++ /dev/null
@@ -1,4 +0,0 @@
-
-$primary_color: #242a33;
-$secondary_color: #1A1B1E;
-$third_color:#25262b;
diff --git a/frontend/src/components/AddNewRegex.tsx b/frontend/src/components/AddNewRegex.tsx
index fddbb57..623120a 100644
--- a/frontend/src/components/AddNewRegex.tsx
+++ b/frontend/src/components/AddNewRegex.tsx
@@ -108,7 +108,7 @@ function AddNewRegex({ opened, onClose, service }:{ opened:boolean, onClose:()=>
}>
Using whitelist means that EVERY packet that doesn't match the regex will be DROPPED... In most cases this cause the service interruption.
>:null}
-
+
Add Filter
diff --git a/frontend/src/components/FilterTypeSelector.tsx b/frontend/src/components/FilterTypeSelector.tsx
index ab7999a..aa331be 100644
--- a/frontend/src/components/FilterTypeSelector.tsx
+++ b/frontend/src/components/FilterTypeSelector.tsx
@@ -1,5 +1,4 @@
import { Box, Center, SegmentedControl } from "@mantine/core";
-import React from "react";
import { FaListAlt } from "react-icons/fa";
import { TiCancel } from "react-icons/ti";
diff --git a/frontend/src/components/Footer/index.module.scss b/frontend/src/components/Footer/index.module.scss
deleted file mode 100644
index be3716c..0000000
--- a/frontend/src/components/Footer/index.module.scss
+++ /dev/null
@@ -1,8 +0,0 @@
-@use "../../vars" as *;
-@use "../../index.scss" as *;
-
-.footer{
- margin-top: 50px;
- background-color: $primary_color;
- @extend .center-flex;
-}
\ No newline at end of file
diff --git a/frontend/src/components/Footer/index.tsx b/frontend/src/components/Footer/index.tsx
deleted file mode 100644
index 66c157a..0000000
--- a/frontend/src/components/Footer/index.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Footer, Space } from '@mantine/core';
-import image from "./pwnzer0tt1.svg"
-
-import style from "./index.module.scss";
-import { Link } from 'react-router-dom';
-
-function FooterPage() {
- return
-}
-
-export default FooterPage;
diff --git a/frontend/src/components/Footer/pwnzer0tt1.svg b/frontend/src/components/Footer/pwnzer0tt1.svg
deleted file mode 100644
index 5a3e87b..0000000
--- a/frontend/src/components/Footer/pwnzer0tt1.svg
+++ /dev/null
@@ -1,595 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend/src/components/Header/ResetModal.tsx b/frontend/src/components/Header/ResetModal.tsx
index b0e2fe4..0b9d46f 100644
--- a/frontend/src/components/Header/ResetModal.tsx
+++ b/frontend/src/components/Header/ResetModal.tsx
@@ -47,7 +47,7 @@ function ResetModal({ opened, onClose }:{ opened: boolean, onClose: () => void }
{...form.getInputProps('delete_data', { type: 'checkbox' })}
/>
-
+
Cancel
Reset
diff --git a/frontend/src/components/Header/ResetPasswordModal.tsx b/frontend/src/components/Header/ResetPasswordModal.tsx
index ad880d8..c607087 100644
--- a/frontend/src/components/Header/ResetPasswordModal.tsx
+++ b/frontend/src/components/Header/ResetPasswordModal.tsx
@@ -46,7 +46,7 @@ function ResetPasswordModal({ opened, onClose }:{ opened: boolean, onClose: () =
{...form.getInputProps('expire', { type: 'checkbox' })}
/>
-
+
Change Password
diff --git a/frontend/src/components/Header/index.module.scss b/frontend/src/components/Header/index.module.scss
deleted file mode 100644
index 369c4ef..0000000
--- a/frontend/src/components/Header/index.module.scss
+++ /dev/null
@@ -1,24 +0,0 @@
-
-@use "../../vars" as *;
-@use "../../index.scss" as *;
-
-.header{
- width: 100%;
- background-color: $primary_color;
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.divlogo{
- width: 110px;
- height: 100%;
- cursor: pointer;
- @extend .center-flex;
-}
-
-.navbtn{
- @extend .center-flex;
- width: 30px;
- margin:0;
-}
\ No newline at end of file
diff --git a/frontend/src/components/Header/index.tsx b/frontend/src/components/Header/index.tsx
index 7e28a08..938c8fb 100644
--- a/frontend/src/components/Header/index.tsx
+++ b/frontend/src/components/Header/index.tsx
@@ -1,7 +1,6 @@
import React, { useState } from 'react';
-import { ActionIcon, Divider, Image, Menu, Tooltip, Burger, Space, Header, Button, ThemeIcon } from '@mantine/core';
-import style from "./index.module.scss";
-import { errorNotify, getmainpath, isLargeScreen, logout } from '../../js/utils';
+import { ActionIcon, Divider, Image, Menu, Tooltip, Burger, Space, AppShell, Box, Title } from '@mantine/core';
+import { errorNotify, getMainPath, isLargeScreen, logout } from '../../js/utils';
import { AiFillHome } from "react-icons/ai"
import { useNavigate } from 'react-router-dom';
import { FaLock } from 'react-icons/fa';
@@ -10,11 +9,13 @@ import { ImExit } from 'react-icons/im';
import ResetPasswordModal from './ResetPasswordModal';
import ResetModal from './ResetModal';
import { MenuDropDownWithButton } from '../MainLayout';
+import { useNavbarStore } from '../../js/store';
-function HeaderPage({navOpen, setNav, ...other}: { navOpen: boolean, setNav:React.Dispatch>}) {
+function HeaderPage(props: any) {
const navigator = useNavigate()
+ const { navOpened, toggleNav } = useNavbarStore()
const logout_action = () => {
logout().then(r => {
@@ -25,40 +26,42 @@ function HeaderPage({navOpen, setNav, ...other}: { navOpen: boolean, setNav:Reac
}
const go_to_home = () => {
- navigator(`/${getmainpath()}`)
+ navigator(`/${getMainPath()}`)
}
const [changePasswordModal, setChangePasswordModal] = useState(false);
const [resetFiregexModal, setResetFiregexModal] = useState(false);
const [tooltipHomeOpened, setTooltipHomeOpened] = useState(false);
const [tooltipLogoutOpened,setTooltipLogoutOpened] = useState(false);
- const isLarge = isLargeScreen()
- console.log(isLarge)
- return
+
}
export default HeaderPage;
diff --git a/frontend/src/components/InterfaceInput.tsx b/frontend/src/components/InterfaceInput.tsx
index 6526c53..2e2b1b2 100644
--- a/frontend/src/components/InterfaceInput.tsx
+++ b/frontend/src/components/InterfaceInput.tsx
@@ -1,55 +1,119 @@
-import { AutocompleteItem, Select, SelectProps } from "@mantine/core";
-import React, { useState } from "react";
+import { Combobox, TextInput, useCombobox } from "@mantine/core";
+import { useState } from "react";
import { ipInterfacesQuery } from "../js/utils";
-
-const AutoCompleteItem = React.forwardRef(
- ({ netint, value, ...props }: ItemProps, ref) =>
- ( {netint} ) -{">"} {value}
-
-);
-
-interface ItemProps extends AutocompleteItem {
+interface ItemProps{
+ value: string
netint: string;
}
-interface InterfaceInputProps extends Omit{
- initialCustomInterfaces?:AutocompleteItem[],
- includeInterfaceNames?:boolean
+interface InterfaceInputProps{
+ initialCustomInterfaces?:ItemProps[],
+ includeInterfaceNames?:boolean,
+ onChange?: (value:string) => void,
+ value?:string,
+ defaultValue?:string
}
-export const InterfaceInput = ({ initialCustomInterfaces, includeInterfaceNames, ...props }:InterfaceInputProps) => {
+export const InterfaceInput = ({ initialCustomInterfaces, includeInterfaceNames, onChange, value, defaultValue }:InterfaceInputProps) => {
- const [customIpInterfaces, setCustomIpInterfaces] = useState(initialCustomInterfaces??[]);
+ const [customIpInterfaces, setCustomIpInterfaces] = useState(initialCustomInterfaces??[]);
const interfacesQuery = ipInterfacesQuery()
const getInterfaces = () => {
if (interfacesQuery.isLoading || !interfacesQuery.data) return []
if(includeInterfaceNames){
- const result = interfacesQuery.data.map(item => ({netint:"IP", value:item.addr, label:item.addr})) as AutocompleteItem[]
- interfacesQuery.data.map(item => item.name).filter((item, index, arr) => arr.indexOf(item) === index).forEach(item => result.push({netint:"INT", value:item, label:item}))
+ const result = interfacesQuery.data.map(item => ({netint:"IP", value:item.addr})) as ItemProps[]
+ interfacesQuery.data.map(item => item.name).filter((item, index, arr) => arr.indexOf(item) === index).forEach(item => result.push({netint:"INT", value:item}))
return result
}
- return (interfacesQuery.data.map(item => ({netint:item.name, value:item.addr, label:item.addr})) as AutocompleteItem[])
+ return (interfacesQuery.data.map(item => ({netint:item.name, value:item.addr})) as ItemProps[])
}
const interfaces = getInterfaces()
- return `+ Use this: ${query}`}
- onCreate={(query) => {
- const item = { value: query, netint: "CUSTOM", label: query };
- setCustomIpInterfaces((current) => [...current, item]);
- return item;
+ const combobox = useCombobox({
+ onDropdownClose: () => {
+ combobox.resetSelectedOption()
+ },
+ });
+
+ const data = [...customIpInterfaces, ...interfaces]
+ const [selectedValue, setSelectedValue] = useState(null);
+ const [search, setSearch] = useState('');
+
+ const exactOptionMatch: ItemProps|undefined = data.find((item) => item.value === search);
+
+ const filteredOptions = data.filter((item) => item.value.toLowerCase().includes(search.toLowerCase().trim())).sort((a, b) => {
+ if (exactOptionMatch != null) {
+ if (a.value == exactOptionMatch.value) return -1
+ if (b.value == exactOptionMatch.value) return 1
+ }
+ return a.value.localeCompare(b.value)
+ });
+
+ const options = filteredOptions.map((item) => (
+
+ ( {item.netint} ) -{">"} {item.value}
+
+ ));
+
+ return <>
+ {
+ if (value === '$create') {
+ const item = { value: search, netint: "CUSTOM" };
+ setCustomIpInterfaces((current) => [...current, item]);
+ setSelectedValue(search);
+ onChange?.(search)
+ } else {
+ setSelectedValue(value);
+ setSearch(value);
+ onChange?.(value)
+ }
+ combobox.closeDropdown();
}}
- style={props.style?{width:"100%", ...props.style}:{width:"100%"}}
- {...props}
- />
+ >
+
+
+ }
+ value={value??(defaultValue?undefined:search)}
+ placeholder="10.1.1.1"
+ rightSectionPointerEvents="none"
+ onChange={(event) => {
+ combobox.openDropdown();
+ combobox.updateSelectedOptionIndex();
+ setSearch(event.currentTarget.value)
+ onChange?.(event.currentTarget.value)
+
+ }}
+ onClick={(e) => {
+ combobox.openDropdown()
+ }}
+ onFocus={(e) => {
+ combobox.openDropdown()
+ }}
+ onBlur={(e) => {
+ combobox.closeDropdown();
+ setSearch(selectedValue??'');
+ }}
+ />
+
+
+
+
+ {options}
+ {(exactOptionMatch==null) && search.trim().length > 0 && (
+ + Use this: {search}
+ )}
+
+
+
+ >
}
\ No newline at end of file
diff --git a/frontend/src/components/MainLayout.tsx b/frontend/src/components/MainLayout.tsx
index 8705288..db8e212 100644
--- a/frontend/src/components/MainLayout.tsx
+++ b/frontend/src/components/MainLayout.tsx
@@ -1,44 +1,38 @@
-import { useEffect, useState } from 'react';
+import { useEffect } from 'react';
import { ActionIcon, Container, Menu, Space } from '@mantine/core';
import { AppShell } from '@mantine/core';
import NavBar from './NavBar';
-import FooterPage from './Footer';
import HeaderPage from './Header';
-import { getmainpath } from '../js/utils';
+import { getMainPath } from '../js/utils';
import { useLocation } from 'react-router-dom';
import { RiMenu5Fill } from 'react-icons/ri';
-
-
+import { useNavbarStore } from '../js/store';
function MainLayout({ children }:{ children:any }) {
- const [opened, setOpened] = useState(false);
+ const { navOpened } = useNavbarStore()
const location = useLocation()
useEffect(()=>{
if (location.pathname !== "/"){
- sessionStorage.setItem('home_section', getmainpath())
+ sessionStorage.setItem('home_section', getMainPath())
}
},[location.pathname])
-
-
- return <>
-
- setOpened(false)} opened={opened} />}
- header={ }
- footer={ }
+ return
-
- {children}
-
+
+
+
+
+ {children}
+
+
->
-
}
export default MainLayout;
@@ -46,7 +40,7 @@ export default MainLayout;
export const MenuDropDownWithButton = ({children}:{children:any}) =>
-
+
diff --git a/frontend/src/components/NFRegex/AddNewService.tsx b/frontend/src/components/NFRegex/AddNewService.tsx
index 4aef819..f0dbc17 100644
--- a/frontend/src/components/NFRegex/AddNewService.tsx
+++ b/frontend/src/components/NFRegex/AddNewService.tsx
@@ -1,4 +1,4 @@
-import { Button, Group, Space, TextInput, Notification, Modal, Switch, SegmentedControl } from '@mantine/core';
+import { Button, Group, Space, TextInput, Notification, Modal, Switch, SegmentedControl, Box } from '@mantine/core';
import { useForm } from '@mantine/form';
import { useState } from 'react';
import { okNotify, regex_ipv4, regex_ipv6 } from '../../js/utils';
@@ -71,12 +71,12 @@ function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void })
-
+
-
+
void })
]}
{...form.getInputProps('proto')}
/>
-
+
-
+
Add Service
diff --git a/frontend/src/components/NFRegex/ServiceRow/RenameForm.tsx b/frontend/src/components/NFRegex/ServiceRow/RenameForm.tsx
index ef44830..412be2c 100644
--- a/frontend/src/components/NFRegex/ServiceRow/RenameForm.tsx
+++ b/frontend/src/components/NFRegex/ServiceRow/RenameForm.tsx
@@ -49,7 +49,7 @@ function RenameForm({ opened, onClose, service }:{ opened:boolean, onClose:()=>v
placeholder="Awesome Service Name!"
{...form.getInputProps('name')}
/>
-
+
Rename
diff --git a/frontend/src/components/NFRegex/ServiceRow/index.module.scss b/frontend/src/components/NFRegex/ServiceRow/index.module.scss
deleted file mode 100644
index 4b15044..0000000
--- a/frontend/src/components/NFRegex/ServiceRow/index.module.scss
+++ /dev/null
@@ -1,23 +0,0 @@
-
-@use "../../../index.scss" as *;
-
-.row{
- width: 95%;
- padding: 30px 0px;
- border-radius: 20px;
- margin: 10px;
- @extend .center-flex;
-}
-
-.name{
- font-size: 2.3em;
- font-weight: bolder;
- margin-right: 10px;
- margin-bottom: 13px;
- color:#FFF;
- max-width: 300px;
- overflow: hidden;
-}
-.name:hover{
- overflow: auto;
-}
\ No newline at end of file
diff --git a/frontend/src/components/NFRegex/ServiceRow/index.tsx b/frontend/src/components/NFRegex/ServiceRow/index.tsx
index 4aa89b0..0ec16a2 100644
--- a/frontend/src/components/NFRegex/ServiceRow/index.tsx
+++ b/frontend/src/components/NFRegex/ServiceRow/index.tsx
@@ -1,9 +1,8 @@
-import { ActionIcon, Badge, Divider, Grid, Menu, Space, Title, Tooltip } from '@mantine/core';
+import { ActionIcon, Badge, Box, Divider, Grid, Menu, Space, Title, Tooltip } from '@mantine/core';
import { useState } from 'react';
import { FaPlay, FaStop } from 'react-icons/fa';
import { nfregex, Service, serviceQueryKey } from '../utils';
import { MdOutlineArrowForwardIos } from "react-icons/md"
-import style from "./index.module.scss";
import YesNoModal from '../../YesNoModal';
import { errorNotify, isMediumScreen, okNotify, regex_ipv4 } from '../../../js/utils';
import { BsTrashFill } from 'react-icons/bs';
@@ -72,71 +71,73 @@ function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void })
}
return <>
-
-
+
+
+
-
-
-
+
+
{service.name}
-
- :{service.port}
-
-
-
Status: {service.status}
- {isMedium?null:
}
-
- {!isMedium? :null}
-
-
-
- {!isMedium?
:<> >}
+
+ Status: {service.status}
+
+ :{service.port}
+
+
+ {isMedium?null: }
+
+
-
- Connections Blocked: {service.n_packets}
-
- Regex: {service.n_regex}
-
- {service.ip_int} on {service.proto}
-
- {isMedium?
:<> >}
-
-
- Rename service
- } onClick={()=>setRenameModal(true)}>Change service name
-
- Danger zone
- } onClick={()=>setDeleteModal(true)}>Delete Service
-
-
-
- setTooltipStopOpened(false)} onBlur={() => setTooltipStopOpened(false)}
- onMouseEnter={() => setTooltipStopOpened(true)} onMouseLeave={() => setTooltipStopOpened(false)}>
-
-
-
-
-
-
-
-
-
-
-
- {onClick?
-
-
-
:null}
- {isMedium?<> >:null}
-
-
-
+
+
+
+
+
+
+ Connections Blocked: {service.n_packets}
+
+ Regex: {service.n_regex}
+
+ {service.ip_int} on {service.proto}
+
+ {isMedium? : }
+
+
+ Rename service
+ } onClick={()=>setRenameModal(true)}>Change service name
+
+ Danger zone
+ } onClick={()=>setDeleteModal(true)}>Delete Service
+
+
+
+ setTooltipStopOpened(false)} onBlur={() => setTooltipStopOpened(false)}
+ onMouseEnter={() => setTooltipStopOpened(true)} onMouseLeave={() => setTooltipStopOpened(false)}>
+
+
+
+
+
+
+
+
+
+ {isMedium? : }
+ {onClick?
+
+ :null}
+ {isMedium? :null}
+
+
+
+
+
void, name:string, icon:any, color:MantineColor, disabled?:boolean, onClick?:CallableFunction }) {
const navigator = useNavigate()
-
- return ({
- display: 'block',
- width: '100%',
- padding: theme.spacing.xs,
- borderRadius: theme.radius.sm,
- opacity: disabled ? 0.4 : 1,
- color: theme.colorScheme === 'dark' ? theme.colors.dark[0] : theme.black,
- backgroundColor:(navigate===getmainpath()?(theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[0]):"transparent"),
- '&:hover': {
- backgroundColor:
- theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[0],
- },
- })} onClick={()=>{
+ return {
if(navigate){navigator(`/${navigate}`);closeNav()}
if (onClick) onClick()
}} disabled={disabled}>
@@ -36,17 +26,16 @@ function NavBarButton({ navigate, closeNav, name, icon, color, disabled, onClick
}
-export default function NavBar({ closeNav, opened }: {closeNav: () => void, opened: boolean}) {
+export default function NavBar() {
const [toggle, setToggleState] = useState(false);
+ const { navOpened, closeNav } = useNavbarStore()
-
- return
-
- [Fi]*regex 🔥
-
+ return
+
+ Options ⚙️
+
-
-
+
} />
} />
} />
@@ -55,7 +44,7 @@ export default function NavBar({ closeNav, opened }: {closeNav: () => void, open
} />
-
+
-
+
}
diff --git a/frontend/src/components/OnOffButton.tsx b/frontend/src/components/OnOffButton.tsx
index cc34f65..eb7498d 100644
--- a/frontend/src/components/OnOffButton.tsx
+++ b/frontend/src/components/OnOffButton.tsx
@@ -1,9 +1,5 @@
-import { ActionIcon, ActionIconProps } from "@mantine/core"
+import { ActionIcon, ActionIconProps, PolymorphicComponentProps } from "@mantine/core"
import { ImCheckmark, ImCross } from "react-icons/im"
-import { TiTick } from "react-icons/ti"
-import {PolymorphicComponentProps} from "@mantine/utils"
-
-
interface IOnOffButtonProps extends Omit, "value">{
value: boolean,
diff --git a/frontend/src/components/PortAndInterface.tsx b/frontend/src/components/PortAndInterface.tsx
index 22a2cf1..53108de 100644
--- a/frontend/src/components/PortAndInterface.tsx
+++ b/frontend/src/components/PortAndInterface.tsx
@@ -1,21 +1,20 @@
-import { AutocompleteItem, Select, Space, Title } from "@mantine/core"
-import React, { useEffect, useState } from "react"
-import { ipInterfacesQuery } from "../js/utils";
+import { Box, Space, Title } from "@mantine/core"
+import React from "react"
import PortInput from "./PortInput";
import { UseFormReturnType } from "@mantine/form/lib/types";
import { InterfaceInput } from "./InterfaceInput";
-interface ItemProps extends AutocompleteItem {
+type ItemProps = {
+ value: string;
netint: string;
-}
+} & any
const AutoCompleteItem = React.forwardRef(
- ({ netint, value, ...props }: ItemProps, ref) =>
+ ({ netint, value, ...props }, ref) =>
( {netint} ) -{">"} {value}
-
+
);
-
export default function PortAndInterface({ form, int_name, port_name, label, orientation }:{ form:UseFormReturnType, int_name:string, port_name:string, label?:string, orientation?:"line"|"column" }) {
@@ -24,7 +23,7 @@ export default function PortAndInterface({ form, int_name, port_name, label, ori
{label?<>
{label}
> :null}
-
+
@@ -32,6 +31,6 @@ export default function PortAndInterface({ form, int_name, port_name, label, ori
<>: >:
}
-
+
>
}
\ No newline at end of file
diff --git a/frontend/src/components/PortHijack/AddNewService.tsx b/frontend/src/components/PortHijack/AddNewService.tsx
index 08c60a3..b685672 100644
--- a/frontend/src/components/PortHijack/AddNewService.tsx
+++ b/frontend/src/components/PortHijack/AddNewService.tsx
@@ -1,4 +1,4 @@
-import { Button, Group, Space, TextInput, Notification, Modal, Switch, SegmentedControl } from '@mantine/core';
+import { Button, Group, Space, TextInput, Notification, Modal, Switch, SegmentedControl, Box } from '@mantine/core';
import { useForm } from '@mantine/form';
import { useState } from 'react';
import { okNotify, regex_ipv6_no_cidr, regex_ipv4_no_cidr } from '../../js/utils';
@@ -79,12 +79,12 @@ function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void })
-
+
-
+
void })
]}
{...form.getInputProps('proto')}
/>
-
+
-
+
Add Service
diff --git a/frontend/src/components/PortHijack/ServiceRow/ChangeDestination.tsx b/frontend/src/components/PortHijack/ServiceRow/ChangeDestination.tsx
index 4a4fb5d..e4f2bef 100644
--- a/frontend/src/components/PortHijack/ServiceRow/ChangeDestination.tsx
+++ b/frontend/src/components/PortHijack/ServiceRow/ChangeDestination.tsx
@@ -53,7 +53,7 @@ function ChangeDestination({ opened, onClose, service }:{ opened:boolean, onClos