feat(waf): ausgeschlossene Regeln grün + Bereits-Ausnahme-Tag — v1.2.84
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1833,7 +1833,8 @@
|
||||
"noDomain": "Domain nicht gefunden — Ausnahme manuell konfigurieren.",
|
||||
"exceptionModalTitle": "Ausnahme für Regel {{rule}} hinzufügen",
|
||||
"exceptionModalHint": "Optional: Begründung warum diese Regel ein False Positive für diese Domain ist.",
|
||||
"exceptionNotePlaceholder": "z.B. Unsere API verwendet nicht-standardisierte Header die diese Regel auslösen."
|
||||
"exceptionNotePlaceholder": "z.B. Unsere API verwendet nicht-standardisierte Header die diese Regel auslösen.",
|
||||
"alreadyExcluded": "Bereits Ausnahme"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1833,7 +1833,8 @@
|
||||
"noDomain": "Domain not found — configure exception manually.",
|
||||
"exceptionModalTitle": "Add exception for rule {{rule}}",
|
||||
"exceptionModalHint": "Optional: describe why this rule is a false positive for this domain.",
|
||||
"exceptionNotePlaceholder": "e.g. Our custom API uses non-standard headers that trigger this rule."
|
||||
"exceptionNotePlaceholder": "e.g. Our custom API uses non-standard headers that trigger this rule.",
|
||||
"alreadyExcluded": "Already excluded"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -292,7 +292,7 @@ async function fetchAlerts(domainId?: number): Promise<WafAlert[]> {
|
||||
return (r.data.data as { alerts?: WafAlert[] }).alerts ?? []
|
||||
}
|
||||
|
||||
function AlertsTab({ domainId }: { domainId?: number }) {
|
||||
function AlertsTab({ domainId, configMap }: { domainId?: number; configMap: Map<number, WafConfig> }) {
|
||||
const { t } = useTranslation()
|
||||
const qc = useQueryClient()
|
||||
const isViewer = useAuthStore((s) => s.user?.role) === 'viewer'
|
||||
@@ -388,6 +388,15 @@ function AlertsTab({ domainId }: { domainId?: number }) {
|
||||
key: 'exception',
|
||||
width: 130,
|
||||
render: (_: unknown, row: WafAlert) => {
|
||||
const isExcluded = !!row.domain_id &&
|
||||
(configMap.get(row.domain_id)?.rule_exclusions ?? []).includes(String(row.rule_id))
|
||||
if (isExcluded) {
|
||||
return (
|
||||
<Tag color="success" icon={<CheckCircleOutlined />}>
|
||||
{t('waf.alerts.alreadyExcluded')}
|
||||
</Tag>
|
||||
)
|
||||
}
|
||||
const canExclude = !!row.domain_id && row.rule_id > 0 && !isViewer
|
||||
return (
|
||||
<Tooltip title={!row.domain_id ? t('waf.alerts.noDomain') : undefined}>
|
||||
@@ -432,9 +441,13 @@ function AlertsTab({ domainId }: { domainId?: number }) {
|
||||
loading={isLoading}
|
||||
dataSource={alerts ?? []}
|
||||
columns={columns}
|
||||
rowClassName={(row: WafAlert) =>
|
||||
row.action === 'blocked' ? 'fw-rule-row--zero-hit' : ''
|
||||
}
|
||||
rowClassName={(row: WafAlert) => {
|
||||
const isExcluded = !!row.domain_id &&
|
||||
(configMap.get(row.domain_id)?.rule_exclusions ?? []).includes(String(row.rule_id))
|
||||
if (isExcluded) return 'waf-alert-row--excluded'
|
||||
if (row.action === 'blocked') return 'fw-rule-row--zero-hit'
|
||||
return ''
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -642,7 +655,7 @@ export default function WAFPage() {
|
||||
{
|
||||
key: 'alerts',
|
||||
label: t('waf.tabs.alerts'),
|
||||
children: <AlertsTab />,
|
||||
children: <AlertsTab configMap={configMap} />,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
@@ -3057,6 +3057,15 @@ h1, h2, h3, h4, h5, h6 {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
/* ── WAF Alert rows ──────────────────────────────────────────────────── */
|
||||
.waf-alert-row--excluded > td {
|
||||
background: #F0FDF4 !important;
|
||||
color: #15803D !important;
|
||||
}
|
||||
.waf-alert-row--excluded:hover > td {
|
||||
background: #DCFCE7 !important;
|
||||
}
|
||||
|
||||
/* ── Firewall Filter-Bar ─────────────────────────────────────────────── */
|
||||
.fw-filter-bar {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user