@7365admin1/core 3.32.2-staging.63 → 3.32.2-staging.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,60 @@
1
+ ---
2
+ "@7365admin1/core": minor
3
+ ---
4
+
5
+ Camera integration layer: a capability descriptor, a transport registry, and the
6
+ Dahua device HTTP adapter (written, tested, switched off).
7
+
8
+ Every camera in the wall and status responses now carries a `capabilities`
9
+ descriptor: `liveVideo`, `stillFrame`, `digitalZoom`, `ptz`, `presets`,
10
+ `playback`, `events`, `audio`, `deviceInfo`, each `supported` / `unsupported` /
11
+ `unknown` with a machine-readable reason code and one sentence. A client renders
12
+ itself from it without knowing anything about relays, recorders or networks.
13
+ `unknown` is distinct on purpose: "we have not been allowed to ask" is not the
14
+ same fact as "this camera cannot".
15
+
16
+ Capabilities resolve through a transport registry instead of the service picking
17
+ a path. `RELAY_PLAYER` is the stored player-page URL rendered in a WebView (the
18
+ live product's picture path, live video only, no control channel). `RTSP_FRAME`
19
+ is one ffmpeg still off the recorder. `DEVICE_HTTP` is the camera's own CGI API.
20
+ Registration order is preference order, so one camera serves live video over the
21
+ relay and evidence stills over RTSP at the same time, and adding a transport
22
+ later needs no service change.
23
+
24
+ `DEVICE_HTTP` covers device info/version, snapshot, PTZ (continuous, absolute,
25
+ stop), presets (list and recall), recorded-file query with playback URL
26
+ construction, and event subscription - digest auth only, values percent-encoded,
27
+ 403 treated as bad credentials and 401 as an ordinary challenge. It contacts
28
+ nothing today: the recorder in this estate answers on RTSP only. Enabling it is
29
+ configuration, not a code change.
30
+
31
+ A shared, persistent authentication failure budget is mandatory on that path. The
32
+ device locks an account for 1800 s after 3 failed logins in 30 s, so failures are
33
+ counted per device in the cache, the budget stops at 2, and once spent no request
34
+ leaves the process. Nothing retries anywhere.
35
+
36
+ Mutating operations are structurally unreachable while disabled: the adapter is
37
+ `null` without `CAMERA_DEVICE_HTTP_ENABLED`, and its `control` object is `null`
38
+ without `CAMERA_DEVICE_CONTROL_ENABLED`. Movement codes are an allow-list;
39
+ `SetPreset`, `ClearPreset`, tours, patterns, `configManager` writes and reboot are
40
+ absent.
41
+
42
+ Capability probing is read-only, cached, budget-aware, never throws, and happens
43
+ only on a deliberate single-camera status request - never as a side effect of a
44
+ list.
45
+
46
+ `host` is now returned for `type: "ip"` cameras on the wall response. It is the
47
+ video relay's player-page URL, not a device address and not a credential, and
48
+ `GET /site-cameras` already returns it to every authenticated caller. `anpr`
49
+ records, whose `host` is a real device endpoint, are excluded by the allow-list
50
+ itself.
51
+
52
+ New configuration, all optional and all off by default: `CAMERA_DEVICE_HTTP`
53
+ (JSON keyed by relay authority, credential referenced by environment variable
54
+ name), `CAMERA_DEVICE_HTTP_ENABLED`, `CAMERA_DEVICE_CONTROL_ENABLED`,
55
+ `CAMERA_DEVICE_HTTP_TIMEOUT_MS` (8000),
56
+ `CAMERA_DEVICE_HTTP_PROBE_TTL_SECONDS` (900). See
57
+ `docs/camera-integration-config.md`.
58
+
59
+ Existing responses keep every field they had, with the same wording, so current
60
+ consumers are unaffected.
@@ -0,0 +1,43 @@
1
+ ---
2
+ "@7365admin1/core": minor
3
+ ---
4
+
5
+ Camera setup from the recorder and channel, and a read-only test before saving.
6
+
7
+ A CCTV camera record stores a video-relay player-page URL. Nothing printed on a
8
+ camera or shown in a recorder's own screens tells anybody what that URL is, so
9
+ adding a camera meant asking whoever runs the video service for one address per
10
+ camera and pasting it in unverified.
11
+
12
+ `POST /site-cameras` and `PATCH /site-cameras/id/:id` now also accept
13
+ `recorderHost`, `recorderPort` and `channel`. The server reads the existing
14
+ `CAMERA_RTSP_DEVICES` map backwards - relay authority to recorder becomes
15
+ recorder to relay authority - and derives the same `https://<relay>/<channel>`
16
+ address it has always stored. There is deliberately no second map and no new
17
+ stored field: the recorder fields are consumed by the controller and never reach
18
+ the model, so `site.cameras` keeps exactly the shape it has today.
19
+
20
+ Additive and ordered so: a request that sends `host` behaves exactly as it
21
+ always has, so every camera configured that way and anyone holding a ready-made
22
+ address is unaffected. A recorder with no configured entry is refused with a
23
+ sentence a property manager can act on rather than a code.
24
+
25
+ New: `POST /site-cameras/site/:siteId/test` - does this address actually show a
26
+ picture? Site-scoped because the camera does not exist yet, and it requires
27
+ `site-settings:manage-cctv-camera`. The probe is read only: one TCP connect with
28
+ no credential, then at most one video frame off the stream. There is no mutating
29
+ call in the path.
30
+
31
+ It is rationed before it can reach a device - one test per camera per 15 s, four
32
+ per recorder per 5 minutes - and it consults the shared authentication failure
33
+ budget first, so pressing the button cannot walk a recorder into its own
34
+ 3-failures-in-30-seconds, 1800-second lockout. It answers with one of five plain
35
+ sentences and never an address, port, credential or device message.
36
+
37
+ `ffmpeg`'s stderr is now read for one fact - was the handshake rejected - and
38
+ discarded chunk by chunk without being accumulated, logged or returned, so "the
39
+ recorder refused the credential" can be told apart from "the channel is not
40
+ sending video". Snapshot failures gain that distinction too.
41
+
42
+ `authorizeSite` takes an optional permission list; existing callers are unchanged
43
+ and still require the camera view permissions.