syco.me Homelab Dashboard
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
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<string, number> = {}
|
||||
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
|
||||
Reference in New Issue
Block a user