2024-10-13 01:50:52 +02:00
|
|
|
import { Button, Group, Loader, LoadingOverlay, Notification, Space, PasswordInput, Title, Box } from '@mantine/core';
|
2023-06-05 00:55:38 +02:00
|
|
|
import { useForm } from '@mantine/form';
|
2023-09-24 05:48:54 +02:00
|
|
|
import { useEffect, useState } from 'react';
|
2022-06-13 16:12:52 +02:00
|
|
|
import { ImCross } from 'react-icons/im';
|
2022-07-22 00:34:57 +02:00
|
|
|
import { Outlet, Route, Routes } from 'react-router-dom';
|
2022-06-11 21:57:50 +02:00
|
|
|
import MainLayout from './components/MainLayout';
|
2022-06-15 19:44:41 +02:00
|
|
|
import { PasswordSend, ServerStatusResponse } from './js/models';
|
2023-09-26 01:17:09 +02:00
|
|
|
import { DEV_IP_BACKEND, errorNotify, getstatus, HomeRedirector, IS_DEV, login, setpassword } from './js/utils';
|
2022-08-12 11:55:07 +00:00
|
|
|
import NFRegex from './pages/NFRegex';
|
2022-07-08 15:13:46 +02:00
|
|
|
import io from 'socket.io-client';
|
2022-08-12 11:55:07 +00:00
|
|
|
import ServiceDetailsNFRegex from './pages/NFRegex/ServiceDetails';
|
|
|
|
|
import PortHijack from './pages/PortHijack';
|
2023-09-23 02:02:02 +02:00
|
|
|
import { Firewall } from './pages/Firewall';
|
2023-09-26 01:17:09 +02:00
|
|
|
import { useQueryClient } from '@tanstack/react-query';
|
2025-02-20 19:51:28 +01:00
|
|
|
import NFProxy from './pages/NFProxy';
|
|
|
|
|
import ServiceDetailsNFProxy from './pages/NFProxy/ServiceDetails';
|
2022-07-08 15:13:46 +02:00
|
|
|
|
2025-02-25 23:53:04 +01:00
|
|
|
export const socket = import.meta.env.DEV?
|
|
|
|
|
io("ws://"+DEV_IP_BACKEND, {
|
|
|
|
|
path:"/sock/socket.io",
|
|
|
|
|
transports: ['websocket'],
|
|
|
|
|
auth: {
|
|
|
|
|
token: localStorage.getItem("access_token")
|
|
|
|
|
}
|
|
|
|
|
}):
|
|
|
|
|
io({
|
|
|
|
|
path:"/sock/socket.io",
|
|
|
|
|
transports: ['websocket'],
|
|
|
|
|
auth: {
|
|
|
|
|
token: localStorage.getItem("access_token")
|
|
|
|
|
}
|
|
|
|
|
})
|
2022-06-11 21:57:50 +02:00
|
|
|
|
|
|
|
|
function App() {
|
2022-06-13 16:12:52 +02:00
|
|
|
|
|
|
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
|
const [systemStatus, setSystemStatus] = useState<ServerStatusResponse>({status:"", loggined:false})
|
|
|
|
|
const [reqError, setReqError] = useState<undefined|string>()
|
|
|
|
|
const [error, setError] = useState<string|null>()
|
|
|
|
|
const [loadinBtn, setLoadingBtn] = useState(false);
|
2025-02-25 23:53:04 +01:00
|
|
|
|
2022-06-13 16:12:52 +02:00
|
|
|
|
|
|
|
|
const getStatus = () =>{
|
2025-02-25 23:53:04 +01:00
|
|
|
getstatus().then( res =>{
|
|
|
|
|
setSystemStatus(res)
|
|
|
|
|
setReqError(undefined)
|
|
|
|
|
}).catch(err=>{
|
|
|
|
|
setReqError(err.toString())
|
|
|
|
|
setTimeout(getStatus, 500)
|
|
|
|
|
}).finally( ()=>setLoading(false) )
|
2022-06-13 16:12:52 +02:00
|
|
|
}
|
|
|
|
|
|
2022-06-15 19:44:41 +02:00
|
|
|
useEffect(()=>{
|
2022-07-08 15:13:46 +02:00
|
|
|
getStatus()
|
2022-06-15 19:44:41 +02:00
|
|
|
},[])
|
|
|
|
|
|
2022-06-13 16:12:52 +02:00
|
|
|
const form = useForm({
|
|
|
|
|
initialValues: {
|
|
|
|
|
password:"",
|
|
|
|
|
},
|
2023-06-05 00:55:38 +02:00
|
|
|
validate:{
|
2023-06-14 21:49:15 +02:00
|
|
|
password: (value) => value !== "" ? null : "Password is required",
|
2022-06-13 16:12:52 +02:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if (loading){
|
|
|
|
|
return <LoadingOverlay visible/>
|
|
|
|
|
}else if (reqError){
|
2024-10-13 01:50:52 +02:00
|
|
|
return <Box className='center-flex-row' style={{padding:"100px"}}>
|
|
|
|
|
<Title order={1} style={{textAlign:"center"}}>Error launching Firegex! 🔥</Title>
|
2022-06-13 16:12:52 +02:00
|
|
|
<Space h="md" />
|
2024-10-13 01:50:52 +02:00
|
|
|
<Title order={4} style={{textAlign:"center"}}>Error communicating with backend</Title>
|
2022-06-13 16:12:52 +02:00
|
|
|
<Space h="md" />
|
2023-09-25 20:43:29 +02:00
|
|
|
Error: {reqError}
|
2022-06-13 16:12:52 +02:00
|
|
|
<Space h="xl" />
|
|
|
|
|
<Loader />
|
2024-10-13 01:50:52 +02:00
|
|
|
</Box>
|
2022-06-13 16:12:52 +02:00
|
|
|
}else if (systemStatus.status === "init"){
|
|
|
|
|
|
|
|
|
|
const submitRequest = async (values:PasswordSend) => {
|
|
|
|
|
setLoadingBtn(true)
|
|
|
|
|
await setpassword(values).then(res => {
|
|
|
|
|
if(!res){
|
|
|
|
|
setSystemStatus({loggined:true, status:"run"})
|
|
|
|
|
}else{
|
|
|
|
|
setError(res)
|
|
|
|
|
}
|
|
|
|
|
}).catch( err => setError(err.toString()))
|
|
|
|
|
setLoadingBtn(false)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2024-10-13 01:50:52 +02:00
|
|
|
return <Box className='center-flex-row' style={{padding:"100px"}}>
|
|
|
|
|
<Title order={3} style={{textAlign:"center"}}>Setup: Choose the password for access to the firewall 🔒</Title>
|
2022-06-13 16:12:52 +02:00
|
|
|
<Space h="xl" />
|
|
|
|
|
<form onSubmit={form.onSubmit(submitRequest)} style={{width:"80%"}}>
|
2022-06-19 20:11:28 +02:00
|
|
|
<PasswordInput
|
2022-06-13 16:12:52 +02:00
|
|
|
label="Password"
|
|
|
|
|
placeholder="$3cr3t"
|
|
|
|
|
{...form.getInputProps('password')}
|
|
|
|
|
/>
|
2024-10-13 01:50:52 +02:00
|
|
|
<Group align="right" mt="md">
|
2022-06-13 16:12:52 +02:00
|
|
|
<Button loading={loadinBtn} type="submit">Set Password</Button>
|
|
|
|
|
</Group>
|
|
|
|
|
</form>
|
|
|
|
|
<Space h="xl" />
|
|
|
|
|
{error?<>
|
|
|
|
|
<Notification icon={<ImCross size={14} />} color="red" onClose={()=>{setError(null)}}>
|
|
|
|
|
Error: {error}
|
|
|
|
|
</Notification><Space h="md" /></>:null}
|
2024-10-13 01:50:52 +02:00
|
|
|
</Box>
|
2022-06-13 16:12:52 +02:00
|
|
|
}else if (systemStatus.status === "run" && !systemStatus.loggined){
|
|
|
|
|
const submitRequest = async (values:PasswordSend) => {
|
|
|
|
|
setLoadingBtn(true)
|
|
|
|
|
await login(values).then(res => {
|
|
|
|
|
if(!res){
|
|
|
|
|
setSystemStatus({...systemStatus, loggined:true})
|
|
|
|
|
}else{
|
2022-06-28 21:49:03 +02:00
|
|
|
setError("Login failed")
|
2022-06-13 16:12:52 +02:00
|
|
|
}
|
|
|
|
|
}).catch( err => setError(err.toString()))
|
|
|
|
|
setLoadingBtn(false)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2024-10-13 01:50:52 +02:00
|
|
|
return <Box className='center-flex-row' style={{padding:"100px"}}>
|
|
|
|
|
<Title order={2} style={{textAlign:"center"}}>Welcome to Firegex 🔥</Title>
|
2022-06-13 16:12:52 +02:00
|
|
|
<Space h="xl" />
|
2024-10-13 01:50:52 +02:00
|
|
|
<Title order={2} style={{textAlign:"center"}}>Before you use the firewall, insert the password 🔒</Title>
|
2022-06-13 16:12:52 +02:00
|
|
|
<Space h="xl" />
|
|
|
|
|
<form onSubmit={form.onSubmit(submitRequest)} style={{width:"80%"}}>
|
2022-06-19 20:11:28 +02:00
|
|
|
<PasswordInput
|
2022-06-13 16:12:52 +02:00
|
|
|
label="Password"
|
|
|
|
|
placeholder="$3cr3t"
|
|
|
|
|
{...form.getInputProps('password')}
|
|
|
|
|
/>
|
2024-10-13 01:50:52 +02:00
|
|
|
<Group align="right" mt="md">
|
2022-06-13 16:12:52 +02:00
|
|
|
<Button loading={loadinBtn} type="submit">Login</Button>
|
|
|
|
|
</Group>
|
|
|
|
|
</form>
|
|
|
|
|
<Space h="xl" />
|
|
|
|
|
{error?<>
|
|
|
|
|
<Notification icon={<ImCross size={14} />} color="red" onClose={()=>{setError(null)}}>
|
|
|
|
|
Error: {error}
|
|
|
|
|
</Notification><Space h="md" /></>:null}
|
2024-10-13 01:50:52 +02:00
|
|
|
</Box>
|
2022-06-13 16:12:52 +02:00
|
|
|
}else if (systemStatus.status === "run" && systemStatus.loggined){
|
2025-02-25 23:53:04 +01:00
|
|
|
return <PageRouting getStatus={getStatus} />
|
2022-06-13 16:12:52 +02:00
|
|
|
}else{
|
2024-10-13 01:50:52 +02:00
|
|
|
return <Box className='center-flex-row' style={{padding:"100px"}}>
|
|
|
|
|
<Title order={1} style={{textAlign:"center"}}>Error launching Firegex! 🔥</Title>
|
2022-06-13 16:12:52 +02:00
|
|
|
<Space h="md" />
|
2024-10-13 01:50:52 +02:00
|
|
|
<Title order={4} style={{textAlign:"center"}}>Error communicating with backend</Title>
|
|
|
|
|
</Box>
|
2022-06-13 16:12:52 +02:00
|
|
|
}
|
2022-06-11 21:57:50 +02:00
|
|
|
}
|
|
|
|
|
|
2025-02-25 23:53:04 +01:00
|
|
|
const PageRouting = ({ getStatus }:{ getStatus:()=>void }) => {
|
|
|
|
|
|
|
|
|
|
const queryClient = useQueryClient()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(()=>{
|
|
|
|
|
getStatus()
|
|
|
|
|
socket.on("update", (data) => {
|
|
|
|
|
queryClient.invalidateQueries({ queryKey: data })
|
|
|
|
|
})
|
|
|
|
|
socket.on("connect_error", (err) => {
|
|
|
|
|
errorNotify("Socket.Io connection failed! ",`Error message: [${err.message}]`)
|
|
|
|
|
getStatus()
|
|
|
|
|
});
|
|
|
|
|
return () => {
|
|
|
|
|
socket.off("update")
|
|
|
|
|
socket.off("connect_error")
|
|
|
|
|
}
|
|
|
|
|
},[])
|
|
|
|
|
|
|
|
|
|
return <Routes>
|
|
|
|
|
<Route element={<MainLayout><Outlet /></MainLayout>}>
|
|
|
|
|
<Route path="nfregex" element={<NFRegex><Outlet /></NFRegex>} >
|
|
|
|
|
<Route path=":srv" element={<ServiceDetailsNFRegex />} />
|
|
|
|
|
</Route>
|
|
|
|
|
<Route path="nfproxy" element={<NFProxy><Outlet /></NFProxy>} >
|
|
|
|
|
<Route path=":srv" element={<ServiceDetailsNFProxy />} />
|
|
|
|
|
</Route>
|
|
|
|
|
<Route path="firewall" element={<Firewall />} />
|
|
|
|
|
<Route path="porthijack" element={<PortHijack />} />
|
|
|
|
|
<Route path="*" element={<HomeRedirector />} />
|
|
|
|
|
</Route>
|
|
|
|
|
</Routes>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-06-11 21:57:50 +02:00
|
|
|
export default App;
|