feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
<!DOCTYPE html>
|
2026-03-09 20:34:35 +01:00
|
|
|
<html lang="en" id="html-root">
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
<title>HONEYPOT // NETWORK MONITOR</title>
|
|
|
|
|
<style>
|
|
|
|
|
:root {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
--bg: #000a00;
|
|
|
|
|
--bg2: #010f01;
|
|
|
|
|
--green: #00ff41;
|
|
|
|
|
--green2: #00dd44;
|
|
|
|
|
--dim: #44bb77; /* was #006600 — now legible secondary text */
|
|
|
|
|
--dim2: #228844; /* slightly darker secondary for non-critical labels */
|
|
|
|
|
--muted: #002800; /* backgrounds only */
|
|
|
|
|
--border: #003a00;
|
|
|
|
|
--red: #ff4040;
|
|
|
|
|
--amber: #ffaa00;
|
|
|
|
|
--white: #d4ffd4;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
html { scrollbar-color: var(--dim2) var(--bg); scrollbar-width: thin; }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
|
|
|
|
|
body {
|
|
|
|
|
background: var(--bg);
|
|
|
|
|
color: var(--green);
|
|
|
|
|
font-family: 'Courier New', 'Lucida Console', monospace;
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
line-height: 1.5;
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
height: 100vh;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
overflow: hidden;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* CRT scanline overlay */
|
|
|
|
|
body::after {
|
|
|
|
|
content: '';
|
|
|
|
|
position: fixed;
|
|
|
|
|
inset: 0;
|
|
|
|
|
background: repeating-linear-gradient(
|
|
|
|
|
0deg, transparent, transparent 2px,
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
rgba(0,0,0,.06) 2px, rgba(0,0,0,.06) 4px
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
);
|
|
|
|
|
pointer-events: none;
|
|
|
|
|
z-index: 9999;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.glow { text-shadow: 0 0 12px var(--green), 0 0 24px var(--green); }
|
|
|
|
|
.glow-sm { text-shadow: 0 0 6px var(--green); }
|
|
|
|
|
|
|
|
|
|
/* ── Header ─────────────────────────────────────────────────────────── */
|
|
|
|
|
header {
|
|
|
|
|
border-bottom: 1px solid var(--border);
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
padding: 8px 20px;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
background: var(--bg2);
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
flex-shrink: 0;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
flex-wrap: wrap;
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
gap: 6px;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.logo {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
font-size: 16px;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
font-weight: bold;
|
|
|
|
|
letter-spacing: 4px;
|
|
|
|
|
color: var(--green);
|
|
|
|
|
}
|
|
|
|
|
.logo em { color: var(--amber); font-style: normal; }
|
|
|
|
|
|
|
|
|
|
.header-right {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
gap: 14px;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
font-size: 11px;
|
|
|
|
|
color: var(--green2);
|
|
|
|
|
letter-spacing: 1px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.live-dot {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
width: 8px; height: 8px;
|
|
|
|
|
background: var(--red);
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
animation: blink 1s step-end infinite;
|
|
|
|
|
box-shadow: 0 0 6px var(--red);
|
|
|
|
|
vertical-align: middle;
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
margin-right: 4px;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes blink { 50% { opacity: 0; } }
|
|
|
|
|
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
.lang-switcher { display: flex; gap: 3px; align-items: center; }
|
2026-03-09 20:34:35 +01:00
|
|
|
.lang-btn {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
background: none; border: none; cursor: pointer;
|
|
|
|
|
padding: 1px 2px; line-height: 1;
|
2026-03-09 20:34:35 +01:00
|
|
|
transition: opacity .15s, font-size .15s;
|
|
|
|
|
}
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
.lang-btn.active { font-size: 20px; opacity: 1; }
|
|
|
|
|
.lang-btn.inactive { font-size: 14px; opacity: 0.35; }
|
2026-03-09 20:34:35 +01:00
|
|
|
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
/* ── Main ───────────────────────────────────────────────────────────── */
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
main {
|
|
|
|
|
flex: 1;
|
|
|
|
|
min-height: 0;
|
|
|
|
|
padding: 10px 14px;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
|
|
|
|
|
/* ── Stat cards ─────────────────────────────────────────────────────── */
|
|
|
|
|
.stats-row {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(5, 1fr);
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
gap: 8px;
|
|
|
|
|
flex-shrink: 0;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.stat-card {
|
|
|
|
|
background: var(--bg2);
|
|
|
|
|
border: 1px solid var(--border);
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
padding: 10px 10px 8px;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
text-align: center;
|
|
|
|
|
position: relative;
|
|
|
|
|
transition: border-color .2s;
|
|
|
|
|
}
|
|
|
|
|
.stat-card::before {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
content: ''; position: absolute;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
top: 0; left: 0; right: 0; height: 2px;
|
|
|
|
|
background: var(--muted);
|
|
|
|
|
transition: background .2s, box-shadow .2s;
|
|
|
|
|
}
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
.stat-card:hover { border-color: var(--dim2); }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
.stat-card:hover::before { background: var(--green); box-shadow: 0 0 8px var(--green); }
|
|
|
|
|
|
|
|
|
|
.stat-num {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
font-size: 26px; font-weight: bold;
|
|
|
|
|
letter-spacing: 2px; line-height: 1.1;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
color: var(--green);
|
|
|
|
|
}
|
|
|
|
|
.stat-lbl {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
font-size: 9px; letter-spacing: 2px;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
text-transform: uppercase;
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
color: var(--dim);
|
|
|
|
|
margin-top: 3px;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
|
|
|
|
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
/* ── Top target banner ──────────────────────────────────────────────── */
|
|
|
|
|
#top-target {
|
|
|
|
|
background: var(--bg2);
|
|
|
|
|
border: 1px solid #2a0000;
|
|
|
|
|
border-left: 3px solid var(--red);
|
|
|
|
|
padding: 7px 14px;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 14px;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
}
|
|
|
|
|
#top-target .tt-label { font-size: 10px; letter-spacing: 2px; color: var(--dim2); }
|
|
|
|
|
#top-target .tt-form { font-size: 14px; font-weight: bold; color: var(--red); text-shadow: 0 0 10px var(--red); }
|
|
|
|
|
#top-target .tt-hits { font-size: 11px; color: var(--amber); }
|
|
|
|
|
#top-target .tt-pct { font-size: 11px; color: var(--dim); }
|
|
|
|
|
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
/* ── Content grid ───────────────────────────────────────────────────── */
|
|
|
|
|
.content-grid {
|
|
|
|
|
display: grid;
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
grid-template-columns: 1fr 420px;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
flex: 1;
|
|
|
|
|
min-height: 0;
|
|
|
|
|
overflow: hidden;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
|
|
|
|
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
/* ── Left column ────────────────────────────────────────────────────── */
|
|
|
|
|
.left-col {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
min-height: 0;
|
|
|
|
|
}
|
|
|
|
|
.left-col::-webkit-scrollbar { width: 3px; }
|
|
|
|
|
.left-col::-webkit-scrollbar-track { background: var(--bg); }
|
|
|
|
|
.left-col::-webkit-scrollbar-thumb { background: var(--dim2); }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
/* ── Right column ───────────────────────────────────────────────────── */
|
|
|
|
|
.right-col {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
min-height: 0;
|
|
|
|
|
overflow: hidden;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
|
|
|
|
|
/* ── Panel ──────────────────────────────────────────────────────────── */
|
|
|
|
|
.panel { background: var(--bg2); border: 1px solid var(--border); }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
.panel-hdr {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
padding: 6px 12px;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
border-bottom: 1px solid var(--border);
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
font-size: 10px; letter-spacing: 2px;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
color: var(--amber);
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
display: flex; align-items: center; justify-content: space-between;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
.panel-body { padding: 10px 12px; }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
|
|
|
|
|
/* ── 24h Chart ──────────────────────────────────────────────────────── */
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
#chart { width: 100%; height: 72px; display: block; }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
|
|
|
|
|
/* ── Bar lists ──────────────────────────────────────────────────────── */
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
.bars-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
|
|
|
|
|
.bar-section-title { font-size: 10px; letter-spacing: 2px; color: var(--amber); margin-bottom: 6px; }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
.bar-list { list-style: none; }
|
|
|
|
|
.bar-item {
|
|
|
|
|
display: grid;
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
grid-template-columns: 140px 1fr 50px;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
align-items: center;
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
gap: 6px; padding: 2px 0; font-size: 11px;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
.bar-lbl { color: var(--white); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
|
|
|
.bar-track { background: var(--muted); height: 6px; }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
.bar-fill { background: var(--green); height: 100%; transition: width .5s ease; }
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
.bar-cnt { color: var(--dim); font-size: 11px; text-align: right; }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
|
|
|
|
|
/* ── Live feed ──────────────────────────────────────────────────────── */
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
.feed-panel {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
flex: 1;
|
|
|
|
|
min-height: 0;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
|
|
|
|
|
#feed {
|
|
|
|
|
flex: 1;
|
|
|
|
|
overflow-y: auto;
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
padding: 6px 12px;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
font-size: 11px;
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
line-height: 1.6;
|
|
|
|
|
min-height: 0;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
|
|
|
|
#feed::-webkit-scrollbar { width: 3px; }
|
|
|
|
|
#feed::-webkit-scrollbar-track { background: var(--bg); }
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
#feed::-webkit-scrollbar-thumb { background: var(--dim2); }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
|
|
|
|
|
.feed-row {
|
|
|
|
|
display: grid;
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
grid-template-columns: 58px 110px auto;
|
|
|
|
|
gap: 5px;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
border-bottom: 1px solid var(--muted);
|
|
|
|
|
padding: 1px 0;
|
|
|
|
|
align-items: start;
|
|
|
|
|
}
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
.feed-ts { color: var(--dim2); }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
.feed-ip { color: var(--amber); }
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
.feed-geo { color: var(--dim); font-size: 10px; }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
.feed-form { color: var(--green2); }
|
|
|
|
|
.feed-reason { color: var(--dim); font-size: 10px; }
|
|
|
|
|
|
|
|
|
|
.feed-footer {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
padding: 5px 12px;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
border-top: 1px solid var(--border);
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
font-size: 10px; color: var(--dim);
|
|
|
|
|
display: flex; justify-content: space-between;
|
|
|
|
|
flex-shrink: 0;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
|
|
|
|
.cursor::after { content: '█'; animation: blink 1s step-end infinite; }
|
|
|
|
|
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
/* ── Attackers (compact, in right col) ──────────────────────────────── */
|
|
|
|
|
.atk-panel {
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
max-height: 260px;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
overflow: hidden;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
.atk-scroll { overflow-y: auto; flex: 1; }
|
|
|
|
|
.atk-scroll::-webkit-scrollbar { width: 3px; }
|
|
|
|
|
.atk-scroll::-webkit-scrollbar-track { background: var(--bg); }
|
|
|
|
|
.atk-scroll::-webkit-scrollbar-thumb { background: var(--dim2); }
|
|
|
|
|
|
|
|
|
|
.atk-table { width: 100%; border-collapse: collapse; font-size: 11px; }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
.atk-table th {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
padding: 5px 10px;
|
|
|
|
|
text-align: left; color: var(--amber);
|
|
|
|
|
font-size: 9px; letter-spacing: 2px;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
border-bottom: 1px solid var(--border);
|
|
|
|
|
white-space: nowrap;
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
position: sticky; top: 0; background: var(--bg2);
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
.atk-table td { padding: 4px 10px; border-bottom: 1px solid var(--muted); }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
.atk-table tr:hover td { background: var(--muted); }
|
|
|
|
|
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
.atk-rank { color: var(--dim2); font-size: 10px; }
|
|
|
|
|
.atk-ip { color: var(--amber); font-weight: bold; }
|
|
|
|
|
.atk-hits { color: var(--green); font-weight: bold; }
|
|
|
|
|
.atk-asn { color: var(--dim); font-size: 10px; max-width: 90px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
.mini-bar { height: 6px; background: var(--muted); min-width: 40px; width: 100%; }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
.mini-fill { background: var(--green); height: 100%; box-shadow: 0 0 4px var(--green); transition: width .5s; }
|
|
|
|
|
|
|
|
|
|
/* ── Footer ─────────────────────────────────────────────────────────── */
|
|
|
|
|
footer {
|
|
|
|
|
border-top: 1px solid var(--border);
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
padding: 6px 20px;
|
|
|
|
|
font-size: 10px; color: var(--dim2);
|
|
|
|
|
display: flex; justify-content: space-between; align-items: center;
|
|
|
|
|
letter-spacing: 1px; flex-shrink: 0; flex-wrap: wrap; gap: 4px;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
2026-03-09 20:34:35 +01:00
|
|
|
footer a { color: var(--dim); text-decoration: none; }
|
|
|
|
|
footer a:hover { color: var(--green2); }
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
.footer-eu { display: flex; align-items: center; gap: 5px; }
|
2026-03-09 19:26:23 +01:00
|
|
|
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
/* ── Responsive ─────────────────────────────────────────────────────── */
|
|
|
|
|
@media (max-width: 1100px) {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
body { overflow: auto; height: auto; }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
.stats-row { grid-template-columns: repeat(3, 1fr); }
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
.content-grid { grid-template-columns: 1fr; height: auto; }
|
|
|
|
|
.left-col { overflow: visible; }
|
|
|
|
|
.right-col { height: 700px; }
|
|
|
|
|
.feed-panel { flex: 1; }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
|
|
|
|
@media (max-width: 640px) {
|
|
|
|
|
.stats-row { grid-template-columns: 1fr 1fr; }
|
|
|
|
|
.bars-2col { grid-template-columns: 1fr; }
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
.bar-item { grid-template-columns: 100px 1fr 42px; }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
|
|
|
|
|
<header>
|
|
|
|
|
<div class="logo glow">[HONEYPOT<em>]</em> // NETWORK THREAT INTELLIGENCE</div>
|
|
|
|
|
<div class="header-right">
|
|
|
|
|
<span id="clock">--:--:--</span>
|
2026-03-09 20:34:35 +01:00
|
|
|
<span><span class="live-dot"></span><span data-i18n="live_feed">LIVE FEED</span></span>
|
|
|
|
|
<div class="lang-switcher">
|
|
|
|
|
<button class="lang-btn" data-lang="en" onclick="setLang('en')" title="English">🇬🇧</button>
|
|
|
|
|
<button class="lang-btn" data-lang="es" onclick="setLang('es')" title="Español">🇪🇸</button>
|
|
|
|
|
<button class="lang-btn" data-lang="ro" onclick="setLang('ro')" title="Română">🇷🇴</button>
|
|
|
|
|
</div>
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
</div>
|
|
|
|
|
</header>
|
|
|
|
|
|
|
|
|
|
<main>
|
|
|
|
|
|
|
|
|
|
<div class="stats-row">
|
|
|
|
|
<div class="stat-card">
|
|
|
|
|
<div class="stat-num glow" id="s-total">…</div>
|
2026-03-09 20:34:35 +01:00
|
|
|
<div class="stat-lbl" data-i18n="stat_total">TOTAL BLOCKED</div>
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
</div>
|
|
|
|
|
<div class="stat-card">
|
|
|
|
|
<div class="stat-num glow" id="s-today">…</div>
|
2026-03-09 20:34:35 +01:00
|
|
|
<div class="stat-lbl" data-i18n="stat_today">TODAY</div>
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
</div>
|
|
|
|
|
<div class="stat-card">
|
|
|
|
|
<div class="stat-num" id="s-7d">…</div>
|
2026-03-09 20:34:35 +01:00
|
|
|
<div class="stat-lbl" data-i18n="stat_7d">LAST 7 DAYS</div>
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
</div>
|
|
|
|
|
<div class="stat-card">
|
|
|
|
|
<div class="stat-num" id="s-30d">…</div>
|
2026-03-09 20:34:35 +01:00
|
|
|
<div class="stat-lbl" data-i18n="stat_30d">LAST 30 DAYS</div>
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
</div>
|
|
|
|
|
<div class="stat-card">
|
|
|
|
|
<div class="stat-num glow" id="s-sites">…</div>
|
2026-03-09 20:34:35 +01:00
|
|
|
<div class="stat-lbl" data-i18n="stat_sites">SITES REPORTING</div>
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-03-09 19:26:23 +01:00
|
|
|
<div id="top-target">
|
2026-03-09 20:34:35 +01:00
|
|
|
<span class="tt-label" id="tt-label" data-i18n="top_target_label">▶ MOST ATTACKED FORM (30D):</span>
|
2026-03-09 19:26:23 +01:00
|
|
|
<span class="tt-form" id="tt-form">—</span>
|
|
|
|
|
<span class="tt-hits" id="tt-hits"></span>
|
2026-03-09 20:34:35 +01:00
|
|
|
<span class="tt-pct" id="tt-pct"></span>
|
2026-03-09 19:26:23 +01:00
|
|
|
</div>
|
|
|
|
|
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
<div class="content-grid">
|
|
|
|
|
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
<!-- Left: charts & bars -->
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
<div class="left-col">
|
|
|
|
|
|
|
|
|
|
<div class="panel">
|
|
|
|
|
<div class="panel-hdr">
|
2026-03-09 20:34:35 +01:00
|
|
|
<span data-i18n="chart_title">▶ 24H ACTIVITY TREND</span>
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
<span id="chart-peak" style="color:var(--dim);font-size:11px"></span>
|
|
|
|
|
</div>
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
<div class="panel-body" style="padding:8px 10px">
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
<canvas id="chart"></canvas>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="panel">
|
2026-03-09 20:34:35 +01:00
|
|
|
<div class="panel-hdr" data-i18n="breakdown_title">▶ ATTACK BREAKDOWN // LAST 30 DAYS</div>
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
<div class="panel-body">
|
|
|
|
|
<div class="bars-2col">
|
|
|
|
|
<div>
|
2026-03-09 20:34:35 +01:00
|
|
|
<div class="bar-section-title" data-i18n="form_types">FORM TYPES</div>
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
<ul class="bar-list" id="bars-forms"></ul>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
2026-03-09 20:34:35 +01:00
|
|
|
<div class="bar-section-title" data-i18n="bot_toolkit">BOT TOOLKIT</div>
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
<ul class="bar-list" id="bars-ua"></ul>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="panel">
|
2026-03-09 20:34:35 +01:00
|
|
|
<div class="panel-hdr" data-i18n="reasons_title">▶ BLOCK REASONS // LAST 30 DAYS</div>
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
<div class="panel-body">
|
|
|
|
|
<ul class="bar-list" id="bars-reasons"></ul>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div><!-- /.left-col -->
|
|
|
|
|
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
<!-- Right: live feed + top attackers -->
|
|
|
|
|
<div class="right-col">
|
|
|
|
|
|
|
|
|
|
<div class="panel feed-panel">
|
|
|
|
|
<div class="panel-hdr">
|
|
|
|
|
<span data-i18n="feed_title">▶ LIVE THREAT FEED</span>
|
|
|
|
|
<span id="feed-count" style="color:var(--dim);font-size:11px">0 <span data-i18n="events">events</span></span>
|
|
|
|
|
</div>
|
|
|
|
|
<div id="feed"></div>
|
|
|
|
|
<div class="feed-footer">
|
|
|
|
|
<span class="cursor"></span>
|
|
|
|
|
<span id="feed-status" data-i18n="connecting">connecting…</span>
|
|
|
|
|
</div>
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
</div>
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
|
|
|
|
|
<div class="panel atk-panel">
|
|
|
|
|
<div class="panel-hdr" data-i18n="attackers_title">▶ TOP ATTACKERS // LAST 30 DAYS</div>
|
|
|
|
|
<div class="atk-scroll">
|
|
|
|
|
<table class="atk-table">
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th>#</th>
|
|
|
|
|
<th data-i18n="col_ip">IP ADDRESS</th>
|
|
|
|
|
<th data-i18n="col_hits">HITS</th>
|
|
|
|
|
<th data-i18n="col_asn">AS</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody id="atk-body">
|
|
|
|
|
<tr><td colspan="4" style="text-align:center;padding:14px;color:var(--dim)" data-i18n="loading">Loading…</td></tr>
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</div>
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
</div>
|
|
|
|
|
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
</div><!-- /.right-col -->
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
</div><!-- /.content-grid -->
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
|
|
|
|
|
</main>
|
|
|
|
|
|
|
|
|
|
<footer>
|
2026-03-09 20:34:35 +01:00
|
|
|
<span data-i18n="footer_copy">HONEYPOT NETWORK MONITOR // CENTRALIZED THREAT INTELLIGENCE</span>
|
|
|
|
|
<div class="footer-eu">
|
|
|
|
|
<span data-i18n="made_in_eu">🇪🇺 Made & hosted in the EU by</span>
|
|
|
|
|
<a href="https://cloudhost.es" target="_blank" rel="noopener">Cloud Host</a>
|
|
|
|
|
|
|
|
|
|
|
<span data-i18n="refreshed">REFRESHED:</span> <span id="last-update">--</span>
|
|
|
|
|
</div>
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
</footer>
|
|
|
|
|
|
|
|
|
|
<script>
|
2026-03-09 20:34:35 +01:00
|
|
|
// ── i18n ──────────────────────────────────────────────────────────────────────
|
|
|
|
|
const I18N = {
|
|
|
|
|
en: {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
live_feed: 'LIVE FEED', stat_total: 'TOTAL BLOCKED', stat_today: 'TODAY',
|
|
|
|
|
stat_7d: 'LAST 7 DAYS', stat_30d: 'LAST 30 DAYS', stat_sites: 'SITES REPORTING',
|
2026-03-09 20:34:35 +01:00
|
|
|
top_target_label: '▶ MOST ATTACKED FORM (30D):',
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
chart_title: '▶ 24H ACTIVITY TREND',
|
|
|
|
|
breakdown_title: '▶ ATTACK BREAKDOWN // LAST 30 DAYS',
|
|
|
|
|
form_types: 'FORM TYPES', bot_toolkit: 'BOT TOOLKIT',
|
|
|
|
|
reasons_title: '▶ BLOCK REASONS // LAST 30 DAYS',
|
|
|
|
|
feed_title: '▶ LIVE THREAT FEED', events: 'events',
|
|
|
|
|
connecting: 'connecting…', connected: 'connected', reconnecting: 'reconnecting…',
|
|
|
|
|
attackers_title: '▶ TOP ATTACKERS // LAST 30 DAYS',
|
|
|
|
|
col_ip: 'IP ADDRESS', col_hits: 'HITS', col_asn: 'AS',
|
|
|
|
|
loading: 'Loading…', no_data: 'No data yet',
|
|
|
|
|
footer_copy: 'HONEYPOT NETWORK MONITOR // CENTRALIZED THREAT INTELLIGENCE',
|
|
|
|
|
refreshed: 'REFRESHED:', made_in_eu: '🇪🇺 Made & hosted in the EU by',
|
2026-03-09 20:34:35 +01:00
|
|
|
},
|
|
|
|
|
es: {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
live_feed: 'EN VIVO', stat_total: 'TOTAL BLOQUEADOS', stat_today: 'HOY',
|
|
|
|
|
stat_7d: 'ÚLTIMOS 7 DÍAS', stat_30d: 'ÚLTIMOS 30 DÍAS', stat_sites: 'SITIOS REPORTANDO',
|
2026-03-09 20:34:35 +01:00
|
|
|
top_target_label: '▶ FORMULARIO MÁS ATACADO (30D):',
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
chart_title: '▶ TENDENCIA 24H',
|
|
|
|
|
breakdown_title: '▶ DESGLOSE DE ATAQUES // ÚLTIMOS 30 DÍAS',
|
|
|
|
|
form_types: 'TIPOS DE FORMULARIO', bot_toolkit: 'HERRAMIENTAS BOT',
|
|
|
|
|
reasons_title: '▶ MOTIVOS DE BLOQUEO // ÚLTIMOS 30 DÍAS',
|
|
|
|
|
feed_title: '▶ FEED EN VIVO', events: 'eventos',
|
|
|
|
|
connecting: 'conectando…', connected: 'conectado', reconnecting: 'reconectando…',
|
|
|
|
|
attackers_title: '▶ TOP ATACANTES // ÚLTIMOS 30 DÍAS',
|
|
|
|
|
col_ip: 'DIRECCIÓN IP', col_hits: 'IMPACTOS', col_asn: 'AS',
|
|
|
|
|
loading: 'Cargando…', no_data: 'Sin datos aún',
|
|
|
|
|
footer_copy: 'MONITOR HONEYPOT // INTELIGENCIA CENTRALIZADA DE AMENAZAS',
|
|
|
|
|
refreshed: 'ACTUALIZADO:', made_in_eu: '🇪🇺 Hecho y alojado en la UE por',
|
2026-03-09 20:34:35 +01:00
|
|
|
},
|
|
|
|
|
ro: {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
live_feed: 'LIVE', stat_total: 'TOTAL BLOCATE', stat_today: 'AZI',
|
|
|
|
|
stat_7d: 'ULTIMELE 7 ZILE', stat_30d: 'ULTIMELE 30 ZILE', stat_sites: 'SITE-URI RAPORTÂND',
|
2026-03-09 20:34:35 +01:00
|
|
|
top_target_label: '▶ FORMULARUL CEL MAI ATACAT (30Z):',
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
chart_title: '▶ TENDINȚĂ 24H',
|
|
|
|
|
breakdown_title: '▶ ANALIZA ATACURILOR // ULTIMELE 30 ZILE',
|
|
|
|
|
form_types: 'TIPURI FORMULAR', bot_toolkit: 'INSTRUMENTE BOT',
|
|
|
|
|
reasons_title: '▶ MOTIVE BLOCARE // ULTIMELE 30 ZILE',
|
|
|
|
|
feed_title: '▶ FLUX LIVE AMENINȚĂRI', events: 'evenimente',
|
|
|
|
|
connecting: 'conectare…', connected: 'conectat', reconnecting: 'reconectare…',
|
|
|
|
|
attackers_title: '▶ TOP ATACATORI // ULTIMELE 30 ZILE',
|
|
|
|
|
col_ip: 'ADRESĂ IP', col_hits: 'ACCESĂRI', col_asn: 'AS',
|
|
|
|
|
loading: 'Se încarcă…', no_data: 'Fără date încă',
|
|
|
|
|
footer_copy: 'MONITOR REȚEA HONEYPOT // INFORMAȚII CENTRALIZATE DESPRE AMENINȚĂRI',
|
|
|
|
|
refreshed: 'ACTUALIZAT:', made_in_eu: '🇪🇺 Realizat și găzduit în UE de',
|
2026-03-09 20:34:35 +01:00
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function detectLang() {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
const s = localStorage.getItem('hp_lang');
|
|
|
|
|
if (s && I18N[s]) return s;
|
2026-03-09 20:34:35 +01:00
|
|
|
const nav = (navigator.language || 'en').slice(0, 2).toLowerCase();
|
|
|
|
|
return I18N[nav] ? nav : 'en';
|
|
|
|
|
}
|
|
|
|
|
let currentLang = detectLang();
|
|
|
|
|
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
function t(k) { return (I18N[currentLang] || I18N.en)[k] || (I18N.en[k] || k); }
|
2026-03-09 20:34:35 +01:00
|
|
|
|
|
|
|
|
function setLang(lang) {
|
|
|
|
|
if (!I18N[lang]) return;
|
|
|
|
|
currentLang = lang;
|
|
|
|
|
localStorage.setItem('hp_lang', lang);
|
|
|
|
|
document.getElementById('html-root').lang = lang;
|
|
|
|
|
applyTranslations();
|
|
|
|
|
updateLangButtons();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function applyTranslations() {
|
|
|
|
|
document.querySelectorAll('[data-i18n]').forEach(el => {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
if (el.children.length === 0) el.textContent = t(el.getAttribute('data-i18n'));
|
2026-03-09 20:34:35 +01:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function updateLangButtons() {
|
|
|
|
|
document.querySelectorAll('.lang-btn').forEach(btn => {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
btn.className = 'lang-btn ' + (btn.dataset.lang === currentLang ? 'active' : 'inactive');
|
2026-03-09 20:34:35 +01:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
// ── Country flag helper ───────────────────────────────────────────────────────
|
|
|
|
|
function flag(cc) {
|
|
|
|
|
if (!cc || cc.length !== 2) return '';
|
|
|
|
|
// Regional indicator symbols: offset 127397 from ASCII
|
|
|
|
|
return String.fromCodePoint(...[...cc.toUpperCase()].map(c => c.charCodeAt(0) + 127397));
|
|
|
|
|
}
|
|
|
|
|
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
// ── Clock ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
const clockEl = document.getElementById('clock');
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
function tick() { clockEl.textContent = new Date().toISOString().slice(11,19) + ' UTC'; }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
tick(); setInterval(tick, 1000);
|
|
|
|
|
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
// ── CountUp ───────────────────────────────────────────────────────────────────
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
const ctMap = new Map();
|
|
|
|
|
function countUp(el, to) {
|
|
|
|
|
const from = parseInt(el.textContent.replace(/,/g,'')) || 0;
|
|
|
|
|
if (from === to) return;
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
const steps = 25, diff = to - from; let s = 0;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
clearInterval(ctMap.get(el));
|
|
|
|
|
const id = setInterval(() => {
|
|
|
|
|
s++;
|
|
|
|
|
el.textContent = Math.round(from + diff * (s / steps)).toLocaleString();
|
|
|
|
|
if (s >= steps) { el.textContent = to.toLocaleString(); clearInterval(id); }
|
|
|
|
|
}, 16);
|
|
|
|
|
ctMap.set(el, id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── Bar charts ────────────────────────────────────────────────────────────────
|
|
|
|
|
function renderBars(listEl, items) {
|
|
|
|
|
if (!items || !items.length) {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
listEl.innerHTML = `<li style="color:var(--dim);font-size:11px;padding:3px 0">${t('no_data')}</li>`;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const max = items[0].hits;
|
|
|
|
|
listEl.innerHTML = items.map(item => {
|
|
|
|
|
const label = item.form_type || item.ua_family || item.reason || item.ip || '?';
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
const pct = max > 0 ? Math.round(item.hits / max * 100) : 0;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
return `<li class="bar-item">
|
|
|
|
|
<span class="bar-lbl" title="${esc(label)}">${esc(label)}</span>
|
|
|
|
|
<div class="bar-track"><div class="bar-fill" style="width:${pct}%"></div></div>
|
|
|
|
|
<span class="bar-cnt">${item.hits.toLocaleString()}</span>
|
|
|
|
|
</li>`;
|
|
|
|
|
}).join('');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── 24h Canvas Chart ──────────────────────────────────────────────────────────
|
|
|
|
|
const canvas = document.getElementById('chart');
|
|
|
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
|
|
|
|
|
|
function drawChart(hourly) {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
const W = canvas.offsetWidth || 600, H = 72;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
canvas.width = W * (window.devicePixelRatio || 1);
|
|
|
|
|
canvas.height = H * (window.devicePixelRatio || 1);
|
|
|
|
|
ctx.scale(window.devicePixelRatio || 1, window.devicePixelRatio || 1);
|
|
|
|
|
ctx.clearRect(0, 0, W, H);
|
|
|
|
|
|
|
|
|
|
if (!hourly || !hourly.length) {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
ctx.fillStyle = '#226644'; ctx.font = '12px Courier New';
|
|
|
|
|
ctx.fillText(t('no_data'), 10, 38); return;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const base = Math.floor(Date.now() / 1000 / 3600) * 3600;
|
|
|
|
|
const map = new Map(hourly.map(r => [r.h, r.n]));
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
const hrs = Array.from({length: 24}, (_, i) => ({ h: base - (23-i)*3600, n: map.get(base-(23-i)*3600)||0 }));
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
const max = Math.max(...hrs.map(h => h.n), 1);
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
const pad = { l:2, r:2, t:5, b:3 };
|
|
|
|
|
const cW = W - pad.l - pad.r, cH = H - pad.t - pad.b;
|
|
|
|
|
const bW = cW / hrs.length - 1;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
ctx.strokeStyle = '#001a00'; ctx.lineWidth = 1;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
[0.33, 0.66].forEach(f => {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
const y = pad.t + cH*(1-f);
|
|
|
|
|
ctx.beginPath(); ctx.moveTo(pad.l, y); ctx.lineTo(W-pad.r, y); ctx.stroke();
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
hrs.forEach((h, i) => {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
const x = pad.l + i*(cW/hrs.length);
|
|
|
|
|
const bH = Math.max(1, h.n/max*cH), y = pad.t+cH-bH;
|
|
|
|
|
const g = ctx.createLinearGradient(0, y, 0, y+bH);
|
|
|
|
|
g.addColorStop(0, '#00ff41'); g.addColorStop(1, '#004400');
|
|
|
|
|
ctx.fillStyle = g;
|
|
|
|
|
ctx.fillRect(x+0.5, y, Math.max(bW,1), bH);
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
if (h.n === max) {
|
|
|
|
|
ctx.shadowColor = '#00ff41'; ctx.shadowBlur = 10;
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
ctx.fillRect(x+0.5, y, Math.max(bW,1), bH);
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
ctx.shadowBlur = 0;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
document.getElementById('chart-peak').textContent =
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
`PEAK ${max.toLocaleString()}/hr TOTAL ${hrs.reduce((a,h)=>a+h.n,0).toLocaleString()}`;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
|
|
|
|
window.addEventListener('resize', () => { if (window._hourly) drawChart(window._hourly); });
|
|
|
|
|
|
|
|
|
|
// ── Attackers table ───────────────────────────────────────────────────────────
|
|
|
|
|
function renderAttackers(ips) {
|
|
|
|
|
const tbody = document.getElementById('atk-body');
|
|
|
|
|
if (!ips || !ips.length) {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
tbody.innerHTML = `<tr><td colspan="4" style="text-align:center;padding:14px;color:var(--dim)">${t('no_data')}</td></tr>`;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const max = ips[0].hits;
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
tbody.innerHTML = ips.map((row, i) => {
|
|
|
|
|
const f = flag(row.country);
|
|
|
|
|
const asnNo = (row.asn || '').split(' ')[0]; // e.g. "AS12345"
|
|
|
|
|
return `<tr>
|
|
|
|
|
<td class="atk-rank">#${i+1}</td>
|
|
|
|
|
<td class="atk-ip">${f ? f+' ' : ''}${esc(row.ip)}</td>
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
<td class="atk-hits">${row.hits.toLocaleString()}</td>
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
<td class="atk-asn" title="${esc(row.asn || '')}">${esc(asnNo)}</td>
|
|
|
|
|
</tr>`;
|
|
|
|
|
}).join('');
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
|
|
|
function esc(s) {
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
return String(s||'').replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
function fmtTime(ts) { return new Date(ts*1000).toISOString().slice(11,19); }
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
|
|
|
|
|
// ── Live feed ─────────────────────────────────────────────────────────────────
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
let feedCount = 0;
|
2026-03-09 20:34:35 +01:00
|
|
|
const feedEl = document.getElementById('feed');
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
const feedCount$ = document.getElementById('feed-count');
|
|
|
|
|
const feedStatus = document.getElementById('feed-status');
|
|
|
|
|
|
|
|
|
|
function addRow(row) {
|
|
|
|
|
feedCount++;
|
2026-03-09 20:34:35 +01:00
|
|
|
feedCount$.textContent = `${feedCount.toLocaleString()} ${t('events')}`;
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
const el = document.createElement('div');
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
el.className = 'feed-row';
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
const f = flag(row.country || '');
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
el.innerHTML = `
|
|
|
|
|
<span class="feed-ts">${fmtTime(row.received_at)}</span>
|
|
|
|
|
<span class="feed-ip">${esc(row.ip_masked || row.ip || '?')}</span>
|
|
|
|
|
<span>
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
${f ? `<span class="feed-geo">${f} ${esc(row.country||'')}</span><br>` : ''}
|
|
|
|
|
<span class="feed-form">${esc(row.form_type||'?')}</span>
|
|
|
|
|
<br><span class="feed-reason">${esc(row.reason||'')}</span>
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
</span>`;
|
|
|
|
|
feedEl.prepend(el);
|
|
|
|
|
while (feedEl.children.length > 120) feedEl.removeChild(feedEl.lastChild);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function seedFeed() {
|
|
|
|
|
try {
|
|
|
|
|
const r = await fetch('/api/v1/stats');
|
|
|
|
|
const s = await r.json();
|
|
|
|
|
if (s.recent) [...s.recent].reverse().forEach(addRow);
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
} catch {}
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function connectSSE() {
|
|
|
|
|
const es = new EventSource('/api/v1/stream');
|
2026-03-09 20:34:35 +01:00
|
|
|
es.onopen = () => { feedStatus.textContent = t('connected'); };
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
es.onmessage = e => { try { JSON.parse(e.data).reverse().forEach(addRow); } catch {} };
|
|
|
|
|
es.onerror = () => {
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
es.close();
|
2026-03-09 20:34:35 +01:00
|
|
|
feedStatus.textContent = t('reconnecting');
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
setTimeout(connectSSE, 5000);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── Stats polling ─────────────────────────────────────────────────────────────
|
|
|
|
|
async function fetchStats() {
|
|
|
|
|
try {
|
|
|
|
|
const r = await fetch('/api/v1/stats');
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
if (!r.ok) return;
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
const s = await r.json();
|
|
|
|
|
|
|
|
|
|
countUp(document.getElementById('s-total'), s.total);
|
|
|
|
|
countUp(document.getElementById('s-today'), s.today);
|
|
|
|
|
countUp(document.getElementById('s-7d'), s.last_7d);
|
|
|
|
|
countUp(document.getElementById('s-30d'), s.last_30d);
|
|
|
|
|
countUp(document.getElementById('s-sites'), s.total_sites);
|
|
|
|
|
|
|
|
|
|
renderBars(document.getElementById('bars-forms'), s.top_forms);
|
|
|
|
|
renderBars(document.getElementById('bars-ua'), s.top_ua);
|
|
|
|
|
renderBars(document.getElementById('bars-reasons'), s.top_reasons);
|
|
|
|
|
renderAttackers(s.top_ips);
|
|
|
|
|
|
2026-03-09 19:26:23 +01:00
|
|
|
if (s.top_forms && s.top_forms.length) {
|
|
|
|
|
const top = s.top_forms[0];
|
2026-03-09 20:34:35 +01:00
|
|
|
document.getElementById('tt-label').textContent = t('top_target_label');
|
|
|
|
|
document.getElementById('tt-form').textContent = top.form_type;
|
|
|
|
|
document.getElementById('tt-hits').textContent = `${top.hits.toLocaleString()} hits`;
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
const pct = s.last_30d > 0 ? Math.round(top.hits/s.last_30d*100) : 0;
|
2026-03-09 20:34:35 +01:00
|
|
|
document.getElementById('tt-pct').textContent = `(${pct}% of all blocks)`;
|
2026-03-09 19:26:23 +01:00
|
|
|
}
|
|
|
|
|
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
window._hourly = s.hourly;
|
|
|
|
|
drawChart(s.hourly);
|
fix: CF7 bypass, auto-flush, layout, contrast, IP geo v2.4.0
CF7:
- Add wpcf7_spam filter registered before is_admin() early-return so
CF7 AJAX submissions (admin-ajax.php) are properly validated
- Exclude CF7 posts from generic catch-all (prevent double-checking)
Auto-flush:
- Add maybe_flush_overdue() with 5-min transient lock, hooked to
shutdown action so every PHP request can trigger a flush if overdue
- No longer depends solely on WP-Cron firing
Dashboard layout:
- Top Attackers moved into right column below live feed
- Viewport-fill layout: body/main use flex+overflow:hidden so content
stays in view; left col scrolls independently if needed
- Feed panel takes flex:1, attackers panel capped at 260px
Colors:
- --dim: #006600 → #44bb77 (legible secondary text, ~5:1 contrast)
- --dim2: #228844 added for slightly darker secondary use
- --muted kept dark for backgrounds only; border lightened slightly
IP geo (server-side, async, non-blocking):
- country + asn columns added to blocks table (migration-safe)
- enrichIP() calls ip-api.com free HTTP API per unique IP, cached 1h
- Background job enriches historic rows missing country (5 per 20s)
- Stats and live feed now include country code + ASN
- Dashboard shows country flag emoji in feed rows and attackers table
- Full AS name shown as tooltip on ASN column
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 07:57:16 +01:00
|
|
|
document.getElementById('last-update').textContent = new Date().toISOString().slice(11,19) + ' UTC';
|
|
|
|
|
} catch {}
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── Boot ──────────────────────────────────────────────────────────────────────
|
2026-03-09 20:34:35 +01:00
|
|
|
feedStatus.textContent = t('connecting');
|
|
|
|
|
applyTranslations();
|
|
|
|
|
updateLangButtons();
|
feat: centralized API dashboard + Docker container
API server (api/):
- Node.js + Express + SQLite (better-sqlite3, WAL mode)
- POST /api/v1/submit — receive blocks from WP sites (rate limited 30/min/IP)
- GET /api/v1/stats — public aggregated stats with 30s cache
- GET /api/v1/stream — SSE live feed, pushed every 2s
- GET /api/v1/health — health check
- IP masking: only first 2 octets stored (192.168.x.x)
- UA family detection: curl, Python, Go, bots, Chrome, etc.
- docker-compose.yml with named volume for SQLite persistence
Dashboard (api/public/index.html):
- Hacker/terminal aesthetic: black + matrix green, CRT scanlines
- Live stat cards: total blocked, today, 7d, 30d, sites reporting
- Canvas 24h activity trend chart with gradient bars
- CSS bar charts: form types, bot toolkit, block reasons
- Live SSE threat feed with countUp animation and auto-scroll
- Top 10 attackers table with frequency bars
- Polls /api/v1/stats every 6s, SSE for instant feed updates
WordPress plugin (honeypot-fields.php):
- SmartHoneypotAPIClient: queue (WP option) + WP-cron batch flush every 5min
- log_spam() now enqueues to central API after local DB write
- Admin 'Central API' tab: enable toggle, endpoint URL, sync stats, manual flush
- Cron properly registered/deregistered on activate/deactivate
2026-03-09 19:21:41 +01:00
|
|
|
seedFeed();
|
|
|
|
|
connectSSE();
|
|
|
|
|
fetchStats();
|
|
|
|
|
setInterval(fetchStats, 6000);
|
|
|
|
|
</script>
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|