From ca1ee64829736fbcf52676981555dc2d57a7b608 Mon Sep 17 00:00:00 2001 From: Debian Date: Sun, 24 May 2026 12:40:08 +0200 Subject: [PATCH] fix(firewall): fehlende onError-Handler + i18n in Rules + NATRules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 6 Mutations (create/update/del je Rules + NATRules) bekommen onError-Handler - Deutsche Placeholder-Texte → t() überführt - Action-Labels (accept/drop/reject) und Kind-Labels (any/object/group/cidr) in t() überführt statt hardkodiert anzeigen - CIDR-Label-Hardkodierung in Rules-Formular behoben - en/de: fw.rule.actions.*, fw.rule.kinds.*, fw.rule.namePlaceholder, fw.nat.namePlaceholder ergänzt Co-Authored-By: Claude Sonnet 4.6 --- VERSION | 2 +- cmd/edgeguard-api/main.go | 2 +- cmd/edgeguard-ctl/main.go | 2 +- cmd/edgeguard-scheduler/main.go | 2 +- management-ui/src/i18n/locales/de/common.json | 5 +++++ management-ui/src/i18n/locales/en/common.json | 5 +++++ management-ui/src/pages/Firewall/NATRules.tsx | 5 ++++- management-ui/src/pages/Firewall/Rules.tsx | 13 ++++++++----- 8 files changed, 26 insertions(+), 10 deletions(-) diff --git a/VERSION b/VERSION index 6daa822..a1b3d6b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.82 +1.1.83 diff --git a/cmd/edgeguard-api/main.go b/cmd/edgeguard-api/main.go index e622712..db6c14b 100644 --- a/cmd/edgeguard-api/main.go +++ b/cmd/edgeguard-api/main.go @@ -60,7 +60,7 @@ import ( usersvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/users" ) -var version = "1.1.82" +var version = "1.1.83" func main() { addr := os.Getenv("EDGEGUARD_API_ADDR") diff --git a/cmd/edgeguard-ctl/main.go b/cmd/edgeguard-ctl/main.go index 28c32e7..be8a726 100644 --- a/cmd/edgeguard-ctl/main.go +++ b/cmd/edgeguard-ctl/main.go @@ -11,7 +11,7 @@ import ( "git.netcell-it.de/projekte/edgeguard-native/internal/services/setup" ) -var version = "1.1.82" +var version = "1.1.83" const usage = `edgeguard-ctl — EdgeGuard CLI diff --git a/cmd/edgeguard-scheduler/main.go b/cmd/edgeguard-scheduler/main.go index 2e25c96..16f093b 100644 --- a/cmd/edgeguard-scheduler/main.go +++ b/cmd/edgeguard-scheduler/main.go @@ -35,7 +35,7 @@ import ( "git.netcell-it.de/projekte/edgeguard-native/internal/services/tlscerts" ) -var version = "1.1.82" +var version = "1.1.83" const ( // renewTickInterval — how often we re-evaluate expiring certs. diff --git a/management-ui/src/i18n/locales/de/common.json b/management-ui/src/i18n/locales/de/common.json index 5a5c9d3..23bff95 100644 --- a/management-ui/src/i18n/locales/de/common.json +++ b/management-ui/src/i18n/locales/de/common.json @@ -105,6 +105,10 @@ "hits": "Hits", "add": "Regel hinzufügen", "edit": "Regel bearbeiten", "deleteConfirm": "Diese Regel wirklich löschen?", + "namePlaceholder": "z.B. SSH von Office erlauben", + "cidr": "CIDR", + "actions": { "accept": "ACCEPT", "drop": "DROP", "reject": "REJECT" }, + "kinds": { "any": "Beliebig", "object": "Objekt", "group": "Gruppe", "cidr": "CIDR" }, "emptyTitle": "Noch keine eigenen Firewall-Regeln.", "emptyDesc": "Die System-Regeln oben halten SSH (rate-limited), HTTPS :443 und Mgmt-UI :3443 immer offen (Anti-Lockout). Eigene Regeln für app-spezifische Inbound-Ports oder zonenübergreifende Forwards anlegen." }, @@ -119,6 +123,7 @@ "comment": "Kommentar", "add": "NAT-Regel hinzufügen", "edit": "NAT-Regel bearbeiten", "deleteConfirm": "Diese NAT-Regel wirklich löschen?", + "namePlaceholder": "z.B. HTTP zu Web-Backend weiterleiten", "emptyTitle": "Noch keine NAT-Regeln.", "emptyDesc": "DNAT (z. B. extern :2030 → intern 10.10.20.12:22 für SSH zu einem internen Host) oder SNAT/MASQUERADE (Internet-Zugang für ein internes Subnetz über die Box-IP)." }, diff --git a/management-ui/src/i18n/locales/en/common.json b/management-ui/src/i18n/locales/en/common.json index dcbe41c..fe4ff81 100644 --- a/management-ui/src/i18n/locales/en/common.json +++ b/management-ui/src/i18n/locales/en/common.json @@ -105,6 +105,10 @@ "hits": "Hits", "add": "Add rule", "edit": "Edit rule", "deleteConfirm": "Really delete this rule?", + "namePlaceholder": "e.g. Allow SSH from office", + "cidr": "CIDR", + "actions": { "accept": "ACCEPT", "drop": "DROP", "reject": "REJECT" }, + "kinds": { "any": "Any", "object": "Object", "group": "Group", "cidr": "CIDR" }, "emptyTitle": "No custom firewall rules yet.", "emptyDesc": "The system rules above keep SSH (rate-limited), HTTPS :443 and the mgmt UI :3443 open (anti-lockout). Add custom rules for app-specific inbound ports or cross-zone forwards." }, @@ -119,6 +123,7 @@ "comment": "Comment", "add": "Add NAT rule", "edit": "Edit NAT rule", "deleteConfirm": "Really delete this NAT rule?", + "namePlaceholder": "e.g. Forward HTTP to web backend", "emptyTitle": "No NAT rules yet.", "emptyDesc": "DNAT (e.g. external :2030 → internal 10.10.20.12:22 for SSH to an internal host) or SNAT/MASQUERADE (internet access for an internal subnet via the box IP)." }, diff --git a/management-ui/src/pages/Firewall/NATRules.tsx b/management-ui/src/pages/Firewall/NATRules.tsx index d01e57f..f1aac5b 100644 --- a/management-ui/src/pages/Firewall/NATRules.tsx +++ b/management-ui/src/pages/Firewall/NATRules.tsx @@ -69,6 +69,7 @@ export default function NATRulesTab() { message.success(t('common.save')); setCreating(false); form.resetFields() void qc.invalidateQueries({ queryKey: ['fw', 'nat'] }) }, + onError: (e: Error) => message.error(e.message), }) const update = useMutation({ mutationFn: async ({ id, v }: { id: number; v: FormValues }) => { await apiClient.put(`/firewall/nat-rules/${id}`, v) }, @@ -76,10 +77,12 @@ export default function NATRulesTab() { message.success(t('common.save')); setEditing(null); form.resetFields() void qc.invalidateQueries({ queryKey: ['fw', 'nat'] }) }, + onError: (e: Error) => message.error(e.message), }) const del = useMutation({ mutationFn: async (id: number) => { await apiClient.delete(`/firewall/nat-rules/${id}`) }, onSuccess: () => { void qc.invalidateQueries({ queryKey: ['fw', 'nat'] }) }, + onError: (e: Error) => message.error(e.message), }) const quickToggle = useMutation({ mutationFn: async ({ id, row, checked }: { id: number; row: NATRule; checked: boolean }) => { @@ -190,7 +193,7 @@ export default function NATRulesTab() { onFinish={(v) => { if (editing) update.mutate({ id: editing.id, v }); else create.mutate(v) }} > - + diff --git a/management-ui/src/pages/Firewall/Rules.tsx b/management-ui/src/pages/Firewall/Rules.tsx index b55beb6..f95b9f8 100644 --- a/management-ui/src/pages/Firewall/Rules.tsx +++ b/management-ui/src/pages/Firewall/Rules.tsx @@ -158,6 +158,7 @@ export default function RulesTab() { message.success(t('common.save')); setCreating(false); form.resetFields() void qc.invalidateQueries({ queryKey: ['fw', 'rules'] }) }, + onError: (e: Error) => message.error(e.message), }) const update = useMutation({ mutationFn: async ({ id, v }: { id: number; v: FormValues }) => { await apiClient.put(`/firewall/rules/${id}`, buildPayload(v)) }, @@ -165,10 +166,12 @@ export default function RulesTab() { message.success(t('common.save')); setEditing(null); form.resetFields() void qc.invalidateQueries({ queryKey: ['fw', 'rules'] }) }, + onError: (e: Error) => message.error(e.message), }) const del = useMutation({ mutationFn: async (id: number) => { await apiClient.delete(`/firewall/rules/${id}`) }, onSuccess: () => { void qc.invalidateQueries({ queryKey: ['fw', 'rules'] }) }, + onError: (e: Error) => message.error(e.message), }) const quickToggle = useMutation({ mutationFn: async ({ id, row, checked }: { id: number; row: FwRule; checked: boolean }) => { @@ -295,7 +298,7 @@ export default function RulesTab() { onFinish={(v) => { if (editing) update.mutate({ id: editing.id, v }); else create.mutate(v) }} > - + @@ -303,7 +306,7 @@ export default function RulesTab() { - ({ value: a, label: t(`fw.rule.actions.${a}`) }))} /> @@ -319,7 +322,7 @@ export default function RulesTab() { ({ value: k, label: k }))} /> + } @@ -349,7 +352,7 @@ export default function RulesTab() { - ({ value: k, label: t(`fw.rule.kinds.${k}`) }))} /> p.service_kind !== c.service_kind}> {({ getFieldValue }) => {