Files
Charon/frontend/src/api/crowdsec.ts
GitHub Actions 1919530662 fix: add LAPI readiness check to CrowdSec status endpoint
The Status() handler was only checking if the CrowdSec process was
running, not if LAPI was actually responding. This caused the
CrowdSecConfig page to always show "LAPI is initializing" even when
LAPI was fully operational.

Changes:
- Backend: Add lapi_ready field to /admin/crowdsec/status response
- Frontend: Add CrowdSecStatus TypeScript interface
- Frontend: Update conditional logic to check lapi_ready not running
- Frontend: Separate warnings for "initializing" vs "not running"
- Tests: Add unit tests for Status handler LAPI check

Fixes regression from crowdsec_lapi_error_diagnostic.md fixes.
2025-12-15 07:30:35 +00:00

76 lines
2.3 KiB
TypeScript

import client from './client'
export interface CrowdSecDecision {
id: string
ip: string
reason: string
duration: string
created_at: string
source: string
}
export async function startCrowdsec(): Promise<{ status: string; pid: number; lapi_ready?: boolean }> {
const resp = await client.post('/admin/crowdsec/start')
return resp.data
}
export async function stopCrowdsec() {
const resp = await client.post('/admin/crowdsec/stop')
return resp.data
}
export interface CrowdSecStatus {
running: boolean
pid: number
lapi_ready: boolean
}
export async function statusCrowdsec(): Promise<CrowdSecStatus> {
const resp = await client.get<CrowdSecStatus>('/admin/crowdsec/status')
return resp.data
}
export async function importCrowdsecConfig(file: File) {
const fd = new FormData()
fd.append('file', file)
const resp = await client.post('/admin/crowdsec/import', fd, {
headers: { 'Content-Type': 'multipart/form-data' },
})
return resp.data
}
export async function exportCrowdsecConfig() {
const resp = await client.get('/admin/crowdsec/export', { responseType: 'blob' })
return resp.data
}
export async function listCrowdsecFiles() {
const resp = await client.get<{ files: string[] }>('/admin/crowdsec/files')
return resp.data
}
export async function readCrowdsecFile(path: string) {
const resp = await client.get<{ content: string }>(`/admin/crowdsec/file?path=${encodeURIComponent(path)}`)
return resp.data
}
export async function writeCrowdsecFile(path: string, content: string) {
const resp = await client.post('/admin/crowdsec/file', { path, content })
return resp.data
}
export async function listCrowdsecDecisions(): Promise<{ decisions: CrowdSecDecision[] }> {
const resp = await client.get<{ decisions: CrowdSecDecision[] }>('/admin/crowdsec/decisions')
return resp.data
}
export async function banIP(ip: string, duration: string, reason: string): Promise<void> {
await client.post('/admin/crowdsec/ban', { ip, duration, reason })
}
export async function unbanIP(ip: string): Promise<void> {
await client.delete(`/admin/crowdsec/ban/${encodeURIComponent(ip)}`)
}
export default { startCrowdsec, stopCrowdsec, statusCrowdsec, importCrowdsecConfig, exportCrowdsecConfig, listCrowdsecFiles, readCrowdsecFile, writeCrowdsecFile, listCrowdsecDecisions, banIP, unbanIP }