feat(dashboard): add JA4 fingerprint and cluster investigation pages

- /ja4/{fingerprint} page: 8 KPIs, timeline, threat pie, IP scores
  table, ASN/geo charts, HTTP logs, AI features — full JA4 investigation
- /cluster/{cid} page: 8 KPIs, timeline, threat/JA4/ASN/host charts,
  member table with bulk classify — full campaign investigation
- /api/ja4/{fingerprint} and /api/cluster/{cid} API endpoints
- fmtJA4 links now navigate to /ja4/ investigation page
- campaigns.html: 'Ouvrir' button links to /cluster/{cid} full page
- Fix: double-brace {{param}} in non-f-string queries → single {param}
  (was causing HTTP 500 on all parameterized ClickHouse queries)
- 50 routes total, all tests pass, 0 JS console errors

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
toto
2026-04-09 14:05:52 +02:00
parent 70188b508c
commit 702c0d5edb
6 changed files with 778 additions and 5 deletions

View File

@ -291,11 +291,11 @@
}
function fmtJA4(ja4) {
if (!ja4) return '';
return `<a href="/detections?ja4=${encodeURIComponent(ja4)}" onclick="event.stopPropagation()" class="text-purple-400 hover:underline cursor-pointer font-mono text-[11px]" title="${escapeHtml(ja4)}">${escapeHtml(ja4.substring(0,22))}…</a>`;
return `<a href="/ja4/${encodeURIComponent(ja4)}" onclick="event.stopPropagation()" class="text-purple-400 hover:underline cursor-pointer font-mono text-[11px]" title="${escapeHtml(ja4)}">${escapeHtml(ja4.substring(0,22))}…</a>`;
}
function fmtJA4Full(ja4) {
if (!ja4) return '';
return `<a href="/detections?ja4=${encodeURIComponent(ja4)}" onclick="event.stopPropagation()" class="text-purple-400 hover:underline cursor-pointer font-mono text-[11px]">${escapeHtml(ja4)}</a>`;
return `<a href="/ja4/${encodeURIComponent(ja4)}" onclick="event.stopPropagation()" class="text-purple-400 hover:underline cursor-pointer font-mono text-[11px]">${escapeHtml(ja4)}</a>`;
}
function fmtBotName(name) {
if (!name) return '';