React Interface v3
This commit is contained in:
@@ -1,33 +1,60 @@
|
||||
import { Button, Group, NumberInput, Space, TextInput, Notification } from '@mantine/core';
|
||||
import { Button, Group, NumberInput, Space, TextInput, Notification, Switch, NativeSelect } from '@mantine/core';
|
||||
import { useForm } from '@mantine/hooks';
|
||||
import React, { useState } from 'react';
|
||||
import { ServiceAddForm } from '../js/models';
|
||||
import { addservice } from '../js/utils';
|
||||
import { RegexAddForm, ServiceAddForm } from '../js/models';
|
||||
import { addregex, addservice, b64encode, validateRegex } from '../js/utils';
|
||||
import { ImCross } from "react-icons/im"
|
||||
import FilterTypeSelector from './FilterTypeSelector';
|
||||
|
||||
|
||||
type RegexAddInfo = {
|
||||
regex:string,
|
||||
type:string,
|
||||
mode:string,
|
||||
regex_exact:boolean,
|
||||
percentage_encoding:boolean
|
||||
}
|
||||
|
||||
function AddNewRegex({ closePopup, service }:{ closePopup:()=>void, service:string }) {
|
||||
|
||||
return <></>
|
||||
/*
|
||||
|
||||
const form = useForm({
|
||||
initialValues: {
|
||||
regex:"",
|
||||
is_blacklist:true,
|
||||
mode:"B"
|
||||
type:"blacklist",
|
||||
mode:"C <-> S",
|
||||
regex_exact:false,
|
||||
percentage_encoding:false
|
||||
},
|
||||
validationRules:{
|
||||
regex: (value) => value !== ""?true:false,
|
||||
port: (value) => value>0 && value<65536
|
||||
regex: (value) => value !== "" && validateRegex(value),
|
||||
type: (value) => ["blacklist","whitelist"].includes(value),
|
||||
mode: (value) => ['C -> S', 'S -> C', 'C <-> S'].includes(value)
|
||||
}
|
||||
})
|
||||
|
||||
const [submitLoading, setSubmitLoading] = useState(false)
|
||||
const [error, setError] = useState<string|null>(null)
|
||||
|
||||
const submitRequest = (values:ServiceAddForm) =>{
|
||||
const submitRequest = (values:RegexAddInfo) => {
|
||||
setSubmitLoading(true)
|
||||
addservice(values).then( res => {
|
||||
const filter_mode = ({'C -> S':'C', 'S -> C':'S', 'C <-> S':'B'}[values.mode])
|
||||
|
||||
let final_regex = values.regex
|
||||
if (values.percentage_encoding){
|
||||
final_regex = decodeURIComponent(final_regex)
|
||||
}
|
||||
if(!values.regex_exact){
|
||||
final_regex = ".*"+final_regex+".*"
|
||||
}
|
||||
|
||||
const request:RegexAddForm = {
|
||||
is_blacklist:values.type !== "whitelist",
|
||||
service_id: service,
|
||||
mode: filter_mode?filter_mode:"B",
|
||||
regex: b64encode(final_regex)
|
||||
}
|
||||
setSubmitLoading(false)
|
||||
addregex(request).then( res => {
|
||||
if (!res){
|
||||
setSubmitLoading(false)
|
||||
closePopup();
|
||||
@@ -39,32 +66,44 @@ function AddNewRegex({ closePopup, service }:{ closePopup:()=>void, service:stri
|
||||
setSubmitLoading(false)
|
||||
setError("Request Failed! [ "+err+" ]")
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
return <form onSubmit={form.onSubmit(submitRequest)}>
|
||||
<TextInput
|
||||
required
|
||||
label="Service name"
|
||||
placeholder="Challenge 01"
|
||||
{...form.getInputProps('name')}
|
||||
label="Regex"
|
||||
placeholder="[A-Z0-9]{31}="
|
||||
{...form.getInputProps('regex')}
|
||||
/>
|
||||
<Space h="md" />
|
||||
|
||||
<NumberInput
|
||||
<Switch
|
||||
label="Use percentage encoding for binary values"
|
||||
{...form.getInputProps('percentage_encoding', { type: 'checkbox' })}
|
||||
/>
|
||||
<Space h="md" />
|
||||
<Switch
|
||||
label="Match the exactly the regex"
|
||||
{...form.getInputProps('regex_exact', { type: 'checkbox' })}
|
||||
/>
|
||||
<Space h="md" />
|
||||
<NativeSelect
|
||||
data={['C -> S', 'S -> C', 'C <-> S']}
|
||||
label="Choose the source of the packets to filter"
|
||||
variant="filled"
|
||||
required
|
||||
placeholder="8080"
|
||||
min={1}
|
||||
max={65535}
|
||||
label="Service port"
|
||||
{...form.getInputProps('port')}
|
||||
{...form.getInputProps('mode')}
|
||||
/>
|
||||
|
||||
|
||||
<Space h="md" />
|
||||
|
||||
<FilterTypeSelector
|
||||
size="md"
|
||||
color="gray"
|
||||
required
|
||||
{...form.getInputProps('type')}
|
||||
/>
|
||||
<Group position="right" mt="md">
|
||||
<Button loading={submitLoading} type="submit">Add Service</Button>
|
||||
<Button loading={submitLoading} type="submit">Add Filter</Button>
|
||||
</Group>
|
||||
|
||||
<Space h="md" />
|
||||
@@ -75,7 +114,6 @@ function AddNewRegex({ closePopup, service }:{ closePopup:()=>void, service:stri
|
||||
</Notification><Space h="md" /></>:null}
|
||||
|
||||
</form>
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
32
frontend/src/components/FilterTypeSelector.tsx
Executable file
32
frontend/src/components/FilterTypeSelector.tsx
Executable file
@@ -0,0 +1,32 @@
|
||||
import { Box, Center, SegmentedControl } from "@mantine/core";
|
||||
import React from "react";
|
||||
import { FaListAlt } from "react-icons/fa";
|
||||
import { TiCancel } from "react-icons/ti";
|
||||
|
||||
|
||||
|
||||
export default function FilterTypeSelector(props:any){
|
||||
return <SegmentedControl
|
||||
data={[
|
||||
{
|
||||
value: 'blacklist',
|
||||
label: (
|
||||
<Center style={{color:"#FFF"}}>
|
||||
<TiCancel size={23} color="red"/>
|
||||
<Box ml={10}>Blacklist</Box>
|
||||
</Center>
|
||||
),
|
||||
},
|
||||
{
|
||||
value: 'whitelist',
|
||||
label: (
|
||||
<Center style={{color:"#FFF"}}>
|
||||
<FaListAlt size={16} color="gray"/>
|
||||
<Box ml={10}>Whitelist</Box>
|
||||
</Center>
|
||||
),
|
||||
},
|
||||
]}
|
||||
{...props}
|
||||
/>
|
||||
}
|
||||
@@ -1,15 +1,14 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { ActionIcon, Badge, Modal } from '@mantine/core';
|
||||
import style from "./Header.module.scss";
|
||||
import { generalstats } from '../../js/utils';
|
||||
import { GeneralStats, notification_time, update_freq } from '../../js/models';
|
||||
import { errorNotify, generalstats } from '../../js/utils';
|
||||
import { GeneralStats, update_freq } from '../../js/models';
|
||||
import { BsPlusLg } from "react-icons/bs"
|
||||
import { AiFillHome } from "react-icons/ai"
|
||||
import { useLocation, useNavigate, useParams } from 'react-router-dom';
|
||||
import AddNewRegex from '../AddNewRegex';
|
||||
import AddNewService from '../AddNewService';
|
||||
import { showNotification } from '@mantine/notifications';
|
||||
import { ImCross } from 'react-icons/im';
|
||||
|
||||
|
||||
function Header() {
|
||||
|
||||
@@ -22,15 +21,8 @@ function Header() {
|
||||
generalstats().then(res => {
|
||||
setGeneralStats(res)
|
||||
}).catch(
|
||||
err =>{
|
||||
showNotification({
|
||||
autoClose: notification_time,
|
||||
title: "General Info Auto-Update failed!",
|
||||
message: "[ "+err+" ]",
|
||||
color: 'red',
|
||||
icon: <ImCross />,
|
||||
});
|
||||
})
|
||||
err => errorNotify("General Info Auto-Update failed!", err.toString())
|
||||
)
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
import { Center, Grid, SegmentedControl, Text, Title, Box, Badge, Space, ActionIcon } from '@mantine/core';
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { RegexFilter } from '../../js/models';
|
||||
import { getHumanReadableRegex } from '../../js/utils';
|
||||
import style from "./RegexView.module.scss";
|
||||
import { FaListAlt } from "react-icons/fa"
|
||||
import { TiCancel } from "react-icons/ti"
|
||||
import { BsTrashFill } from "react-icons/bs"
|
||||
import YesNoModal from '../YesNoModal';
|
||||
import FilterTypeSelector from '../FilterTypeSelector';
|
||||
|
||||
|
||||
function RegexView({ regexInfo }:{ regexInfo:RegexFilter }) {
|
||||
|
||||
const mode_string = regexInfo.mode == "C"? "C -> S":
|
||||
regexInfo.mode == "S"? "S -> C":
|
||||
regexInfo.mode == "B"? "S <-> C": "🤔"
|
||||
const mode_string = regexInfo.mode === "C"? "C -> S":
|
||||
regexInfo.mode === "S"? "S -> C":
|
||||
regexInfo.mode === "B"? "S <-> C": "🤔"
|
||||
|
||||
let regex_expr = getHumanReadableRegex(regexInfo.regex);
|
||||
let exact_regex = true;
|
||||
@@ -22,6 +24,8 @@ function RegexView({ regexInfo }:{ regexInfo:RegexFilter }) {
|
||||
exact_regex = false;
|
||||
}
|
||||
|
||||
const [deleteModal, setDeleteModal] = useState(false);
|
||||
|
||||
return <div className={style.box}>
|
||||
<Grid>
|
||||
<Grid.Col span={2}>
|
||||
@@ -31,55 +35,42 @@ function RegexView({ regexInfo }:{ regexInfo:RegexFilter }) {
|
||||
<Text className={style.regex_text}> {regex_expr}</Text>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2}>
|
||||
<ActionIcon color="red" onClick={()=>{}} size="xl" radius="md" variant="filled"><BsTrashFill size={22} /></ActionIcon>
|
||||
<ActionIcon color="red" onClick={()=>setDeleteModal(true)} size="xl" radius="md" variant="filled"><BsTrashFill size={22} /></ActionIcon>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2} />
|
||||
<Grid.Col className='center-flex-row' span={4}>
|
||||
<Space h="xs" />
|
||||
<SegmentedControl
|
||||
data={[
|
||||
{
|
||||
value: 'blacklist',
|
||||
label: (
|
||||
<Center style={{color:"#FFF"}}>
|
||||
<TiCancel size={23} color="red"/>
|
||||
<Box ml={10}>Blacklist</Box>
|
||||
</Center>
|
||||
),
|
||||
},
|
||||
{
|
||||
value: 'whitelist',
|
||||
label: (
|
||||
<Center style={{color:"#FFF"}}>
|
||||
<FaListAlt size={16} color="gray"/>
|
||||
<Box ml={10}>Whitelist</Box>
|
||||
</Center>
|
||||
),
|
||||
},
|
||||
]}
|
||||
<FilterTypeSelector
|
||||
size="md"
|
||||
color="gray"
|
||||
disabled
|
||||
/>
|
||||
<Space h="md" />
|
||||
<div className='center-flex'>
|
||||
<Badge size="md" color="green" variant="filled">Service: {regexInfo.service_id}</Badge>
|
||||
<Space w="xs" />
|
||||
<Badge size="md" color="gray" variant="filled">ID: {regexInfo.id}</Badge>
|
||||
</div>
|
||||
</Grid.Col>
|
||||
<Grid.Col style={{width:"100%"}} span={6}>
|
||||
value={regexInfo.is_blacklist?"blacklist":"whitelist"}
|
||||
/>
|
||||
<Space h="md" />
|
||||
<div className='center-flex'>
|
||||
<Badge size="md" color="green" variant="filled">Service: {regexInfo.service_id}</Badge>
|
||||
<Space w="xs" />
|
||||
<Badge size="md" color="gray" variant="filled">ID: {regexInfo.id}</Badge>
|
||||
</div>
|
||||
</Grid.Col>
|
||||
<Grid.Col style={{width:"100%"}} span={6}>
|
||||
<Space h="xs" />
|
||||
<div className='center-flex-row'>
|
||||
<Badge size="md" color={exact_regex?"grape":"pink"} variant="filled">Match: {exact_regex?"EXACT":"FIND"}</Badge>
|
||||
<Space h="xs" />
|
||||
<div className='center-flex-row'>
|
||||
<Badge size="md" color={exact_regex?"grape":"pink"} variant="filled">Match: {exact_regex?"EXACT":"FIND"}</Badge>
|
||||
<Space h="xs" />
|
||||
<Badge size="md" color="yellow" variant="filled">Packets filtered: {regexInfo.n_packets}</Badge>
|
||||
<Space h="xs" />
|
||||
<Badge size="md" color="blue" variant="filled">Mode: {mode_string}</Badge>
|
||||
</div>
|
||||
</Grid.Col>
|
||||
|
||||
<Badge size="md" color="yellow" variant="filled">Packets filtered: {regexInfo.n_packets}</Badge>
|
||||
<Space h="xs" />
|
||||
<Badge size="md" color="blue" variant="filled">Mode: {mode_string}</Badge>
|
||||
</div>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
<YesNoModal
|
||||
title='Are you sure to delete this regex?'
|
||||
description={`You are going to delete the regex '${regex_expr}', causing the restart of the firewall if it is active.`}
|
||||
onClose={()=>setDeleteModal(false)}
|
||||
action={()=>console.log("Delete regex please!")}
|
||||
opened={deleteModal}
|
||||
/>
|
||||
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { ActionIcon, Badge, Grid, Space, Title } from '@mantine/core';
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { FaPause, FaPlay, FaStop } from 'react-icons/fa';
|
||||
import { Service } from '../../js/models';
|
||||
import { MdOutlineArrowForwardIos } from "react-icons/md"
|
||||
import style from "./ServiceRow.module.scss";
|
||||
import YesNoModal from '../YesNoModal';
|
||||
|
||||
//"status":"stop"/"wait"/"active"/"pause",
|
||||
function ServiceRow({ service, onClick, additional_buttons }:{ service:Service, onClick?:()=>void, additional_buttons?:any }) {
|
||||
@@ -15,6 +16,31 @@ function ServiceRow({ service, onClick, additional_buttons }:{ service:Service,
|
||||
case "active": status_color = "teal"; break;
|
||||
case "pause": status_color = "cyan"; break;
|
||||
}
|
||||
|
||||
const [stopModal, setStopModal] = useState(false);
|
||||
const [buttonLoading, setButtonLoading] = useState(false)
|
||||
|
||||
const stopService = () => {
|
||||
setButtonLoading(true)
|
||||
console.log("Stop this service please!")
|
||||
setButtonLoading(false)
|
||||
}
|
||||
|
||||
const startService = () => {
|
||||
setButtonLoading(true)
|
||||
console.log("Start this service please!")
|
||||
setButtonLoading(false)
|
||||
}
|
||||
|
||||
const pauseService = () => {
|
||||
if (service.status === "pause") return setStopModal(true)
|
||||
setButtonLoading(true)
|
||||
console.log("Pause this service please!")
|
||||
setButtonLoading(false)
|
||||
}
|
||||
|
||||
|
||||
|
||||
return <>
|
||||
<Grid className={style.row} style={{width:"100%"}}>
|
||||
<Grid.Col span={4}>
|
||||
@@ -33,17 +59,29 @@ function ServiceRow({ service, onClick, additional_buttons }:{ service:Service,
|
||||
<Space w="xl" /><Space w="xl" />
|
||||
<div className="center-flex">
|
||||
{additional_buttons}
|
||||
<ActionIcon color={service.status === "pause"?"yellow":"red"} size="xl" radius="md" variant="filled" disabled={!["wait","active","pause"].includes(service.status)?true:false}>
|
||||
<ActionIcon color={service.status === "pause"?"yellow":"red"} loading={buttonLoading}
|
||||
onClick={pauseService} size="xl" radius="md" variant="filled"
|
||||
disabled={!["wait","active","pause"].includes(service.status)?true:false}>
|
||||
{service.status === "pause"?<FaStop size="20px" />:<FaPause size="20px" />}
|
||||
</ActionIcon>
|
||||
<Space w="md"/>
|
||||
<ActionIcon color="teal" size="xl" radius="md" variant="filled" disabled={!["stop","pause"].includes(service.status)?true:false}><FaPlay size="20px" /></ActionIcon>
|
||||
<ActionIcon color="teal" size="xl" radius="md" onClick={startService} loading={buttonLoading}
|
||||
variant="filled" disabled={!["stop","pause"].includes(service.status)?true:false}>
|
||||
<FaPlay size="20px" />
|
||||
</ActionIcon>
|
||||
</div>
|
||||
<Space w="xl" /><Space w="xl" />
|
||||
{onClick?<MdOutlineArrowForwardIos onClick={onClick} style={{cursor:"pointer"}} size="45px" />:null}
|
||||
<Space w="xl" />
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
<YesNoModal
|
||||
title='Are you sure to stop this service!'
|
||||
description={`You are going to delete the service '${service.id}', causing the stopping of the firewall. This will cause the shutdown of your service ⚠️!`}
|
||||
onClose={()=>setStopModal(false)}
|
||||
action={stopService}
|
||||
opened={stopModal}
|
||||
/>
|
||||
<hr style={{width:"100%"}}/>
|
||||
</>
|
||||
}
|
||||
|
||||
19
frontend/src/components/YesNoModal.tsx
Executable file
19
frontend/src/components/YesNoModal.tsx
Executable file
@@ -0,0 +1,19 @@
|
||||
import { Button, Group, Modal } from '@mantine/core';
|
||||
import React from 'react';
|
||||
|
||||
function YesNoModal( { title, description, action, onClose, opened}:{ title:string, description:string, onClose:()=>void, action:()=>void, opened:boolean} ){
|
||||
|
||||
return <Modal size="xl" title={title} opened={opened} onClose={onClose} centered>
|
||||
{description}
|
||||
<Group position="right" mt="md">
|
||||
<Button onClick={()=>{
|
||||
onClose()
|
||||
action()
|
||||
}} color="teal" type="submit">Yes</Button>
|
||||
<Button onClick={onClose} color="red" type="submit">No</Button>
|
||||
|
||||
</Group>
|
||||
</Modal>
|
||||
}
|
||||
|
||||
export default YesNoModal;
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
export const update_freq = 5000;
|
||||
export const update_freq = 3000;
|
||||
export const notification_time = 2000;
|
||||
|
||||
export type GeneralStats = {
|
||||
@@ -37,3 +37,10 @@ export type RegexFilter = {
|
||||
mode:string //C S B => C->S S->C BOTH
|
||||
n_packets:number
|
||||
}
|
||||
|
||||
export type RegexAddForm = {
|
||||
"service_id":string,
|
||||
"regex":string,
|
||||
"is_blacklist":boolean,
|
||||
"mode":string // C->S S->C BOTH
|
||||
}
|
||||
@@ -1,4 +1,9 @@
|
||||
import { GeneralStats, Service, ServiceAddForm, ServerResponse, RegexFilter } from "./models";
|
||||
import { showNotification } from "@mantine/notifications";
|
||||
import { ImCross } from "react-icons/im";
|
||||
import { TiTick } from "react-icons/ti"
|
||||
import { GeneralStats, Service, ServiceAddForm, ServerResponse, RegexFilter, notification_time, RegexAddForm } from "./models";
|
||||
|
||||
var Buffer = require('buffer').Buffer
|
||||
|
||||
export async function getapi(path:string):Promise<any>{
|
||||
return await fetch(`/api/${path}`).then( res => res.json() )
|
||||
@@ -33,6 +38,11 @@ export async function addservice(data:ServiceAddForm) {
|
||||
return status === "ok"?undefined:status
|
||||
}
|
||||
|
||||
export async function addregex(data:RegexAddForm) {
|
||||
const { status } = await postapi("regexes/add",data) as ServerResponse;
|
||||
return status === "ok"?undefined:status
|
||||
}
|
||||
|
||||
export async function serviceregexlist(service_id:string){
|
||||
return await getapi(`service/${service_id}/regexes`) as RegexFilter[];
|
||||
}
|
||||
@@ -40,7 +50,6 @@ export async function serviceregexlist(service_id:string){
|
||||
const unescapedChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$&\'()*+,-./:;<=>?@[\\]^_`{|}~ ";
|
||||
|
||||
export function getHumanReadableRegex(regexB64:string){
|
||||
var Buffer = require('buffer').Buffer
|
||||
const regex = Buffer.from(regexB64, "base64")
|
||||
let res = ""
|
||||
for (let i=0; i < regex.length; i++){
|
||||
@@ -53,3 +62,44 @@ export function getHumanReadableRegex(regexB64:string){
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
export function errorNotify(title:string, description:string ){
|
||||
showNotification({
|
||||
autoClose: notification_time,
|
||||
title: title,
|
||||
message: description,
|
||||
color: 'red',
|
||||
icon: <ImCross />,
|
||||
});
|
||||
}
|
||||
|
||||
export function okNotify(title:string, description:string ){
|
||||
showNotification({
|
||||
autoClose: notification_time,
|
||||
title: title,
|
||||
message: description,
|
||||
color: 'teal',
|
||||
icon: <TiTick />,
|
||||
});
|
||||
}
|
||||
|
||||
export function validateRegex(pattern:string) {
|
||||
var parts = pattern.split('/'),
|
||||
regex = pattern,
|
||||
options = "";
|
||||
if (parts.length > 1) {
|
||||
regex = parts[1];
|
||||
options = parts[2];
|
||||
}
|
||||
try {
|
||||
new RegExp(regex, options);
|
||||
return true;
|
||||
}
|
||||
catch(e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function b64encode(data:string){
|
||||
return Buffer.from(data).toString('base64')
|
||||
}
|
||||
@@ -1,50 +1,22 @@
|
||||
import { Space, Title } from '@mantine/core';
|
||||
import { showNotification } from '@mantine/notifications';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import ServiceRow from '../components/ServiceRow';
|
||||
import { notification_time, Service, update_freq } from '../js/models';
|
||||
import { servicelist } from '../js/utils';
|
||||
import { ImCross } from "react-icons/im"
|
||||
import { Service, update_freq } from '../js/models';
|
||||
import { errorNotify, servicelist } from '../js/utils';
|
||||
|
||||
|
||||
function HomePage() {
|
||||
|
||||
const [services, setServices] = useState<Service[]>([
|
||||
{
|
||||
id:"ctfe",
|
||||
internal_port:18080,
|
||||
n_packets: 30,
|
||||
n_regex: 40,
|
||||
name:"CTFe",
|
||||
public_port:80,
|
||||
status:"pause"
|
||||
},
|
||||
{
|
||||
id:"saas",
|
||||
internal_port:18080,
|
||||
n_packets: 30,
|
||||
n_regex: 40,
|
||||
name:"SaaS",
|
||||
public_port:5000,
|
||||
status:"active"
|
||||
}
|
||||
]);
|
||||
const [services, setServices] = useState<Service[]>([]);
|
||||
const navigator = useNavigate()
|
||||
|
||||
const updateInfo = () => {
|
||||
servicelist().then(res => {
|
||||
setServices(res)
|
||||
}).catch(
|
||||
err =>{
|
||||
showNotification({
|
||||
autoClose: notification_time,
|
||||
title: "Home Page Auto-Update failed!",
|
||||
message: "[ "+err+" ]",
|
||||
color: 'red',
|
||||
icon: <ImCross />,
|
||||
});
|
||||
})
|
||||
err => errorNotify("Home Page Auto-Update failed!", err.toString())
|
||||
)
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import { ActionIcon, Grid, Space, Title } from '@mantine/core';
|
||||
import { showNotification } from '@mantine/notifications';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { BsTrashFill } from 'react-icons/bs';
|
||||
import { ImCross } from 'react-icons/im';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import RegexView from '../components/RegexView';
|
||||
import ServiceRow from '../components/ServiceRow';
|
||||
import { notification_time, RegexFilter, Service, update_freq } from '../js/models';
|
||||
import { serviceinfo, serviceregexlist } from '../js/utils';
|
||||
import YesNoModal from '../components/YesNoModal';
|
||||
import { RegexFilter, Service, update_freq } from '../js/models';
|
||||
import { errorNotify, serviceinfo, serviceregexlist } from '../js/utils';
|
||||
|
||||
function ServiceDetails() {
|
||||
const {srv_id} = useParams()
|
||||
@@ -22,24 +21,9 @@ function ServiceDetails() {
|
||||
status:"🤔"
|
||||
})
|
||||
|
||||
const [regexesList, setRegexesList] = useState<RegexFilter[]>([
|
||||
{
|
||||
id:3546,
|
||||
is_blacklist:true,
|
||||
mode:"B",
|
||||
regex:"LipmbGFnX2NoZWNrLio=",
|
||||
service_id:"ctfe",
|
||||
n_packets:5,
|
||||
},
|
||||
{
|
||||
id:3546,
|
||||
is_blacklist:true,
|
||||
mode:"B",
|
||||
regex:"d2VkcmZoaXdlZGZoYnVp",
|
||||
service_id:"ctfe",
|
||||
n_packets: 54
|
||||
}
|
||||
])
|
||||
const [regexesList, setRegexesList] = useState<RegexFilter[]>([])
|
||||
|
||||
const navigator = useNavigate()
|
||||
|
||||
const updateInfo = async () => {
|
||||
if (!srv_id) return
|
||||
@@ -48,28 +32,17 @@ function ServiceDetails() {
|
||||
setServiceInfo(res)
|
||||
}).catch(
|
||||
err =>{
|
||||
showNotification({
|
||||
autoClose: notification_time,
|
||||
title: `Updater for ${srv_id} service failed [General Info]!`,
|
||||
message: "[ "+err+" ]",
|
||||
color: 'red',
|
||||
icon: <ImCross />,
|
||||
});
|
||||
error = true;
|
||||
errorNotify(`Updater for ${srv_id} service failed [General Info]!`, err.toString())
|
||||
error = true;
|
||||
navigator("/")
|
||||
})
|
||||
if (error) return
|
||||
await serviceregexlist(srv_id).then(res => {
|
||||
setRegexesList(res)
|
||||
}).catch(
|
||||
err =>{
|
||||
showNotification({
|
||||
autoClose: notification_time,
|
||||
title: `Updater for ${srv_id} service failed [Regex list]!`,
|
||||
message: "[ "+err+" ]",
|
||||
color: 'red',
|
||||
icon: <ImCross />,
|
||||
});
|
||||
error = true;
|
||||
errorNotify(`Updater for ${srv_id} service failed [Regex list]!`, err.toString())
|
||||
error = true;
|
||||
})
|
||||
}
|
||||
|
||||
@@ -79,9 +52,11 @@ function ServiceDetails() {
|
||||
return () => { clearInterval(updater) }
|
||||
}, []);
|
||||
|
||||
const [deleteModal, setDeleteModal] = useState(false)
|
||||
|
||||
return <>
|
||||
<ServiceRow service={serviceInfo} additional_buttons={<>
|
||||
<ActionIcon color="red" onClick={()=>{}} size="xl" radius="md" variant="filled"><BsTrashFill size={22} /></ActionIcon>
|
||||
<ActionIcon color="red" onClick={()=>setDeleteModal(true)} size="xl" radius="md" variant="filled"><BsTrashFill size={22} /></ActionIcon>
|
||||
<Space w="md"/>
|
||||
</>}></ServiceRow>
|
||||
{regexesList.length === 0?
|
||||
@@ -90,6 +65,13 @@ function ServiceDetails() {
|
||||
{regexesList.map( (regexInfo) => <Grid.Col key={regexInfo.id} span={6}><RegexView regexInfo={regexInfo}/></Grid.Col>)}
|
||||
</Grid>
|
||||
}
|
||||
<YesNoModal
|
||||
title='Are you sure to delete this service?'
|
||||
description={`You are going to delete the service '${serviceInfo.id}', causing the stopping of the firewall and deleting all the regex associated. This will cause the shutdown of your service ⚠️!`}
|
||||
onClose={()=>setDeleteModal(false)}
|
||||
action={()=>console.log("Delete the service please!")}
|
||||
opened={deleteModal}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user