diff --git a/docs/widgets/services/crowdsec.md b/docs/widgets/services/crowdsec.md index 977b0adb4..fdf03a77e 100644 --- a/docs/widgets/services/crowdsec.md +++ b/docs/widgets/services/crowdsec.md @@ -9,7 +9,9 @@ See the [crowdsec docs](https://docs.crowdsec.net/docs/local_api/intro/#machines in most instances you can use the default credentials (`/etc/crowdsec/local_api_credentials.yaml`). !!! note -Without the `limit24h` option, the widget will fetch all alerts which is limited to 100 by the API to avoid performance issues. + + `alerts` counts alerts raised by your own engine in the last 24 hours. Alerts originating from the + CrowdSec community blocklist are excluded. Allowed fields: `["alerts", "bans"]`. @@ -19,5 +21,4 @@ widget: url: http://crowdsechostorip:port username: localhost # machine_id in crowdsec password: password - limit24h: true # optional, limits alerts to last 24h. Default: false ``` diff --git a/src/widgets/crowdsec/component.jsx b/src/widgets/crowdsec/component.jsx index 7eea1fc9c..15794187f 100644 --- a/src/widgets/crowdsec/component.jsx +++ b/src/widgets/crowdsec/component.jsx @@ -4,14 +4,19 @@ import { useTranslation } from "next-i18next/pages"; import useWidgetAPI from "utils/proxy/use-widget-api"; +const ALERTS_LIMIT = 500; + export default function Component({ service }) { const { t } = useTranslation(); const { widget } = service; - const { data: alerts, error: alertsError } = useWidgetAPI(widget, !!widget.limit24h ? "alerts24h" : "alerts"); + const { data: alerts, error: alertsError } = useWidgetAPI(widget, "alerts"); const { data: bans, error: bansError } = useWidgetAPI(widget, "bans"); + const alertsCount = alerts?.length ?? 0; + const alertsValue = t("common.number", { value: alertsCount }); + if (alertsError || bansError) { return ; } @@ -27,7 +32,7 @@ export default function Component({ service }) { return ( - + = ALERTS_LIMIT ? `${alertsValue}+` : alertsValue} /> ); diff --git a/src/widgets/crowdsec/component.test.jsx b/src/widgets/crowdsec/component.test.jsx index abc4c8696..9802eaed4 100644 --- a/src/widgets/crowdsec/component.test.jsx +++ b/src/widgets/crowdsec/component.test.jsx @@ -17,15 +17,25 @@ describe("widgets/crowdsec/component", () => { vi.clearAllMocks(); }); - it("selects alerts24h endpoint when limit24h is enabled", () => { + it("requests the alerts and bans endpoints", () => { + useWidgetAPI.mockImplementation(() => ({ data: undefined, error: undefined })); + + renderWithProviders(, { + settings: { hideErrors: false }, + }); + + expect(useWidgetAPI).toHaveBeenNthCalledWith(1, expect.any(Object), "alerts"); + expect(useWidgetAPI).toHaveBeenNthCalledWith(2, expect.any(Object), "bans"); + }); + + it("ignores the deprecated limit24h option", () => { useWidgetAPI.mockImplementation(() => ({ data: undefined, error: undefined })); renderWithProviders(, { settings: { hideErrors: false }, }); - expect(useWidgetAPI).toHaveBeenNthCalledWith(1, expect.any(Object), "alerts24h"); - expect(useWidgetAPI).toHaveBeenNthCalledWith(2, expect.any(Object), "bans"); + expect(useWidgetAPI).toHaveBeenNthCalledWith(1, expect.any(Object), "alerts"); }); it("renders placeholders when both alerts and bans are missing", () => { @@ -52,4 +62,28 @@ describe("widgets/crowdsec/component", () => { expectBlockValue(container, "crowdsec.alerts", 0); expectBlockValue(container, "crowdsec.bans", 0); }); + + it("marks the alert count as truncated at the API limit", () => { + useWidgetAPI + .mockReturnValueOnce({ data: new Array(500).fill({}), error: undefined }) + .mockReturnValueOnce({ data: [], error: undefined }); + + renderWithProviders(, { + settings: { hideErrors: false }, + }); + + expect(screen.getByText("500+")).toBeInTheDocument(); + }); + + it("does not mark the alert count below the API limit", () => { + useWidgetAPI + .mockReturnValueOnce({ data: new Array(499).fill({}), error: undefined }) + .mockReturnValueOnce({ data: [], error: undefined }); + + const { container } = renderWithProviders(, { + settings: { hideErrors: false }, + }); + + expectBlockValue(container, "crowdsec.alerts", 499); + }); }); diff --git a/src/widgets/crowdsec/widget.js b/src/widgets/crowdsec/widget.js index 1b60168d0..223e94811 100644 --- a/src/widgets/crowdsec/widget.js +++ b/src/widgets/crowdsec/widget.js @@ -7,13 +7,10 @@ const widget = { mappings: { alerts: { - endpoint: "alerts", - }, - alerts24h: { - endpoint: "alerts?limit=0&since=24h", + endpoint: "alerts?limit=500&since=24h&with_decisions=false&include_capi=false", }, bans: { - endpoint: "alerts?decision_type=ban&origin=crowdsec&has_active_decision=1", + endpoint: "alerts?decision_type=ban&include_capi=false&has_active_decision=1&with_decisions=false", }, }, };