2022-06-15 01:23:54 +02:00
import { Button , Group , Space , TextInput , Notification , Switch , NativeSelect , Tooltip , Modal } from '@mantine/core' ;
2022-06-12 12:09:50 +02:00
import { useForm } from '@mantine/hooks' ;
import React , { useState } from 'react' ;
2022-06-12 22:28:16 +02:00
import { RegexAddForm } from '../js/models' ;
2022-06-22 01:31:46 +02:00
import { addregex , b64encode , fireUpdateRequest , getBinaryRegex , getHumanReadableRegex , okNotify } from '../js/utils' ;
2022-06-12 12:09:50 +02:00
import { ImCross } from "react-icons/im"
2022-06-12 16:44:54 +02:00
import FilterTypeSelector from './FilterTypeSelector' ;
2022-06-12 12:09:50 +02:00
2022-06-12 16:44:54 +02:00
type RegexAddInfo = {
regex :string ,
type : string ,
mode :string ,
2022-06-18 00:18:50 +02:00
is_case_insensitive :boolean ,
2022-06-12 16:44:54 +02:00
percentage_encoding :boolean
}
2022-06-15 01:23:54 +02:00
function AddNewRegex ( { opened , onClose , service } : { opened :boolean , onClose : ( ) = > void , service :string } ) {
2022-06-12 12:09:50 +02:00
const form = useForm ( {
initialValues : {
regex : "" ,
2022-06-12 16:44:54 +02:00
type : "blacklist" ,
mode : "C <-> S" ,
2022-06-18 00:18:50 +02:00
is_case_insensitive :false ,
2022-06-12 16:44:54 +02:00
percentage_encoding :false
2022-06-12 12:09:50 +02:00
} ,
validationRules : {
2022-06-15 08:47:13 +02:00
regex : ( value ) = > value !== "" ,
2022-06-12 16:44:54 +02:00
type : ( value ) = > [ "blacklist" , "whitelist" ] . includes ( value ) ,
mode : ( value ) = > [ 'C -> S' , 'S -> C' , 'C <-> S' ] . includes ( value )
2022-06-12 12:09:50 +02:00
}
} )
2022-06-15 01:23:54 +02:00
const close = ( ) = > {
onClose ( )
form . reset ( )
2022-06-15 08:47:13 +02:00
setError ( null )
2022-06-15 01:23:54 +02:00
}
2022-06-12 12:09:50 +02:00
const [ submitLoading , setSubmitLoading ] = useState ( false )
const [ error , setError ] = useState < string | null > ( null )
2022-06-12 16:44:54 +02:00
const submitRequest = ( values :RegexAddInfo ) = > {
2022-06-12 12:09:50 +02:00
setSubmitLoading ( true )
2022-06-12 16:44:54 +02:00
const filter_mode = ( { 'C -> S' : 'C' , 'S -> C' : 'S' , 'C <-> S' : 'B' } [ values . mode ] )
2022-06-22 01:31:46 +02:00
let final_regex :string | number [ ] = values . regex
2022-06-12 16:44:54 +02:00
if ( values . percentage_encoding ) {
2022-06-22 01:31:46 +02:00
final_regex = getBinaryRegex ( final_regex )
2022-06-12 16:44:54 +02:00
}
const request :RegexAddForm = {
is_blacklist :values.type !== "whitelist" ,
2022-06-18 00:18:50 +02:00
is_case_sensitive : ! values . is_case_insensitive ,
2022-06-12 16:44:54 +02:00
service_id : service ,
mode : filter_mode?filter_mode : "B" ,
regex : b64encode ( final_regex )
}
setSubmitLoading ( false )
addregex ( request ) . then ( res = > {
2022-06-12 12:09:50 +02:00
if ( ! res ) {
setSubmitLoading ( false )
2022-06-15 01:23:54 +02:00
close ( ) ;
2022-06-15 19:44:41 +02:00
fireUpdateRequest ( ) ;
2022-06-17 20:48:27 +02:00
okNotify ( ` Regex ${ getHumanReadableRegex ( request . regex ) } has been added ` , ` Successfully added ${ request . is_case_sensitive ? "case sensitive" : "case insensitive" } ${ request . is_blacklist ? "blacklist" : "whitelist" } regex to ${ request . service_id } service ` )
2022-06-15 08:47:13 +02:00
} else if ( res . toLowerCase ( ) === "invalid regex" ) {
setSubmitLoading ( false )
form . setFieldError ( "regex" , "Invalid Regex" )
2022-06-12 12:09:50 +02:00
} else {
setSubmitLoading ( false )
2022-06-15 08:47:13 +02:00
setError ( "Error: [ " + res + " ]" )
2022-06-12 12:09:50 +02:00
}
} ) . catch ( err = > {
setSubmitLoading ( false )
setError ( "Request Failed! [ " + err + " ]" )
} )
2022-06-12 16:44:54 +02:00
2022-06-12 12:09:50 +02:00
}
2022-06-15 01:23:54 +02:00
return < Modal size = "xl" title = "Add a new regex filter" opened = { opened } onClose = { close } closeOnClickOutside = { false } centered >
< form onSubmit = { form . onSubmit ( submitRequest ) } >
< TextInput
label = "Regex"
placeholder = "[A-Z0-9]{31}="
{ . . . form . getInputProps ( 'regex' ) }
/ >
< Space h = "md" / >
2022-06-16 02:25:41 +02:00
< Tooltip label = "To represent binary data use URL encoding. Example: %01" transition = "slide-right" openDelay = { 500 } transitionDuration = { 500 } transitionTimingFunction = "ease"
color = "gray" wrapLines width = { 220 } withArrow position = 'right' gutter = { 20 } >
2022-06-15 01:23:54 +02:00
< Switch
label = "Use percentage encoding for binary values"
{ . . . form . getInputProps ( 'percentage_encoding' , { type : 'checkbox' } ) }
/ >
< / Tooltip >
< Space h = "md" / >
2022-06-17 20:48:27 +02:00
< Switch
2022-06-18 00:18:50 +02:00
label = "Case insensitive"
{ . . . form . getInputProps ( 'is_case_insensitive' , { type : 'checkbox' } ) }
2022-06-17 20:48:27 +02:00
/ >
< Space h = "md" / >
2022-06-15 01:23:54 +02:00
< NativeSelect
data = { [ 'C -> S' , 'S -> C' , 'C <-> S' ] }
label = "Choose the source of the packets to filter"
variant = "filled"
{ . . . form . getInputProps ( 'mode' ) }
2022-06-14 22:43:48 +02:00
/ >
2022-06-15 01:23:54 +02:00
< Space h = "md" / >
< FilterTypeSelector
size = "md"
color = "gray"
{ . . . form . getInputProps ( 'type' ) }
/ >
< Group position = "right" mt = "md" >
< Button loading = { submitLoading } type = "submit" > Add Filter < / Button >
< / Group >
2022-06-12 12:09:50 +02:00
2022-06-15 01:23:54 +02:00
< Space h = "md" / >
{ error ? < >
< Notification icon = { < ImCross size = { 14 } / > } color = "red" onClose = { ( ) = > { setError ( null ) } } >
Error : { error }
< / Notification > < Space h = "md" / > < / > : null }
< / form >
< / Modal >
2022-06-12 12:09:50 +02:00
}
export default AddNewRegex ;