This commit is contained in:
DomySh
2022-07-22 00:34:57 +02:00
parent 1399d0e22d
commit d8dc5c9f8b
38 changed files with 112 additions and 81 deletions

View File

@@ -15,9 +15,9 @@ Dockerfile
/frontend/coverage /frontend/coverage
/backend/db/ /backend/db/
/backend/db/firegex.db /backend/db/**
/backend/db/firegex.db-journal
/backend/modules/cppqueue /backend/modules/cppqueue
/backend/modules/proxy
docker-compose.yml docker-compose.yml
# misc # misc

1
.gitignore vendored
View File

@@ -15,6 +15,7 @@
/backend/db/ /backend/db/
/backend/db/** /backend/db/**
/backend/modules/cppqueue /backend/modules/cppqueue
/backend/modules/proxy
docker-compose.yml docker-compose.yml
# misc # misc

View File

@@ -16,11 +16,11 @@ RUN mkdir build; cd build; cmake ../ -DLIBTINS_ENABLE_CXX11=1; make; make instal
RUN mkdir -p /execute/modules RUN mkdir -p /execute/modules
WORKDIR /execute WORKDIR /execute
COPY ./backend/nfqueue /execute/nfqueue COPY ./backend/binsrc /execute/binsrc
ARG GCC_PARAMS ARG GCC_PARAMS
RUN g++ nfqueue/nfqueue.cpp -o modules/cppqueue -std=c++20 -O3 -march=native -lnetfilter_queue -pthread -lpcre2-8 -ltins -lmnl -lnfnetlink RUN g++ binsrc/nfqueue.cpp -o modules/cppqueue -O3 -march=native -lnetfilter_queue -pthread -lpcre2-8 -ltins -lmnl -lnfnetlink
RUN g++ -O3 -march=native $GCC_PARAMS -o modules/proxy nfqueue/proxy.cpp -pthread -lboost_system -lboost_thread -lpcre2-8 RUN g++ binsrc/proxy.cpp -o modules/proxy -O3 -march=native $GCC_PARAMS -pthread -lboost_system -lboost_thread -lpcre2-8
ADD ./backend/requirements.txt /execute/requirements.txt ADD ./backend/requirements.txt /execute/requirements.txt
RUN pip3 install --no-cache-dir -r /execute/requirements.txt RUN pip3 install --no-cache-dir -r /execute/requirements.txt

View File

@@ -48,12 +48,14 @@ int main(int argc, char *argv[])
cerr << "[fatal] [main] You must be root to run this program" << endl; cerr << "[fatal] [main] You must be root to run this program" << endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
int n_of_queue = 1; int n_of_threads = 1;
if (argc >= 2) n_of_queue = atoi(argv[1]); if (argc >= 2) n_of_threads = atoi(argv[1]);
if(n_of_threads <= 0) n_of_threads = 1;
if (n_of_threads % 2 != 0 ) n_of_threads++;
regex_config.reset(new regex_rules()); regex_config.reset(new regex_rules());
NFQueueSequence<filter_callback<true>> input_queues(n_of_queue); NFQueueSequence<filter_callback<true>> input_queues(n_of_threads/2);
input_queues.start(); input_queues.start();
NFQueueSequence<filter_callback<false>> output_queues(n_of_queue); NFQueueSequence<filter_callback<false>> output_queues(n_of_threads/2);
output_queues.start(); output_queues.start();
cout << "QUEUES INPUT " << input_queues.init() << " " << input_queues.end() << " OUTPUT " << output_queues.init() << " " << output_queues.end() << endl; cout << "QUEUES INPUT " << input_queues.init() << " " << input_queues.end() << " OUTPUT " << output_queues.init() << " " << output_queues.end() << endl;

Binary file not shown.

View File

@@ -3,6 +3,7 @@ from modules.regexproxy.proxy import Filter, Proxy
import random, socket, asyncio import random, socket, asyncio
from base64 import b64decode from base64 import b64decode
from utils.sqlite import SQLite from utils.sqlite import SQLite
from utils import refresh_frontend
class STATUS: class STATUS:
WAIT = "wait" WAIT = "wait"
@@ -129,8 +130,10 @@ class ServiceManager:
while True: while True:
if check_port_is_open(self.proxy.public_port): if check_port_is_open(self.proxy.public_port):
self._set_status(to) self._set_status(to)
await refresh_frontend()
await self.proxy.start(in_pause=(to==STATUS.PAUSE)) await self.proxy.start(in_pause=(to==STATUS.PAUSE))
self._set_status(STATUS.STOP) self._set_status(STATUS.STOP)
await refresh_frontend()
return return
else: else:
await asyncio.sleep(.5) await asyncio.sleep(.5)

Binary file not shown.

View File

@@ -6,16 +6,16 @@ from pydantic import BaseModel
from modules.regexproxy.utils import STATUS, ProxyManager, gen_internal_port, gen_service_id from modules.regexproxy.utils import STATUS, ProxyManager, gen_internal_port, gen_service_id
from utils.sqlite import SQLite from utils.sqlite import SQLite
from utils.models import ResetRequest, StatusMessageModel from utils.models import ResetRequest, StatusMessageModel
from utils.firegextables import FiregexTables from utils import refactor_name, refresh_frontend
app = APIRouter() app = APIRouter()
db = SQLite("regextcpproxy.db",{ db = SQLite("db/regextcpproxy.db",{
'services': { 'services': {
'status': 'VARCHAR(100) NOT NULL', 'status': 'VARCHAR(100) NOT NULL',
'service_id': 'VARCHAR(100) PRIMARY KEY', 'service_id': 'VARCHAR(100) PRIMARY KEY',
'internal_port': 'INT NOT NULL CHECK(internal_port > 0 and internal_port < 65536)', 'internal_port': 'INT NOT NULL CHECK(internal_port > 0 and internal_port < 65536)',
'public_port': 'INT NOT NULL CHECK(internal_port > 0 and internal_port < 65536) UNIQUE', 'public_port': 'INT NOT NULL CHECK(internal_port > 0 and internal_port < 65536) UNIQUE',
'name': 'VARCHAR(100) NOT NULL' 'name': 'VARCHAR(100) NOT NULL UNIQUE'
}, },
'regexes': { 'regexes': {
'regex': 'TEXT NOT NULL', 'regex': 'TEXT NOT NULL',
@@ -31,7 +31,7 @@ db = SQLite("regextcpproxy.db",{
'QUERY':[ 'QUERY':[
"CREATE UNIQUE INDEX IF NOT EXISTS unique_regex_service ON regexes (regex,service_id,is_blacklist,mode,is_case_sensitive);" "CREATE UNIQUE INDEX IF NOT EXISTS unique_regex_service ON regexes (regex,service_id,is_blacklist,mode,is_case_sensitive);"
] ]
}) })
firewall = ProxyManager(db) firewall = ProxyManager(db)
@@ -39,7 +39,6 @@ async def reset(params: ResetRequest):
if not params.delete: if not params.delete:
db.backup() db.backup()
await firewall.close() await firewall.close()
FiregexTables().reset()
if params.delete: if params.delete:
db.delete() db.delete()
db.init() db.init()
@@ -122,18 +121,21 @@ async def get_service_by_id(service_id: str, ):
async def service_stop(service_id: str, ): async def service_stop(service_id: str, ):
"""Request the stop of a specific service""" """Request the stop of a specific service"""
await firewall.get(service_id).next(STATUS.STOP) await firewall.get(service_id).next(STATUS.STOP)
await refresh_frontend()
return {'status': 'ok'} return {'status': 'ok'}
@app.get('/service/{service_id}/pause', response_model=StatusMessageModel) @app.get('/service/{service_id}/pause', response_model=StatusMessageModel)
async def service_pause(service_id: str, ): async def service_pause(service_id: str, ):
"""Request the pause of a specific service""" """Request the pause of a specific service"""
await firewall.get(service_id).next(STATUS.PAUSE) await firewall.get(service_id).next(STATUS.PAUSE)
await refresh_frontend()
return {'status': 'ok'} return {'status': 'ok'}
@app.get('/service/{service_id}/start', response_model=StatusMessageModel) @app.get('/service/{service_id}/start', response_model=StatusMessageModel)
async def service_start(service_id: str, ): async def service_start(service_id: str, ):
"""Request the start of a specific service""" """Request the start of a specific service"""
await firewall.get(service_id).next(STATUS.ACTIVE) await firewall.get(service_id).next(STATUS.ACTIVE)
await refresh_frontend()
return {'status': 'ok'} return {'status': 'ok'}
@app.get('/service/{service_id}/delete', response_model=StatusMessageModel) @app.get('/service/{service_id}/delete', response_model=StatusMessageModel)
@@ -142,6 +144,7 @@ async def service_delete(service_id: str, ):
db.query('DELETE FROM services WHERE service_id = ?;', service_id) db.query('DELETE FROM services WHERE service_id = ?;', service_id)
db.query('DELETE FROM regexes WHERE service_id = ?;', service_id) db.query('DELETE FROM regexes WHERE service_id = ?;', service_id)
await firewall.remove(service_id) await firewall.remove(service_id)
await refresh_frontend()
return {'status': 'ok'} return {'status': 'ok'}
@@ -150,6 +153,7 @@ async def regen_service_port(service_id: str, ):
"""Request the regeneration of a the internal proxy port of a specific service""" """Request the regeneration of a the internal proxy port of a specific service"""
db.query('UPDATE services SET internal_port = ? WHERE service_id = ?;', gen_internal_port(db), service_id) db.query('UPDATE services SET internal_port = ? WHERE service_id = ?;', gen_internal_port(db), service_id)
await firewall.get(service_id).update_port() await firewall.get(service_id).update_port()
await refresh_frontend()
return {'status': 'ok'} return {'status': 'ok'}
class ChangePortForm(BaseModel): class ChangePortForm(BaseModel):
@@ -175,8 +179,9 @@ async def change_service_ports(service_id: str, change_port:ChangePortForm ):
query.append(service_id) query.append(service_id)
db.query(f'UPDATE services SET {sql_inj} WHERE service_id = ?;', *query) db.query(f'UPDATE services SET {sql_inj} WHERE service_id = ?;', *query)
except sqlite3.IntegrityError: except sqlite3.IntegrityError:
return {'status': 'Name or/and port of the service has been already assigned to another service'} return {'status': 'Port of the service has been already assigned to another service'}
await firewall.get(service_id).update_port() await firewall.get(service_id).update_port()
await refresh_frontend()
return {'status': 'ok'} return {'status': 'ok'}
class RegexModel(BaseModel): class RegexModel(BaseModel):
@@ -218,7 +223,7 @@ async def regex_delete(regex_id: int, ):
if len(res) != 0: if len(res) != 0:
db.query('DELETE FROM regexes WHERE regex_id = ?;', regex_id) db.query('DELETE FROM regexes WHERE regex_id = ?;', regex_id)
await firewall.get(res[0]["service_id"]).update_filters() await firewall.get(res[0]["service_id"]).update_filters()
await refresh_frontend()
return {'status': 'ok'} return {'status': 'ok'}
@app.get('/regex/{regex_id}/enable', response_model=StatusMessageModel) @app.get('/regex/{regex_id}/enable', response_model=StatusMessageModel)
@@ -228,6 +233,7 @@ async def regex_enable(regex_id: int, ):
if len(res) != 0: if len(res) != 0:
db.query('UPDATE regexes SET active=1 WHERE regex_id = ?;', regex_id) db.query('UPDATE regexes SET active=1 WHERE regex_id = ?;', regex_id)
await firewall.get(res[0]["service_id"]).update_filters() await firewall.get(res[0]["service_id"]).update_filters()
await refresh_frontend()
return {'status': 'ok'} return {'status': 'ok'}
@app.get('/regex/{regex_id}/disable', response_model=StatusMessageModel) @app.get('/regex/{regex_id}/disable', response_model=StatusMessageModel)
@@ -237,6 +243,7 @@ async def regex_disable(regex_id: int, ):
if len(res) != 0: if len(res) != 0:
db.query('UPDATE regexes SET active=0 WHERE regex_id = ?;', regex_id) db.query('UPDATE regexes SET active=0 WHERE regex_id = ?;', regex_id)
await firewall.get(res[0]["service_id"]).update_filters() await firewall.get(res[0]["service_id"]).update_filters()
await refresh_frontend()
return {'status': 'ok'} return {'status': 'ok'}
class RegexAddForm(BaseModel): class RegexAddForm(BaseModel):
@@ -259,8 +266,8 @@ async def add_new_regex(form: RegexAddForm, ):
form.service_id, form.regex, form.is_blacklist, form.mode, form.is_case_sensitive, True if form.active is None else form.active ) form.service_id, form.regex, form.is_blacklist, form.mode, form.is_case_sensitive, True if form.active is None else form.active )
except sqlite3.IntegrityError: except sqlite3.IntegrityError:
return {'status': 'An identical regex already exists'} return {'status': 'An identical regex already exists'}
await firewall.get(form.service_id).update_filters() await firewall.get(form.service_id).update_filters()
await refresh_frontend()
return {'status': 'ok'} return {'status': 'ok'}
class ServiceAddForm(BaseModel): class ServiceAddForm(BaseModel):
@@ -278,14 +285,20 @@ class RenameForm(BaseModel):
@app.post('/service/{service_id}/rename', response_model=StatusMessageModel) @app.post('/service/{service_id}/rename', response_model=StatusMessageModel)
async def service_rename(service_id: str, form: RenameForm, ): async def service_rename(service_id: str, form: RenameForm, ):
"""Request to change the name of a specific service""" """Request to change the name of a specific service"""
form.name = refactor_name(form.name)
if not form.name: return {'status': 'The name cannot be empty!'} if not form.name: return {'status': 'The name cannot be empty!'}
db.query('UPDATE services SET name=? WHERE service_id = ?;', form.name, service_id) try:
db.query('UPDATE services SET name=? WHERE service_id = ?;', form.name, service_id)
except sqlite3.IntegrityError:
return {'status': 'The name is already used!'}
await refresh_frontend()
return {'status': 'ok'} return {'status': 'ok'}
@app.post('/services/add', response_model=ServiceAddStatus) @app.post('/services/add', response_model=ServiceAddStatus)
async def add_new_service(form: ServiceAddForm, ): async def add_new_service(form: ServiceAddForm, ):
"""Add a new service""" """Add a new service"""
serv_id = gen_service_id(db) serv_id = gen_service_id(db)
form.name = refactor_name(form.name)
try: try:
internal_port = form.internalPort if form.internalPort else gen_internal_port(db) internal_port = form.internalPort if form.internalPort else gen_internal_port(db)
db.query("INSERT INTO services (name, service_id, internal_port, public_port, status) VALUES (?, ?, ?, ?, ?)", db.query("INSERT INTO services (name, service_id, internal_port, public_port, status) VALUES (?, ?, ?, ?, ?)",
@@ -293,5 +306,5 @@ async def add_new_service(form: ServiceAddForm, ):
except sqlite3.IntegrityError: except sqlite3.IntegrityError:
return {'status': 'Name or/and ports of the service has been already assigned to another service'} return {'status': 'Name or/and ports of the service has been already assigned to another service'}
await firewall.reload() await firewall.reload()
await refresh_frontend()
return {'status': 'ok', "id": serv_id } return {'status': 'ok', "id": serv_id }

BIN
docs/Firegex_Screenshot.jpg Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 85 KiB

View File

@@ -1,13 +1,13 @@
{ {
"files": { "files": {
"main.css": "/static/css/main.166875ec.css", "main.css": "/static/css/main.96ef8f18.css",
"main.js": "/static/js/main.414c65b7.js", "main.js": "/static/js/main.8840c3f9.js",
"index.html": "/index.html", "index.html": "/index.html",
"main.166875ec.css.map": "/static/css/main.166875ec.css.map", "main.96ef8f18.css.map": "/static/css/main.96ef8f18.css.map",
"main.414c65b7.js.map": "/static/js/main.414c65b7.js.map" "main.8840c3f9.js.map": "/static/js/main.8840c3f9.js.map"
}, },
"entrypoints": [ "entrypoints": [
"static/css/main.166875ec.css", "static/css/main.96ef8f18.css",
"static/js/main.414c65b7.js" "static/js/main.8840c3f9.js"
] ]
} }

View File

@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="manifest" href="/site.webmanifest"><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#FFFFFFFF"/><meta name="description" content="Firegex by Pwnzer0tt1"/><title>Firegex</title><script defer="defer" src="/static/js/main.414c65b7.js"></script><link href="/static/css/main.166875ec.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html> <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="manifest" href="/site.webmanifest"><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#FFFFFFFF"/><meta name="description" content="Firegex by Pwnzer0tt1"/><title>Firegex</title><script defer="defer" src="/static/js/main.8840c3f9.js"></script><link href="/static/css/main.96ef8f18.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

View File

@@ -1,2 +0,0 @@
@import url(https://fonts.googleapis.com/css2?family=Lato&display=swap);.center-flex,.center-flex-row{align-items:center;display:flex;justify-content:center}.center-flex-row{flex-direction:column}.flex-spacer{flex-grow:1}.Footer_center-flex-row__Iibc4,.Footer_center-flex__mTXcH,.Footer_footer__V8Lu\+{align-items:center;display:flex;justify-content:center}.Footer_center-flex-row__Iibc4{flex-direction:column}.Footer_flex-spacer__6R1Ah{flex-grow:1}.Footer_footer__V8Lu\+{background-color:#242a33;height:150px;margin-top:50px}.Header_header__MY7fH{align-items:center;background-color:#242a33;display:flex;height:140px;justify-content:center;width:100%}.Header_logo__qeTuP{height:70%;margin-left:40px;width:200px}body{font-family:Lato,sans-serif;margin:0}.ServiceRow_center-flex-row__NF59z,.ServiceRow_center-flex__Ffq-d,.ServiceRow_row__HwgWF{align-items:center;display:flex;justify-content:center}.ServiceRow_center-flex-row__NF59z{flex-direction:column}.ServiceRow_flex-spacer__OVA44{flex-grow:1}::-webkit-scrollbar{background:#333;cursor:pointer;margin:3px;width:12px}::-webkit-scrollbar-thumb{background:#757575;border-radius:8px}.ServiceRow_row__HwgWF{border-radius:20px;margin:10px;padding:30px 0;width:95%}.ServiceRow_name__HSrHR{color:#fff;font-size:2.3em;font-weight:bolder;margin-bottom:13px;margin-right:10px}.RegexView_box__Z6\+8g{margin:5px;padding:30px}.RegexView_regex_text__YbrUl{background-color:#25262b;border-radius:8px;margin:6px;padding:6px}
/*# sourceMappingURL=main.166875ec.css.map*/

View File

@@ -1 +0,0 @@
{"version":3,"file":"static/css/main.166875ec.css","mappings":"wEAUA,8BAGE,mBAFA,aACA,sBACA,CAGF,iBAEE,sBAGF,aACE,YAZF,iFAGE,mBAFA,aACA,sBACA,CAGF,+BAEE,sBAGF,2BACE,YCnBF,uBAGI,yBAFA,aACA,eCJY,CCEhB,sBAKI,mBAFA,wBDLY,CCMZ,aAFA,aAIA,uBALA,UAKA,CAGJ,oBAGI,WADA,iBADA,WAEA,CHVJ,KAEE,4BADA,QACA,CAGF,yFAGE,mBAFA,aACA,sBACA,CAGF,mCAEE,sBAGF,+BACE,YAGF,oBAGE,gBACA,eAFA,UAAU,CADV,UAGA,CAEF,0BACE,mBACA,kBI9BF,uBAGI,mBACA,YAFA,eADA,SAGA,CAIJ,wBAKI,WAJA,gBACA,mBAEA,mBADA,iBAEA,CCbJ,uBAEI,UAAS,CADT,YACU,CAGd,6BAEI,wBHPS,CGQT,kBACA,WAHA,WAGA","sources":["index.scss","components/Footer/index.module.scss","_vars.scss","components/Header/index.module.scss","components/NFRegex/ServiceRow/index.module.scss","components/NFRegex/RegexView/index.module.scss"],"sourcesContent":["\n@use \"vars\" as *;\n\n@import url('https://fonts.googleapis.com/css2?family=Lato&display=swap');\n\nbody {\n margin: 0;\n font-family: 'Lato', sans-serif;\n}\n\n.center-flex{\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.center-flex-row{\n @extend .center-flex;\n flex-direction: column;\n}\n\n.flex-spacer{\n flex-grow: 1;\n}\n\n::-webkit-scrollbar {\n width: 12px;\n margin:3px;\n background: #333;\n cursor: pointer;\n}\n::-webkit-scrollbar-thumb {\n background: #757575;\n border-radius: 8px;\n}","@use \"../../vars\" as *;\r\n@use \"../../index.scss\" as *;\r\n\r\n.footer{\r\n height: 150px;\r\n margin-top: 50px;\r\n background-color: $primary_color;\r\n @extend .center-flex;\r\n}","\r\n$primary_color: #242a33;\r\n$second_color: #1A1B1E;\r\n$third_color:#25262b;\r\n","\r\n@use \"../../vars\" as *;\r\n\r\n.header{\r\n width: 100%;\r\n height: 140px;\r\n background-color: $primary_color;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n\r\n.logo{\r\n width: 200px;\r\n margin-left: 40px;\r\n height: 70%;\r\n}","\r\n@use \"../../../index.scss\" as *;\r\n\r\n.row{\r\n width: 95%;\r\n padding: 30px 0px;\r\n border-radius: 20px;\r\n margin: 10px;\r\n @extend .center-flex;\r\n}\r\n\r\n.name{\r\n font-size: 2.3em;\r\n font-weight: bolder;\r\n margin-right: 10px;\r\n margin-bottom: 13px;\r\n color:#FFF;\r\n}","\r\n@use \"../../../vars\" as *;\r\n\r\n.box{\r\n padding:30px;\r\n margin:5px;\r\n}\r\n\r\n.regex_text{\r\n padding: 6px;\r\n background-color: $third_color;\r\n border-radius: 8px;\r\n margin: 6px;\r\n}"],"names":[],"sourceRoot":""}

View File

@@ -0,0 +1,2 @@
@import url(https://fonts.googleapis.com/css2?family=Lato&display=swap);.center-flex,.center-flex-row{align-items:center;display:flex;justify-content:center}.center-flex-row{flex-direction:column}.flex-spacer{flex-grow:1}.Footer_center-flex-row__Iibc4,.Footer_center-flex__mTXcH,.Footer_footer__V8Lu\+{align-items:center;display:flex;justify-content:center}.Footer_center-flex-row__Iibc4{flex-direction:column}.Footer_flex-spacer__6R1Ah{flex-grow:1}.Footer_footer__V8Lu\+{background-color:#242a33;margin-top:50px}.Header_center-flex-row__IvRvv,.Header_center-flex__DB4BQ,.Header_divlogo__5tqvT,.Header_navbtn__0vn69{align-items:center;display:flex;justify-content:center}.Header_center-flex-row__IvRvv{flex-direction:column}.Header_flex-spacer__lqMXa{flex-grow:1}.Header_header__MY7fH{align-items:center;background-color:#242a33;display:flex;justify-content:center;width:100%}.Header_divlogo__5tqvT{cursor:pointer;height:100%;width:110px}.Header_navbtn__0vn69{margin:0;width:30px}.ServiceRow_center-flex-row__NF59z,.ServiceRow_center-flex__Ffq-d,.ServiceRow_row__HwgWF{align-items:center;display:flex;justify-content:center}.ServiceRow_center-flex-row__NF59z{flex-direction:column}.ServiceRow_flex-spacer__OVA44{flex-grow:1}.ServiceRow_row__HwgWF{border-radius:20px;margin:10px;padding:30px 0;width:95%}.ServiceRow_name__HSrHR{color:#fff;font-size:2.3em;font-weight:bolder;margin-bottom:13px;margin-right:10px}body{font-family:Lato,sans-serif;margin:0}.ServiceRow_center-flex-row__KpTZC,.ServiceRow_center-flex__OM87P,.ServiceRow_row__q7RbE{align-items:center;display:flex;justify-content:center}.ServiceRow_center-flex-row__KpTZC{flex-direction:column}.ServiceRow_flex-spacer__5N54i{flex-grow:1}::-webkit-scrollbar{background:#333;cursor:pointer;margin:3px;width:12px}::-webkit-scrollbar-thumb{background:#757575;border-radius:8px}.ServiceRow_row__q7RbE{border-radius:20px;margin:10px;padding:30px 0;width:95%}.ServiceRow_name__Qefq\+{color:#fff;font-size:2.3em;font-weight:bolder;margin-bottom:13px;margin-right:10px}.RegexView_box__IDvxB{margin:5px;padding:30px}.RegexView_regex_text__pFvPS{background-color:#25262b;border-radius:8px;margin:6px;padding:6px}
/*# sourceMappingURL=main.96ef8f18.css.map*/

View File

@@ -0,0 +1 @@
{"version":3,"file":"static/css/main.96ef8f18.css","mappings":"wEAUA,8BAGE,mBAFA,aACA,sBACA,CAGF,iBAEE,sBAGF,aACE,YAZF,iFAGE,mBAFA,aACA,sBACA,CAGF,+BAEE,sBAGF,2BACE,YCnBF,uBAEI,yBADA,eCHY,CFShB,uGAGE,mBAFA,aACA,sBACA,CAGF,+BAEE,sBAGF,2BACE,YGlBF,sBAII,mBAFA,wBDLY,CCMZ,aAEA,uBAJA,UAIA,CAGJ,uBAGI,eADA,YADA,WAEA,CAIJ,sBAGI,QAAO,CADP,UACQ,CHZZ,yFAGE,mBAFA,aACA,sBACA,CAGF,mCAEE,sBAGF,+BACE,YInBF,uBAGI,mBACA,YAFA,eADA,SAGA,CAIJ,wBAKI,WAJA,gBACA,mBAEA,mBADA,iBAEA,CJXJ,KAEE,4BADA,QACA,CAGF,yFAGE,mBAFA,aACA,sBACA,CAGF,mCAEE,sBAGF,+BACE,YAGF,oBAGE,gBACA,eAFA,UAAU,CADV,UAGA,CAEF,0BACE,mBACA,kBK9BF,uBAGI,mBACA,YAFA,eADA,SAGA,CAIJ,yBAKI,WAJA,gBACA,mBAEA,mBADA,iBAEA,CCbJ,sBAEI,UAAS,CADT,YACU,CAGd,6BAEI,wBJPS,CIQT,kBACA,WAHA,WAGA","sources":["index.scss","components/Footer/index.module.scss","_vars.scss","components/Header/index.module.scss","components/NFRegex/ServiceRow/index.module.scss","components/RegexProxy/ServiceRow/ServiceRow.module.scss","components/RegexView/index.module.scss"],"sourcesContent":["\n@use \"vars\" as *;\n\n@import url('https://fonts.googleapis.com/css2?family=Lato&display=swap');\n\nbody {\n margin: 0;\n font-family: 'Lato', sans-serif;\n}\n\n.center-flex{\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n.center-flex-row{\n @extend .center-flex;\n flex-direction: column;\n}\n\n.flex-spacer{\n flex-grow: 1;\n}\n\n::-webkit-scrollbar {\n width: 12px;\n margin:3px;\n background: #333;\n cursor: pointer;\n}\n::-webkit-scrollbar-thumb {\n background: #757575;\n border-radius: 8px;\n}","@use \"../../vars\" as *;\r\n@use \"../../index.scss\" as *;\r\n\r\n.footer{\r\n margin-top: 50px;\r\n background-color: $primary_color;\r\n @extend .center-flex;\r\n}","\r\n$primary_color: #242a33;\r\n$second_color: #1A1B1E;\r\n$third_color:#25262b;\r\n","\r\n@use \"../../vars\" as *;\r\n@use \"../../index.scss\" as *;\r\n\r\n.header{\r\n width: 100%;\r\n background-color: $primary_color;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n\r\n.divlogo{\r\n width: 110px;\r\n height: 100%;\r\n cursor: pointer;\r\n @extend .center-flex;\r\n}\r\n\r\n.navbtn{\r\n @extend .center-flex;\r\n width: 30px;\r\n margin:0;\r\n}","\r\n@use \"../../../index.scss\" as *;\r\n\r\n.row{\r\n width: 95%;\r\n padding: 30px 0px;\r\n border-radius: 20px;\r\n margin: 10px;\r\n @extend .center-flex;\r\n}\r\n\r\n.name{\r\n font-size: 2.3em;\r\n font-weight: bolder;\r\n margin-right: 10px;\r\n margin-bottom: 13px;\r\n color:#FFF;\r\n}","\r\n@use \"../../../index.scss\" as *;\r\n\r\n.row{\r\n width: 95%;\r\n padding: 30px 0px;\r\n border-radius: 20px;\r\n margin: 10px;\r\n @extend .center-flex;\r\n}\r\n\r\n.name{\r\n font-size: 2.3em;\r\n font-weight: bolder;\r\n margin-right: 10px;\r\n margin-bottom: 13px;\r\n color:#FFF;\r\n}","\r\n@use \"../../vars\" as *;\r\n\r\n.box{\r\n padding:30px;\r\n margin:5px;\r\n}\r\n\r\n.regex_text{\r\n padding: 6px;\r\n background-color: $third_color;\r\n border-radius: 8px;\r\n margin: 6px;\r\n}"],"names":[],"sourceRoot":""}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -2,13 +2,15 @@ import { Button, Group, Loader, LoadingOverlay, Notification, Space, PasswordInp
import { useForm } from '@mantine/hooks'; import { useForm } from '@mantine/hooks';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { ImCross } from 'react-icons/im'; import { ImCross } from 'react-icons/im';
import { Navigate, Outlet, Route, Routes } from 'react-router-dom'; import { Outlet, Route, Routes } from 'react-router-dom';
import MainLayout from './components/MainLayout'; import MainLayout from './components/MainLayout';
import { PasswordSend, ServerStatusResponse } from './js/models'; import { PasswordSend, ServerStatusResponse } from './js/models';
import { errorNotify, fireUpdateRequest, getstatus, login, setpassword } from './js/utils'; import { errorNotify, fireUpdateRequest, getstatus, HomeRedirector, login, setpassword } from './js/utils';
import NFRegex from './pages/NFRegex.tsx'; import NFRegex from './pages/NFRegex.tsx';
import ServiceDetails from './pages/NFRegex.tsx/ServiceDetails';
import io from 'socket.io-client'; import io from 'socket.io-client';
import RegexProxy from './pages/RegexProxy';
import ServiceDetailsNFRegex from './pages/NFRegex.tsx/ServiceDetails';
import ServiceDetailsProxyRegex from './pages/RegexProxy/ServiceDetails';
const socket = io({transports: ["websocket", "polling"], path:"/sock" }); const socket = io({transports: ["websocket", "polling"], path:"/sock" });
@@ -146,9 +148,12 @@ function App() {
return <Routes> return <Routes>
<Route element={<MainLayout><Outlet /></MainLayout>}> <Route element={<MainLayout><Outlet /></MainLayout>}>
<Route path="nfregex" element={<NFRegex><Outlet /></NFRegex>} > <Route path="nfregex" element={<NFRegex><Outlet /></NFRegex>} >
<Route path=":srv" element={<ServiceDetails />} /> <Route path=":srv" element={<ServiceDetailsNFRegex />} />
</Route> </Route>
<Route path="*" element={<Navigate to="/nfregex" />} /> <Route path="regexproxy" element={<RegexProxy><Outlet /></RegexProxy>} >
<Route path=":srv" element={<ServiceDetailsProxyRegex />} />
</Route>
<Route path="*" element={<HomeRedirector />} />
</Route> </Route>
</Routes> </Routes>
}else{ }else{

View File

@@ -1,7 +1,7 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { ActionIcon, Divider, Image, Menu, Tooltip, FloatingTooltip, MediaQuery, Burger, Space, Header } from '@mantine/core'; import { ActionIcon, Divider, Image, Menu, Tooltip, FloatingTooltip, MediaQuery, Burger, Space, Header } from '@mantine/core';
import style from "./index.module.scss"; import style from "./index.module.scss";
import { errorNotify, gatmainpath, logout } from '../../js/utils'; import { errorNotify, getmainpath, logout } from '../../js/utils';
import { AiFillHome } from "react-icons/ai" import { AiFillHome } from "react-icons/ai"
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { FaLock } from 'react-icons/fa'; import { FaLock } from 'react-icons/fa';
@@ -24,7 +24,7 @@ function HeaderPage({navOpen, setNav, ...other}: { navOpen: boolean, setNav:Reac
} }
const go_to_home = () => { const go_to_home = () => {
navigator(`/${gatmainpath()}`) navigator(`/${getmainpath()}`)
} }
const [changePasswordModal, setChangePasswordModal] = useState(false); const [changePasswordModal, setChangePasswordModal] = useState(false);

View File

@@ -1,15 +1,24 @@
import React, { useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Container, Space } from '@mantine/core'; import { Container, Space } from '@mantine/core';
import { AppShell } from '@mantine/core'; import { AppShell } from '@mantine/core';
import NavBar from './NavBar'; import NavBar from './NavBar';
import FooterPage from './Footer'; import FooterPage from './Footer';
import HeaderPage from './Header'; import HeaderPage from './Header';
import { getmainpath } from '../js/utils';
import { useLocation } from 'react-router-dom';
function MainLayout({ children }:{ children:any }) { function MainLayout({ children }:{ children:any }) {
const [opened, setOpened] = useState(false); const [opened, setOpened] = useState(false);
const location = useLocation()
useEffect(()=>{
if (location.pathname !== "/"){
sessionStorage.setItem('home_section', getmainpath())
}
},[location.pathname])
return <> return <>
<AppShell <AppShell

View File

@@ -3,7 +3,7 @@ import React from "react";
import { IoMdGitNetwork } from "react-icons/io"; import { IoMdGitNetwork } from "react-icons/io";
import { MdTransform } from "react-icons/md"; import { MdTransform } from "react-icons/md";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { gatmainpath } from "../../js/utils"; import { getmainpath } from "../../js/utils";
import { GrDirections } from "react-icons/gr"; import { GrDirections } from "react-icons/gr";
function NavBarButton({ navigate, closeNav, name, icon, color, disabled }: function NavBarButton({ navigate, closeNav, name, icon, color, disabled }:
@@ -17,7 +17,7 @@ function NavBarButton({ navigate, closeNav, name, icon, color, disabled }:
borderRadius: theme.radius.sm, borderRadius: theme.radius.sm,
opacity: disabled ? 0.4 : 1, opacity: disabled ? 0.4 : 1,
color: theme.colorScheme === 'dark' ? theme.colors.dark[0] : theme.black, color: theme.colorScheme === 'dark' ? theme.colors.dark[0] : theme.black,
backgroundColor:(navigate===gatmainpath()?(theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[0]):"transparent"), backgroundColor:(navigate===getmainpath()?(theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[0]):"transparent"),
'&:hover': { '&:hover': {
backgroundColor: backgroundColor:
theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[0], theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[0],

View File

@@ -1,7 +1,7 @@
import { Button, Group, NumberInput, Space, TextInput, Notification, Modal, Switch } from '@mantine/core'; import { Button, Group, NumberInput, Space, TextInput, Notification, Modal, Switch } from '@mantine/core';
import { useForm } from '@mantine/hooks'; import { useForm } from '@mantine/hooks';
import React, { useState } from 'react'; import React, { useState } from 'react';
import { fireUpdateRequest, okNotify } from '../../js/utils'; import { okNotify } from '../../js/utils';
import { ImCross } from "react-icons/im" import { ImCross } from "react-icons/im"
import { regexproxy } from './utils'; import { regexproxy } from './utils';
@@ -45,7 +45,6 @@ function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void })
if (res.status === "ok"){ if (res.status === "ok"){
setSubmitLoading(false) setSubmitLoading(false)
close(); close();
fireUpdateRequest();
if (autostart) regexproxy.servicestart(res.id) if (autostart) regexproxy.servicestart(res.id)
okNotify(`Service ${name} has been added`, `Successfully added ${res.id} with port ${port}`) okNotify(`Service ${name} has been added`, `Successfully added ${res.id} with port ${port}`)
}else{ }else{

View File

@@ -4,7 +4,7 @@ import React, { useEffect, useState } from 'react';
import { ImCross } from "react-icons/im" import { ImCross } from "react-icons/im"
import { FaLongArrowAltDown } from 'react-icons/fa'; import { FaLongArrowAltDown } from 'react-icons/fa';
import { regexproxy, Service } from '../utils'; import { regexproxy, Service } from '../utils';
import { fireUpdateRequest, okNotify } from '../../../js/utils'; import { okNotify } from '../../../js/utils';
type InputForm = { type InputForm = {
internalPort:number, internalPort:number,
@@ -43,7 +43,6 @@ function ChangePortModal({ service, opened, onClose }:{ service:Service, opened:
if (!res){ if (!res){
setSubmitLoading(false) setSubmitLoading(false)
close(); close();
fireUpdateRequest();
okNotify(`Internal port on ${service.name} service has changed in ${data.internalPort}`, `Successfully changed internal port of service with id ${service.id}`) okNotify(`Internal port on ${service.name} service has changed in ${data.internalPort}`, `Successfully changed internal port of service with id ${service.id}`)
}else{ }else{
setSubmitLoading(false) setSubmitLoading(false)

View File

@@ -1,7 +1,7 @@
import { Button, Group, Space, TextInput, Notification, Modal } from '@mantine/core'; import { Button, Group, Space, TextInput, Notification, Modal } from '@mantine/core';
import { useForm } from '@mantine/hooks'; import { useForm } from '@mantine/hooks';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { fireUpdateRequest, okNotify } from '../../../js/utils'; import { okNotify } from '../../../js/utils';
import { ImCross } from "react-icons/im" import { ImCross } from "react-icons/im"
import { regexproxy, Service } from '../utils'; import { regexproxy, Service } from '../utils';
@@ -29,7 +29,6 @@ function RenameForm({ opened, onClose, service }:{ opened:boolean, onClose:()=>v
if (!res){ if (!res){
setSubmitLoading(false) setSubmitLoading(false)
close(); close();
fireUpdateRequest();
okNotify(`Service ${service.name} has been renamed in ${ name }`, `Successfully renamed service on port ${service.public_port}`) okNotify(`Service ${service.name} has been renamed in ${ name }`, `Successfully renamed service on port ${service.public_port}`)
}else{ }else{
setSubmitLoading(false) setSubmitLoading(false)

View File

@@ -1,5 +1,5 @@
@use "../../index.scss" as *; @use "../../../index.scss" as *;
.row{ .row{
width: 95%; width: 95%;

View File

@@ -4,7 +4,7 @@ import { FaPause, FaPlay, FaStop } from 'react-icons/fa';
import { MdOutlineArrowForwardIos } from "react-icons/md" import { MdOutlineArrowForwardIos } from "react-icons/md"
import style from "./ServiceRow.module.scss"; import style from "./ServiceRow.module.scss";
import YesNoModal from '../../YesNoModal'; import YesNoModal from '../../YesNoModal';
import { errorNotify, fireUpdateRequest, okNotify } from '../../../js/utils'; import { errorNotify, okNotify } from '../../../js/utils';
import { BsArrowRepeat, BsTrashFill } from 'react-icons/bs'; import { BsArrowRepeat, BsTrashFill } from 'react-icons/bs';
import { TbNumbers } from 'react-icons/tb'; import { TbNumbers } from 'react-icons/tb';
import { BiRename } from 'react-icons/bi' import { BiRename } from 'react-icons/bi'
@@ -36,7 +36,6 @@ function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void })
await regexproxy.servicestop(service.id).then(res => { await regexproxy.servicestop(service.id).then(res => {
if(!res){ if(!res){
okNotify(`Service ${service.id} stopped successfully!`,`The service ${service.name} has been stopped!`) okNotify(`Service ${service.id} stopped successfully!`,`The service ${service.name} has been stopped!`)
fireUpdateRequest();
}else{ }else{
errorNotify(`An error as occurred during the stopping of the service ${service.id}`,`Error: ${res}`) errorNotify(`An error as occurred during the stopping of the service ${service.id}`,`Error: ${res}`)
} }
@@ -51,7 +50,6 @@ function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void })
await regexproxy.servicestart(service.id).then(res => { await regexproxy.servicestart(service.id).then(res => {
if(!res){ if(!res){
okNotify(`Service ${service.id} started successfully!`,`The service ${service.name} has been started!`) okNotify(`Service ${service.id} started successfully!`,`The service ${service.name} has been started!`)
fireUpdateRequest();
}else{ }else{
errorNotify(`An error as occurred during the starting of the service ${service.id}`,`Error: ${res}`) errorNotify(`An error as occurred during the starting of the service ${service.id}`,`Error: ${res}`)
} }
@@ -66,7 +64,6 @@ function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void })
await regexproxy.servicepause(service.id).then(res => { await regexproxy.servicepause(service.id).then(res => {
if(!res){ if(!res){
okNotify(`Service ${service.id} paused successfully!`,`The service ${service.name} has been paused (Transparent mode)!`) okNotify(`Service ${service.id} paused successfully!`,`The service ${service.name} has been paused (Transparent mode)!`)
fireUpdateRequest();
}else{ }else{
errorNotify(`An error as occurred during the pausing of the service ${service.id}`,`Error: ${res}`) errorNotify(`An error as occurred during the pausing of the service ${service.id}`,`Error: ${res}`)
} }
@@ -81,7 +78,6 @@ function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void })
regexproxy.servicedelete(service.id).then(res => { regexproxy.servicedelete(service.id).then(res => {
if (!res){ if (!res){
okNotify("Service delete complete!",`The service ${service.id} has been deleted!`) okNotify("Service delete complete!",`The service ${service.id} has been deleted!`)
fireUpdateRequest();
}else }else
errorNotify("An error occurred while deleting a service",`Error: ${res}`) errorNotify("An error occurred while deleting a service",`Error: ${res}`)
}).catch(err => { }).catch(err => {
@@ -94,7 +90,6 @@ function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void })
regexproxy.serviceregenport(service.id).then(res => { regexproxy.serviceregenport(service.id).then(res => {
if (!res){ if (!res){
okNotify("Service port regeneration completed!",`The service ${service.id} has changed the internal port!`) okNotify("Service port regeneration completed!",`The service ${service.id} has changed the internal port!`)
fireUpdateRequest();
}else }else
errorNotify("An error occurred while changing the internal service port",`Error: ${res}`) errorNotify("An error occurred while changing the internal service port",`Error: ${res}`)
}).catch(err => { }).catch(err => {
@@ -108,14 +103,14 @@ function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void })
<MediaQuery smallerThan="md" styles={{ display: 'none' }}><div> <MediaQuery smallerThan="md" styles={{ display: 'none' }}><div>
<div className="center-flex-row"> <div className="center-flex-row">
<div className="center-flex"><Title className={style.name}>{service.name}</Title> <Badge size="xl" gradient={{ from: 'indigo', to: 'cyan' }} variant="gradient">:{service.public_port}</Badge></div> <div className="center-flex"><Title className={style.name}>{service.name}</Title> <Badge size="xl" gradient={{ from: 'indigo', to: 'cyan' }} variant="gradient">:{service.public_port}</Badge></div>
<Badge color={status_color} size="xl" radius="md">{service.internal_port} {"->"} {service.public_port}</Badge> <Badge color={status_color} size="lg" radius="md">{service.internal_port} {"->"} {service.public_port}</Badge>
</div> </div>
</div></MediaQuery> </div></MediaQuery>
<MediaQuery largerThan="md" styles={{ display: 'none' }}><div> <MediaQuery largerThan="md" styles={{ display: 'none' }}><div>
<div className="center-flex"> <div className="center-flex">
<div className="center-flex"><Title className={style.name}>{service.name}</Title> <Badge size="xl" gradient={{ from: 'indigo', to: 'cyan' }} variant="gradient">:{service.public_port}</Badge></div> <div className="center-flex"><Title className={style.name}>{service.name}</Title> <Badge size="xl" gradient={{ from: 'indigo', to: 'cyan' }} variant="gradient">:{service.public_port}</Badge></div>
<Space w="xl" /> <Space w="xl" />
<Badge color={status_color} size="xl" radius="md">{service.internal_port} {"->"} {service.public_port}</Badge> <Badge color={status_color} size="lg" radius="md">{service.internal_port} {"->"} {service.public_port}</Badge>
</div> </div>
</div></MediaQuery> </div></MediaQuery>
@@ -133,9 +128,9 @@ function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void })
</MediaQuery> </MediaQuery>
<div className="center-flex-row"> <div className="center-flex-row">
<Badge style={{marginBottom:"20px"}} color={status_color} radius="sm" size="xl" variant="filled">Status: <u>{service.status}</u></Badge> <Badge style={{marginBottom:"20px"}} color={status_color} radius="sm" size="lg" variant="filled">Status: <u>{service.status}</u></Badge>
<Badge style={{marginBottom:"8px"}}color="violet" radius="sm" size="lg" variant="filled">Regex: {service.n_regex}</Badge> <Badge style={{marginBottom:"8px"}}color="violet" radius="sm" size="md" variant="filled">Regex: {service.n_regex}</Badge>
<Badge color="yellow" radius="sm" size="lg" variant="filled">Connections Blocked: {service.n_packets}</Badge> <Badge color="yellow" radius="sm" size="md" variant="filled">Connections Blocked: {service.n_packets}</Badge>
</div> </div>
<MediaQuery largerThan="md" styles={{ display: 'none' }}> <MediaQuery largerThan="md" styles={{ display: 'none' }}>
<div className='flex-spacer' /> <div className='flex-spacer' />
@@ -170,8 +165,7 @@ function ServiceRow({ service, onClick }:{ service:Service, onClick?:()=>void })
</Tooltip>: </Tooltip>:
<Tooltip label={service.status === "stop"?"Start in pause mode":"Pause service"} zIndex={0} transition="pop" transitionDuration={200} /*openDelay={500}*/ transitionTimingFunction="ease" color={service.status === "stop"?"cyan":"red"}> <Tooltip label={service.status === "stop"?"Start in pause mode":"Pause service"} zIndex={0} transition="pop" transitionDuration={200} /*openDelay={500}*/ transitionTimingFunction="ease" color={service.status === "stop"?"cyan":"red"}>
<ActionIcon color={service.status === "stop"?"cyan":"red"} loading={buttonLoading} <ActionIcon color={service.status === "stop"?"cyan":"red"} loading={buttonLoading}
onClick={pauseService} size="xl" radius="md" variant="filled" onClick={pauseService} size="xl" radius="md" variant="filled">
/*disabled={service.status === "stop"}*/>
<FaPause size="20px" /> <FaPause size="20px" />
</ActionIcon> </ActionIcon>
</Tooltip> </Tooltip>

View File

@@ -1,6 +1,7 @@
import { showNotification } from "@mantine/notifications"; import { showNotification } from "@mantine/notifications";
import { ImCross } from "react-icons/im"; import { ImCross } from "react-icons/im";
import { TiTick } from "react-icons/ti" import { TiTick } from "react-icons/ti"
import { Navigate } from "react-router-dom";
import { nfregex } from "../components/NFRegex/utils"; import { nfregex } from "../components/NFRegex/utils";
import { regexproxy } from "../components/RegexProxy/utils"; import { regexproxy } from "../components/RegexProxy/utils";
import { ChangePassword, IpInterface, LoginResponse, PasswordSend, ServerResponse, ServerResponseToken, ServerStatusResponse } from "./models"; import { ChangePassword, IpInterface, LoginResponse, PasswordSend, ServerResponse, ServerResponseToken, ServerStatusResponse } from "./models";
@@ -52,20 +53,26 @@ export async function postapi(path:string,data:any,is_form:boolean=false):Promis
}); });
} }
export function gatmainpath(){ export function getmainpath(){
const paths = window.location.pathname.split("/") const paths = window.location.pathname.split("/")
if (paths.length > 1) return paths[1] if (paths.length > 1) return paths[1]
return "" return ""
} }
export function getapiobject(){ export function getapiobject(){
switch(gatmainpath()){ switch(getmainpath()){
case "nfregex": case "nfregex":
return nfregex return nfregex
case "regexproxy": case "regexproxy":
return regexproxy return regexproxy
} }
throw 'No api for this tool!'; throw new Error('No api for this tool!');
}
export function HomeRedirector(){
const section = sessionStorage.getItem("home_section")
const path = section?`/${section}`:`/nfqueue`
return <Navigate to={path} />
} }
export function fireUpdateRequest(){ export function fireUpdateRequest(){

View File

@@ -10,7 +10,7 @@ import { errorNotify, eventUpdateName, fireUpdateRequest } from '../../js/utils'
import { useWindowEvent } from '@mantine/hooks'; import { useWindowEvent } from '@mantine/hooks';
import { RegexFilter } from '../../js/models'; import { RegexFilter } from '../../js/models';
function ServiceDetails() { function ServiceDetailsNFRegex() {
const {srv} = useParams() const {srv} = useParams()
const [serviceInfo, setServiceInfo] = useState<Service>({ const [serviceInfo, setServiceInfo] = useState<Service>({
service_id: "", service_id: "",
@@ -81,4 +81,4 @@ function ServiceDetails() {
</> </>
} }
export default ServiceDetails; export default ServiceDetailsNFRegex;

View File

@@ -10,15 +10,15 @@ import ServiceRow from '../../components/RegexProxy/ServiceRow';
import AddNewRegex from '../../components/AddNewRegex'; import AddNewRegex from '../../components/AddNewRegex';
import RegexView from '../../components/RegexView'; import RegexView from '../../components/RegexView';
function ServiceDetails() { function ServiceDetailsProxyRegex() {
const {srv_id} = useParams() const {srv} = useParams()
const [serviceInfo, setServiceInfo] = useState<Service>({ const [serviceInfo, setServiceInfo] = useState<Service>({
id:srv_id?srv_id:"", id:srv?srv:"",
internal_port:0, internal_port:0,
n_packets:0, n_packets:0,
n_regex:0, n_regex:0,
name:srv_id?srv_id:"", name:srv?srv:"",
public_port:0, public_port:0,
status:"🤔" status:"🤔"
}) })
@@ -29,9 +29,9 @@ function ServiceDetails() {
const closeModal = () => {setOpen(false);updateInfo();} const closeModal = () => {setOpen(false);updateInfo();}
const updateInfo = async () => { const updateInfo = async () => {
if (!srv_id) return if (!srv) return
let error = false; let error = false;
await regexproxy.serviceinfo(srv_id).then(res => { await regexproxy.serviceinfo(srv).then(res => {
setServiceInfo(res) setServiceInfo(res)
}).catch( }).catch(
err =>{ err =>{
@@ -39,10 +39,10 @@ function ServiceDetails() {
navigator("/") navigator("/")
}) })
if (error) return if (error) return
await regexproxy.serviceregexes(srv_id).then(res => { await regexproxy.serviceregexes(srv).then(res => {
setRegexesList(res) setRegexesList(res)
}).catch( }).catch(
err => errorNotify(`Updater for ${srv_id} service failed [Regex list]!`, err.toString()) err => errorNotify(`Updater for ${srv} service failed [Regex list]!`, err.toString())
) )
setLoader(false) setLoader(false)
} }
@@ -76,10 +76,10 @@ function ServiceDetails() {
</Grid> </Grid>
} }
{srv_id?<AddNewRegex opened={open} onClose={closeModal} service={srv_id} />:null} {srv?<AddNewRegex opened={open} onClose={closeModal} service={srv} />:null}
</div> </div>
} }
export default ServiceDetails; export default ServiceDetailsProxyRegex;

View File

@@ -47,7 +47,7 @@ function RegexProxy({ children }: { children: any }) {
return <> return <>
<Space h="sm" /> <Space h="sm" />
<div className='center-flex'> <div className='center-flex'>
<Title order={4}>Netfilter Regex</Title> <Title order={4}>TCP Proxy Regex Filter (IPv4 Only)</Title>
<div className='flex-spacer' /> <div className='flex-spacer' />
<Badge size="sm" color="green" variant="filled">Services: {generalStats.services}</Badge> <Badge size="sm" color="green" variant="filled">Services: {generalStats.services}</Badge>
<Space w="xs" /> <Space w="xs" />

View File

@@ -54,7 +54,7 @@ services:
network_mode: "host" network_mode: "host"
environment: environment:
- PORT={args.port} - PORT={args.port}
- NTHREADS={args.thread_per_queue} - NTHREADS={args.threads}
volumes: volumes:
- /execute/db - /execute/db
cap_add: cap_add:
@@ -79,7 +79,7 @@ services:
- {args.port}:{args.port} - {args.port}:{args.port}
environment: environment:
- PORT={args.port} - PORT={args.port}
- NTHREADS={args.thread_per_queue} - NTHREADS={args.threads}
volumes: volumes:
- /execute/db - /execute/db
cap_add: cap_add: