fix(campaigns): fix IP navigation URL encoding

fmtIP() returns an HTML <a> tag string. Using encodeURIComponent(fmtIP(ip))
was URL-encoding the entire HTML markup instead of the raw IP address,
resulting in /ip/%3Ca%20href%3D... navigation.

Fix: extract raw IP (stripping ::ffff: prefix) before building the URL.
Applied to all 3 click handlers in campaigns.html:
- members table row onclick
- scatter chart point click
- force graph node click

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
toto
2026-04-10 01:08:53 +02:00
parent 7a04e47041
commit 92432085e2

View File

@ -362,7 +362,7 @@ function renderScatter() {
onClick: (e, els) => { onClick: (e, els) => {
if (els.length) { if (els.length) {
const m = els[0].element.$context.raw._meta; const m = els[0].element.$context.raw._meta;
window.location.href = `/ip/${encodeURIComponent(fmtIP(m.ip))}`; window.location.href = `/ip/${encodeURIComponent(String(m.ip||'').replace('::ffff:',''))}`;
} }
}, },
}, },
@ -488,7 +488,7 @@ function renderGraph() {
const rect = canvas.getBoundingClientRect(); const rect = canvas.getBoundingClientRect();
const mx = e.clientX - rect.left, my = e.clientY - rect.top; const mx = e.clientX - rect.left, my = e.clientY - rect.top;
const hit = nodes.find(n => Math.hypot(n.x-mx, n.y-my) <= n.radius+2); const hit = nodes.find(n => Math.hypot(n.x-mx, n.y-my) <= n.radius+2);
if (hit) window.location.href = `/ip/${encodeURIComponent(fmtIP(hit.id))}`; if (hit) window.location.href = `/ip/${encodeURIComponent(String(hit.id||'').replace('::ffff:',''))}`;
}); });
canvas.style.cursor = 'default'; canvas.style.cursor = 'default';
canvas.addEventListener('mousemove', e => { canvas.addEventListener('mousemove', e => {
@ -561,8 +561,10 @@ async function selectCampaign(cid) {
document.getElementById('member-count').textContent = `(${members.length})`; document.getElementById('member-count').textContent = `(${members.length})`;
// Members table // Members table
document.getElementById('members-body').innerHTML = members.map(m => ` document.getElementById('members-body').innerHTML = members.map(m => {
<tr class="hover:bg-gray-800/40 cursor-pointer" onclick="window.location='/ip/${encodeURIComponent(fmtIP(m.src_ip))}'"> const rawIP = String(m.src_ip||'').replace('::ffff:','');
return `
<tr class="hover:bg-gray-800/40 cursor-pointer" onclick="window.location='/ip/${encodeURIComponent(rawIP)}'">
<td class="px-3 py-2 font-mono text-purple-300">${fmtIP(m.src_ip)}</td> <td class="px-3 py-2 font-mono text-purple-300">${fmtIP(m.src_ip)}</td>
<td class="px-3 py-2 font-mono text-[10px] text-gray-400 max-w-[140px] truncate">${escapeHtml(m.ja4||'')}</td> <td class="px-3 py-2 font-mono text-[10px] text-gray-400 max-w-[140px] truncate">${escapeHtml(m.ja4||'')}</td>
<td class="px-3 py-2 text-gray-300">${escapeHtml(m.host||'')}</td> <td class="px-3 py-2 text-gray-300">${escapeHtml(m.host||'')}</td>
@ -574,7 +576,8 @@ async function selectCampaign(cid) {
<td class="px-3 py-2">${fmtCountry(m.country_code)}</td> <td class="px-3 py-2">${fmtCountry(m.country_code)}</td>
<td class="px-3 py-2 text-gray-500 text-[10px]">${m.detected_at||''}</td> <td class="px-3 py-2 text-gray-500 text-[10px]">${m.detected_at||''}</td>
</tr> </tr>
`).join('') || '<tr><td colspan="10" class="text-center py-6 text-gray-500">Aucun membre</td></tr>'; `;
}).join('') || '<tr><td colspan="10" class="text-center py-6 text-gray-500">Aucun membre</td></tr>';
// Radar chart // Radar chart
renderRadar(p); renderRadar(p);