Autosuggestion for network interfaces ips
This commit is contained in:
@@ -11,7 +11,7 @@ from passlib.context import CryptContext
|
|||||||
from fastapi_socketio import SocketManager
|
from fastapi_socketio import SocketManager
|
||||||
from modules import SQLite, FirewallManager
|
from modules import SQLite, FirewallManager
|
||||||
from modules.firewall import STATUS
|
from modules.firewall import STATUS
|
||||||
from utils import ip_parse, refactor_name, gen_service_id
|
from utils import get_interfaces, ip_parse, refactor_name, gen_service_id
|
||||||
|
|
||||||
ON_DOCKER = len(sys.argv) > 1 and sys.argv[1] == "DOCKER"
|
ON_DOCKER = len(sys.argv) > 1 and sys.argv[1] == "DOCKER"
|
||||||
DEBUG = len(sys.argv) > 1 and sys.argv[1] == "DEBUG"
|
DEBUG = len(sys.argv) > 1 and sys.argv[1] == "DEBUG"
|
||||||
@@ -365,6 +365,15 @@ async def add_new_service(form: ServiceAddForm, auth: bool = Depends(is_loggined
|
|||||||
await refresh_frontend()
|
await refresh_frontend()
|
||||||
return {'status': 'ok', 'service_id': srv_id}
|
return {'status': 'ok', 'service_id': srv_id}
|
||||||
|
|
||||||
|
class IpInterface(BaseModel):
|
||||||
|
addr: str
|
||||||
|
name: str
|
||||||
|
|
||||||
|
@app.get('/api/interfaces', response_model=List[IpInterface])
|
||||||
|
async def get_ip_interfaces(auth: bool = Depends(is_loggined)):
|
||||||
|
"""Get a list of ip and ip6 interfaces"""
|
||||||
|
return get_interfaces()
|
||||||
|
|
||||||
async def frontend_debug_proxy(path):
|
async def frontend_debug_proxy(path):
|
||||||
httpc = httpx.AsyncClient()
|
httpc = httpx.AsyncClient()
|
||||||
req = httpc.build_request("GET",f"http://127.0.0.1:{os.getenv('F_PORT','3000')}/"+path)
|
req = httpc.build_request("GET",f"http://127.0.0.1:{os.getenv('F_PORT','3000')}/"+path)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ fastapi[all]
|
|||||||
httpx
|
httpx
|
||||||
uvicorn[standard]
|
uvicorn[standard]
|
||||||
passlib[bcrypt]
|
passlib[bcrypt]
|
||||||
|
psutil
|
||||||
python-jose[cryptography]
|
python-jose[cryptography]
|
||||||
fastapi-socketio
|
fastapi-socketio
|
||||||
git+https://salsa.debian.org/pkg-netfilter-team/pkg-nftables#egg=nftables&subdirectory=py
|
git+https://salsa.debian.org/pkg-netfilter-team/pkg-nftables#egg=nftables&subdirectory=py
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from ipaddress import ip_interface
|
from ipaddress import ip_interface
|
||||||
import os, socket, secrets
|
import os, socket, secrets, psutil
|
||||||
|
|
||||||
LOCALHOST_IP = socket.gethostbyname(os.getenv("LOCALHOST_IP","127.0.0.1"))
|
LOCALHOST_IP = socket.gethostbyname(os.getenv("LOCALHOST_IP","127.0.0.1"))
|
||||||
|
|
||||||
@@ -19,4 +19,12 @@ def ip_parse(ip:str):
|
|||||||
return str(ip_interface(ip).network)
|
return str(ip_interface(ip).network)
|
||||||
|
|
||||||
def ip_family(ip:str):
|
def ip_family(ip:str):
|
||||||
return "ip6" if ip_interface(ip).version == 6 else "ip"
|
return "ip6" if ip_interface(ip).version == 6 else "ip"
|
||||||
|
|
||||||
|
def get_interfaces():
|
||||||
|
def _get_interfaces():
|
||||||
|
for int_name, interfs in psutil.net_if_addrs().items():
|
||||||
|
for interf in interfs:
|
||||||
|
if interf.family in [socket.AF_INET, socket.AF_INET6]:
|
||||||
|
yield {"name": int_name, "addr":interf.address}
|
||||||
|
return list(_get_interfaces())
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"files": {
|
"files": {
|
||||||
"main.css": "/static/css/main.08225a85.css",
|
"main.css": "/static/css/main.08225a85.css",
|
||||||
"main.js": "/static/js/main.6bded0d7.js",
|
"main.js": "/static/js/main.10378d73.js",
|
||||||
"index.html": "/index.html",
|
"index.html": "/index.html",
|
||||||
"main.08225a85.css.map": "/static/css/main.08225a85.css.map",
|
"main.08225a85.css.map": "/static/css/main.08225a85.css.map",
|
||||||
"main.6bded0d7.js.map": "/static/js/main.6bded0d7.js.map"
|
"main.10378d73.js.map": "/static/js/main.10378d73.js.map"
|
||||||
},
|
},
|
||||||
"entrypoints": [
|
"entrypoints": [
|
||||||
"static/css/main.08225a85.css",
|
"static/css/main.08225a85.css",
|
||||||
"static/js/main.6bded0d7.js"
|
"static/js/main.10378d73.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -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.6bded0d7.js"></script><link href="/static/css/main.08225a85.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.10378d73.js"></script><link href="/static/css/main.08225a85.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||||
3
frontend/build/static/js/main.10378d73.js
Normal file
3
frontend/build/static/js/main.10378d73.js
Normal file
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
@@ -1,7 +1,7 @@
|
|||||||
import { Button, Group, NumberInput, Space, TextInput, Notification, Modal, Switch, SegmentedControl } from '@mantine/core';
|
import { Button, Group, NumberInput, Space, TextInput, Notification, Modal, Switch, SegmentedControl, SelectItemProps, Autocomplete, AutocompleteItem } from '@mantine/core';
|
||||||
import { useForm } from '@mantine/hooks';
|
import { useForm } from '@mantine/hooks';
|
||||||
import React, { useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { addservice, okNotify, startservice, regex_ipv4, regex_ipv6 } from '../js/utils';
|
import { addservice, okNotify, startservice, regex_ipv4, regex_ipv6, getipinterfaces } from '../js/utils';
|
||||||
import { ImCross } from "react-icons/im"
|
import { ImCross } from "react-icons/im"
|
||||||
|
|
||||||
type ServiceAddForm = {
|
type ServiceAddForm = {
|
||||||
@@ -12,13 +12,23 @@ type ServiceAddForm = {
|
|||||||
autostart: boolean,
|
autostart: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ItemProps extends AutocompleteItem {
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AutoCompleteItem = React.forwardRef<HTMLDivElement, ItemProps>(
|
||||||
|
({ label, value, ...props }: ItemProps, ref) => <div ref={ref} {...props}>
|
||||||
|
( <b>{label}</b> ) -{">"} <b>{value}</b>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void }) {
|
function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void }) {
|
||||||
|
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
initialValues: {
|
initialValues: {
|
||||||
name:"",
|
name:"",
|
||||||
port:8080,
|
port:8080,
|
||||||
ip_int:"127.0.0.1",
|
ip_int:"",
|
||||||
proto:"tcp",
|
proto:"tcp",
|
||||||
autostart: true
|
autostart: true
|
||||||
},
|
},
|
||||||
@@ -30,6 +40,14 @@ function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void })
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const [ipInterfaces, setIpInterfaces] = useState<AutocompleteItem[]>([]);
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
getipinterfaces().then(data => {
|
||||||
|
setIpInterfaces(data.map(item => ({label:item.name, value:item.addr})));
|
||||||
|
})
|
||||||
|
},[])
|
||||||
|
|
||||||
const close = () =>{
|
const close = () =>{
|
||||||
onClose()
|
onClose()
|
||||||
form.reset()
|
form.reset()
|
||||||
@@ -55,7 +73,8 @@ function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void })
|
|||||||
setSubmitLoading(false)
|
setSubmitLoading(false)
|
||||||
setError("Request Failed! [ "+err+" ]")
|
setError("Request Failed! [ "+err+" ]")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return <Modal size="xl" title="Add a new service" opened={opened} onClose={close} closeOnClickOutside={false} centered>
|
return <Modal size="xl" title="Add a new service" opened={opened} onClose={close} closeOnClickOutside={false} centered>
|
||||||
<form onSubmit={form.onSubmit(submitRequest)}>
|
<form onSubmit={form.onSubmit(submitRequest)}>
|
||||||
@@ -66,9 +85,11 @@ function AddNewService({ opened, onClose }:{ opened:boolean, onClose:()=>void })
|
|||||||
/>
|
/>
|
||||||
<Space h="md" />
|
<Space h="md" />
|
||||||
|
|
||||||
<TextInput
|
<Autocomplete
|
||||||
label="Public IP Interface (ipv4/ipv6 + CIDR allowed)"
|
label="Public IP Interface (ipv4/ipv6 + CIDR allowed)"
|
||||||
placeholder="10.1.1.0/24"
|
placeholder="10.1.1.0/24"
|
||||||
|
itemComponent={AutoCompleteItem}
|
||||||
|
data={ipInterfaces}
|
||||||
{...form.getInputProps('ip_int')}
|
{...form.getInputProps('ip_int')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -74,4 +74,9 @@ export type RegexAddForm = {
|
|||||||
is_blacklist:boolean,
|
is_blacklist:boolean,
|
||||||
mode:string, // C->S S->C BOTH,
|
mode:string, // C->S S->C BOTH,
|
||||||
active: boolean
|
active: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IpInterface = {
|
||||||
|
name:string,
|
||||||
|
addr:string
|
||||||
}
|
}
|
||||||
@@ -1,7 +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 { GeneralStats, Service, ServiceAddForm, ServerResponse, RegexFilter, RegexAddForm, ServerStatusResponse, PasswordSend, ChangePassword, LoginResponse, ServerResponseToken, ServiceAddResponse } from "./models";
|
import { GeneralStats, Service, ServiceAddForm, ServerResponse, RegexFilter, RegexAddForm, ServerStatusResponse, PasswordSend, ChangePassword, LoginResponse, ServerResponseToken, ServiceAddResponse, IpInterface } from "./models";
|
||||||
|
|
||||||
var Buffer = require('buffer').Buffer
|
var Buffer = require('buffer').Buffer
|
||||||
|
|
||||||
@@ -54,6 +54,10 @@ export function fireUpdateRequest(){
|
|||||||
window.dispatchEvent(new Event(eventUpdateName))
|
window.dispatchEvent(new Event(eventUpdateName))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getipinterfaces(){
|
||||||
|
return await getapi("interfaces") as IpInterface[];
|
||||||
|
}
|
||||||
|
|
||||||
export async function getstatus(){
|
export async function getstatus(){
|
||||||
return await getapi(`status`) as ServerStatusResponse;
|
return await getapi(`status`) as ServerStatusResponse;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user