<?php ?> <script nonce="<?= $cspNonce ?> "> (function(){ var panel = document.getElementById('panel-wd-threats'); if(!panel) return; panel.innerHTML = '<div class="wd-toolbar">' + '<select id="wd-threat-sev" class="form-select"><option value="">All Severity</option><option value="critical">Critical</option><option value="high">High</option><option value="medium">Medium</option><option value="low">Low</option></select>' + '<select id="wd-threat-type" class="form-select"><option value="">All Types</option><option value="sql_injection">SQLi</option><option value="xss_attempt">XSS</option><option value="bot_detected">Bot</option><option value="devtools_opened">DevTools</option><option value="screenshot_detected">Screenshot</option><option value="source_code_viewed">Source View</option><option value="inhuman_typing">Inhuman Typing</option><option value="inhuman_mouse">Inhuman Mouse</option><option value="bulk_copy">Bulk Copy</option></select>' + '<button id="wd-threat-refresh" class="btn btn-sm">Refresh</button>' + '</div>' + '<div class="wd-stats-row" id="wd-threat-stats"></div>' + '<table class="wd-table" id="wd-threat-table"><thead><tr><th>Time</th><th>Severity</th><th>Type</th><th>IP</th><th>Detail</th><th>Actions</th></tr></thead><tbody id="wd-threat-tbody"></tbody></table>'; var tbody = document.getElementById('wd-threat-tbody'); function loadThreats(){ var sev = document.getElementById('wd-threat-sev').value; var type = document.getElementById('wd-threat-type').value; fetch('api/system/pulse.php?scope=watchdog_threats&severity='+sev+'&type='+type+'&_t='+Date.now(), {credentials:'same-origin'}) .then(function(r){return r.json()}) .then(function(d){ if(d.stats){ document.getElementById('wd-threat-stats').innerHTML = '<div class="wd-stat-card wd-critical">'+d.stats.critical+' Critical</div>' + '<div class="wd-stat-card wd-high">'+d.stats.high+' High</div>' + '<div class="wd-stat-card wd-medium">'+d.stats.medium+' Medium</div>' + '<div class="wd-stat-card wd-low">'+d.stats.low+' Low</div>'; } tbody.innerHTML = ''; if(!d.flags) return; d.flags.forEach(function(f){ var tr = document.createElement('tr'); tr.innerHTML = '<td>'+f.time+'</td>' + '<td><span class="wd-badge wd-'+f.severity+'">'+f.severity+'</span></td>' + '<td>'+f.type+'</td>' + '<td>'+f.ip+'</td>' + '<td>'+f.details+'</td>' + '<td><button class="btn btn-xs btn-danger wd-flag-block" data-vid="'+f.vid+'" data-ip="'+f.ip+'">Block</button> <button class="btn btn-xs wd-flag-resolve" data-id="'+f.id+'">Resolve</button></td>'; tbody.appendChild(tr); }); bindFlagActions(); }).catch(function(){}); } function bindFlagActions(){ tbody.querySelectorAll('.wd-flag-block').forEach(function(b){ b.addEventListener('click', function(){ if(!confirm('Block IP '+b.dataset.ip+'?')) return; var fd = new FormData(); fd.append('_csrf', window._csrf||''); fd.append('action', 'watchdog_block'); fd.append('visitor_id', b.dataset.vid); fetch('system/verify.php', {method:'POST', body:fd, credentials:'same-origin'}) .then(function(r){return r.json()}).then(function(d){ alert(d.ok?'Blocked':'Failed'); loadThreats(); }); }); }); tbody.querySelectorAll('.wd-flag-resolve').forEach(function(b){ b.addEventListener('click', function(){ var fd = new FormData(); fd.append('_csrf', window._csrf||''); fd.append('action', 'watchdog_resolve_flag'); fd.append('flag_id', b.dataset.id); fetch('system/verify.php', {method:'POST', body:fd, credentials:'same-origin'}) .then(function(r){return r.json()}).then(function(d){ if(d.ok) loadThreats(); }); }); }); } document.getElementById('wd-threat-refresh').addEventListener('click', loadThreats); document.getElementById('wd-threat-sev').addEventListener('change', loadThreats); document.getElementById('wd-threat-type').addEventListener('change', loadThreats); loadThreats(); })(); </script>