import { Router } from 'express' import axios from 'axios' const router = Router() router.get('/stats', async (_req, res) => { try { const host = process.env.CROWDSEC_HOST const key = process.env.CROWDSEC_API_KEY if (!host || !key) { res.status(503).json({ error: 'CROWDSEC_HOST / CROWDSEC_API_KEY not configured' }) return } const headers = { 'X-Api-Key': key.trim() } // Bouncers can only access /v1/decisions — alerts require machine/agent auth const [activeRes, weekRes] = await Promise.all([ axios.get(`${host}/v1/decisions`, { headers, params: { limit: 500000 } }), axios.get(`${host}/v1/decisions`, { headers, params: { limit: 500000, since: '168h' } }), ]) type Decision = { id?: number origin?: string type?: string scope?: string value?: string scenario?: string created_at?: string until?: string } const active: Decision[] = Array.isArray(activeRes.data) ? activeRes.data : [] const week: Decision[] = Array.isArray(weekRes.data) ? weekRes.data : [] const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000) const alertsLast24h = active.filter(d => d.created_at && new Date(d.created_at) > oneDayAgo).length const originCount: Record = {} for (const d of active) { const o = d.origin ?? 'unknown' originCount[o] = (originCount[o] ?? 0) + 1 } const origins = Object.entries(originCount) .sort((a, b) => b[1] - a[1]) .map(([name, count]) => ({ name, count })) const recent = [...active] .filter(d => d.created_at) .sort((a, b) => new Date(b.created_at!).getTime() - new Date(a.created_at!).getTime()) .slice(0, 6) .map(d => ({ value: d.value ?? '?', scenario: d.scenario ?? d.origin ?? '?', created_at: d.created_at! })) res.json({ activeBans: active.length, alertsLast24h, blocksThisWeek: week.length, origins, recent, }) } catch (err: unknown) { const msg = err instanceof Error ? err.message : 'Unknown error' res.status(500).json({ error: msg }) } }) export default router