fix(hik-alarm): listen on all methods + skippable source-IP guard (WSL)
Diagnosed why no camera push ever landed: (1) the route only registered POST/GET, so a probe with another method got a generic 404 the camera reads as "service available" while our handler never ran; (2) more fundamentally, WSL mirrored mode REWRITES the inbound source IP to the host's own address (10.0.10.203), so the camera's real IP (10.0.10.12) never survives and the source-IP guard rejected every push as a mismatch. - Register the event route on POST/GET/PUT/PATCH/DELETE/OPTIONS (HEAD comes with GET) so ANYTHING hitting the path reaches the handler and is recorded. - Log + store the HTTP method of each hit; log every hit on arrival, before any guard, so even a rejected probe is visible immediately. - Add per-device skipSourceIpCheck (a Setup checkbox) to bypass the source-IP guard where the network rewrites the source (WSL). Digest auth + the signed ledger remain the real guards. Tests: hik-alarm 10 (skip-IP accept + method capture). server green; web build green (new checkbox renderer + this field). Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
@@ -138,6 +138,23 @@ describe("Hikvision Alarm Server push", () => {
|
||||
expect(alarmEvents()[0]!.detail.eventType).toBe("vehicleDetection");
|
||||
});
|
||||
|
||||
it("accepts a push from ANY source IP when skipSourceIpCheck is set (WSL rewrites it)", async () => {
|
||||
// WSL mirrored mode rewrites the inbound source to the host's own IP, so the camera's
|
||||
// real IP never survives and a strict check rejects every push. With the opt-out, a
|
||||
// push from the 'wrong' IP is accepted.
|
||||
seedHikCamera({ skipSourceIpCheck: true });
|
||||
const res = await app.inject({
|
||||
method: "POST",
|
||||
url: `/api/devices/hikvision/${CAM_ID}/event`,
|
||||
headers: { "content-type": "application/xml" },
|
||||
payload: VEHICLE_XML,
|
||||
remoteAddress: "10.0.10.203", // the rewritten host IP, NOT the camera's
|
||||
});
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(alarmEvents()).toHaveLength(1);
|
||||
expect(alarmEvents()[0]!.detail.target).toBe("vehicle");
|
||||
});
|
||||
|
||||
it("rejects a push from a DIFFERENT source IP (404, nothing recorded)", async () => {
|
||||
seedHikCamera();
|
||||
const res = await app.inject({
|
||||
|
||||
Reference in New Issue
Block a user