Compare commits

...

2 Commits

Author SHA1 Message Date
dependabot[bot] 565d086d04 Chore(deps): Bump crowdin/github-action from 2.17.1 to 3.0.0
Bumps [crowdin/github-action](https://github.com/crowdin/github-action) from 2.17.1 to 3.0.0.
- [Release notes](https://github.com/crowdin/github-action/releases)
- [Commits](https://github.com/crowdin/github-action/compare/8f01d54f70f1713ee3f09d82c2bbb2daeac28689...e4a6c1338b4063c77d46a81875265f9e8bd76f95)

---
updated-dependencies:
- dependency-name: crowdin/github-action
  dependency-version: 3.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-03 16:33:45 +00:00
shamoon ddc5adc91c Fix: handle literal null from crowdsec api alerts (#7088)
Docker CI / Docker Build & Push (push) Has been cancelled
Lint / Linting Checks (push) Has been cancelled
Release Drafter / Update Release Draft (push) Has been cancelled
Release Drafter / Auto Label PR (push) Has been cancelled
Tests / vitest (1) (push) Has been cancelled
Tests / vitest (2) (push) Has been cancelled
Tests / vitest (3) (push) Has been cancelled
Tests / vitest (4) (push) Has been cancelled
2026-09-02 12:40:40 -07:00
5 changed files with 43 additions and 2 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ jobs:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: crowdin action
uses: crowdin/github-action@8f01d54f70f1713ee3f09d82c2bbb2daeac28689 # v2
uses: crowdin/github-action@e4a6c1338b4063c77d46a81875265f9e8bd76f95 # v3.0.0
with:
upload_translations: false
download_translations: true
+1 -1
View File
@@ -21,7 +21,7 @@ export default function Component({ service }) {
return <Container service={service} error={alertsError ?? bansError} />;
}
if (!alerts && !bans) {
if (alerts === undefined && bans === undefined) {
return (
<Container service={service}>
<Block label="crowdsec.alerts" />
+11
View File
@@ -86,4 +86,15 @@ describe("widgets/crowdsec/component", () => {
expectBlockValue(container, "crowdsec.alerts", 499);
});
it("renders null responses as 0 counts", () => {
useWidgetAPI.mockImplementation(() => ({ data: null, error: undefined }));
const { container } = renderWithProviders(<Component service={{ widget: { type: "crowdsec" } }} />, {
settings: { hideErrors: false },
});
expectBlockValue(container, "crowdsec.alerts", 0);
expectBlockValue(container, "crowdsec.bans", 0);
});
});
+5
View File
@@ -102,6 +102,11 @@ export default async function crowdsecProxyHandler(req, res) {
return res.status(status).json({ error: "Crowdsec API Error", data });
}
// Crowdsec returns a literal null instead of an empty array when nothing matches
if (data?.toString().trim() === "null") {
return res.status(status).json([]);
}
return res.status(status).send(data);
} catch (error) {
logger.error("Exception calling Crowdsec API: %s", error.message);
+25
View File
@@ -161,4 +161,29 @@ describe("widgets/crowdsec/proxy", () => {
expect(res.statusCode).toBe(500);
expect(res.body).toEqual({ error: "Failed to authenticate with Crowdsec" });
});
it("normalizes a literal null response to an empty array", async () => {
getServiceWidget.mockResolvedValue({
type: "crowdsec",
url: "http://cs",
username: "machine",
password: "pw",
});
httpProxy
.mockResolvedValueOnce([
200,
"application/json",
JSON.stringify({ token: "tok", expire: new Date(Date.now() + 60_000).toISOString() }),
])
.mockResolvedValueOnce([200, "application/json", Buffer.from("null")]);
const req = { query: { group: "g", service: "svc", endpoint: "alerts", index: "0" } };
const res = createMockRes();
await crowdsecProxyHandler(req, res);
expect(res.statusCode).toBe(200);
expect(res.body).toEqual([]);
});
});