Merge pull request #42 from Pwnzer0tt1/dev

Minor UI and demo fixes
This commit is contained in:
Domingo Dirutigliano 2026-09-03 18:46:20 +02:00 committed by GitHub
commit 6b34de4371
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 13 additions and 16 deletions

View File

@ -27,13 +27,6 @@ def block_path_traversal(packet: HttpRequest):
if ".." in packet.url: if ".." in packet.url:
return REJECT return REJECT
return ACCEPT return ACCEPT
@pyfilter
def strip_debug_header(packet: HttpRequest):
if "X-Debug" in packet.headers:
del packet.headers["X-Debug"]
return ACCEPT
` `
// ------------------------------------------------------------------ seed state // ------------------------------------------------------------------ seed state
@ -65,14 +58,12 @@ const state = {
}, },
nfproxy: { nfproxy: {
services: [ services: [
{ service_id: svcProxy, name: "shop-api", status: "active", port: 9000, proto: "tcp", ip_int: "10.60.3.1", n_filters: 2, edited_packets: 3401, blocked_packets: 762, fail_open: true, target_type: "internal", tls_stream_id: null }, { service_id: svcProxy, name: "shop-api", status: "active", port: 9000, proto: "tcp", ip_int: "10.60.3.1", n_filters: 1, edited_packets: 0, blocked_packets: 641, fail_open: true, target_type: "internal", tls_stream_id: null },
{ service_id: svcQuiz, name: "quiz", status: "stop", port: 1337, proto: "tcp", ip_int: "10.60.3.1", n_filters: 2, edited_packets: 0, blocked_packets: 0, fail_open: false, target_type: "internal", tls_stream_id: null }, { service_id: svcQuiz, name: "quiz", status: "stop", port: 1337, proto: "tcp", ip_int: "10.60.3.1", n_filters: 1, edited_packets: 0, blocked_packets: 0, fail_open: false, target_type: "internal", tls_stream_id: null },
] as Json[], ] as Json[],
pyfilters: [ pyfilters: [
{ name: "block_path_traversal", service_id: svcProxy, blocked_packets: 641, edited_packets: 0, active: true }, { name: "block_path_traversal", service_id: svcProxy, blocked_packets: 641, edited_packets: 0, active: true },
{ name: "strip_debug_header", service_id: svcProxy, blocked_packets: 0, edited_packets: 3401, active: true },
{ name: "block_path_traversal", service_id: svcQuiz, blocked_packets: 0, edited_packets: 0, active: true }, { name: "block_path_traversal", service_id: svcQuiz, blocked_packets: 0, edited_packets: 0, active: true },
{ name: "strip_debug_header", service_id: svcQuiz, blocked_packets: 0, edited_packets: 0, active: false },
] as Json[], ] as Json[],
code: { [svcProxy]: SAMPLE_FILTER, [svcQuiz]: SAMPLE_FILTER } as Record<string, string>, code: { [svcProxy]: SAMPLE_FILTER, [svcQuiz]: SAMPLE_FILTER } as Record<string, string>,
tls: {} as Record<string, Json>, tls: {} as Record<string, Json>,
@ -125,7 +116,6 @@ const startTicker = () => {
} }
for (const s of state.nfproxy.services) { for (const s of state.nfproxy.services) {
if (s.status !== "active") continue if (s.status !== "active") continue
s.edited_packets += Math.floor(Math.random() * 12)
s.blocked_packets += Math.random() < 0.4 ? 1 : 0 s.blocked_packets += Math.random() < 0.4 ? 1 : 0
changed = true changed = true
} }
@ -252,8 +242,9 @@ const routes: [string, RegExp, Handler][] = [
["PUT", /^nfproxy\/services\/([^/]+)\/tls-config$/, () => ok], ["PUT", /^nfproxy\/services\/([^/]+)\/tls-config$/, () => ok],
["GET", /^nfproxy\/services\/([^/]+)\/tls-config$/, () => ({ tls_enabled: false, tls_cert: null, tls_key: null })], ["GET", /^nfproxy\/services\/([^/]+)\/tls-config$/, () => ({ tls_enabled: false, tls_cert: null, tls_key: null })],
["GET", /^nfproxy\/services\/([^/]+)\/pyfilters$/, m => state.nfproxy.pyfilters.filter(f => f.service_id === m[1])], ["GET", /^nfproxy\/services\/([^/]+)\/pyfilters$/, m => state.nfproxy.pyfilters.filter(f => f.service_id === m[1])],
["GET", /^nfproxy\/services\/([^/]+)\/code$/, m => ({ code: state.nfproxy.code[m[1]] ?? "" })], // the real endpoint is a PlainTextResponse: it returns the source, not an object
["POST", /^nfproxy\/services\/([^/]+)\/code$/, (m, b) => { ["GET", /^nfproxy\/services\/([^/]+)\/code$/, m => state.nfproxy.code[m[1]] ?? ""],
["PUT", /^nfproxy\/services\/([^/]+)\/code$/, (m, b) => {
state.nfproxy.code[m[1]] = b?.code ?? "" state.nfproxy.code[m[1]] = b?.code ?? ""
emit(["nfproxy"]); return ok emit(["nfproxy"]); return ok
}], }],

View File

@ -111,7 +111,11 @@ export async function genericapi(method:string,path:string,data:any = undefined,
const errorDefault = res.statusText const errorDefault = res.statusText
return res.json().then( res => reject(getErrorMessageFromServerResponse(res, errorDefault)) ).catch( _err => reject(errorDefault)) return res.json().then( res => reject(getErrorMessageFromServerResponse(res, errorDefault)) ).catch( _err => reject(errorDefault))
} }
// text/plain bodies (the nfproxy filter source) stay strings: a source file that
// happens to be valid JSON must not be parsed into a number/array/object
const isPlainText = (res.headers.get("content-type") ?? "").startsWith("text/plain")
res.text().then(t => { res.text().then(t => {
if (isPlainText) return resolve(t)
try{ try{
resolve(JSON.parse(t)) resolve(JSON.parse(t))
}catch(e){ }catch(e){

View File

@ -199,9 +199,11 @@ export const Firewall = () => {
radius="md" radius="md"
p="md" p="md"
mb="md" mb="md"
w="100%"
bg="transparent" bg="transparent"
style={{ style={{
// not the `w` prop: Mantine's style props would beat the width dnd measures, and
// `100%` against a `position: fixed` card resolves to the viewport, not the list
width: '100%',
transition: 'border-color 0.2s ease', transition: 'border-color 0.2s ease',
// dnd puts the drag transform/transition in here: it has to win over our defaults // dnd puts the drag transform/transition in here: it has to win over our defaults
...provided.draggableProps.style, ...provided.draggableProps.style,

View File

@ -207,7 +207,7 @@ export default function ServiceDetailsNFProxy() {
</Group> </Group>
</Card> </Card>
{filterCode.data ? <> {typeof filterCode.data === "string" && filterCode.data ? <>
<Group justify="center" gap="xs" mt="xl"> <Group justify="center" gap="xs" mt="xl">
<ThemeIcon radius="md" size="md" variant="light" color="yellow"><FaPython size={16} /></ThemeIcon> <ThemeIcon radius="md" size="md" variant="light" color="yellow"><FaPython size={16} /></ThemeIcon>
<Title order={3}>Filter code</Title> <Title order={3}>Filter code</Title>