Secure the device→backend input push, and configure it automatically when the
admin assigns the device (no manual URL/secret entry).
Auth — HTTP Digest (chosen by hardware testing: the device can't push to a
self-signed HTTPS backend, but does Digest correctly; a URL token is sniffable/
logged):
- digest-auth.ts: MD5 qop=auth challenge/verify, single-use nonces (replay
resistance). Password never crosses the wire.
- push route: Digest + source-IP allowlist; per-device pushUser/pushPassword from
lane_devices. Still not behind the SPA cookie/CSRF auth (machine call). The
signed event log remains the real anti-fraud guarantee.
Auto-config on assign:
- setup assign: for push-capable devices, generate Digest creds, call
configureInputPush to write them + the push URLs to the device, store the creds
(password not echoed back). net.ts derives the backend IP on the device's
subnet (BACKEND_HOST_IP override).
- driver configureInputPush sets auth=2 + creds; PushConfig carries the creds.
- removed the earlier URL-token approach.
Two hard-won device-write bugs fixed in the driver:
- configApi now sets an explicit Content-Length — the device silently ignores
chunked request bodies (Node's default without Content-Length), so every config
write looked successful ({"status":0}) but did nothing. This was the root cause
of the session's "writes don't apply" mystery.
- #writeConfig polls until the change is verified, retrying (the device reboots on
apply; back-to-back writes were lost). The `pass` field caps at 31 chars, so the
generated password is 24 hex chars.
Verified on hardware: assign auto-configures the device; all 4 inputs then push
with Digest auth, zero failures. wiki/device-input-flow updated.
The device pushes button events to the backend via its Input Link URL feature;
the backend decides. No polling — the chosen entry architecture.
packages/devices:
- dingtian driver: configureInputPush() writes the device's input_link_url
config (per-input server/port/path, en=1, active-LOW, plain HTTP) so each
input HTTP-GETs the backend on press/release. Extracted #readConfig/#writeConfig
(with the required command:setconfig injection + post-write reset tolerance).
apps/server:
- routes/devices.ts: public GET/POST
/api/devices/dingtian/:deviceId/input/:n/{on,off} — translates a device push
into an internal device event. Not behind cookie/CSRF (machine call from the
device); trust comes from the signed event log, not this request.
- device-events.ts: internal EventEmitter bus so the entry flow subscribes to
input events without coupling to HTTP. Wired into the server.
Verified on hardware: configured the device, then real presses on all 4 inputs
pushed to the backend (input N on+off, source = device IP). No polling.
wiki: device-input-flow concept (path + trust model for the flat/no-VLAN
network); dingtian-relay updated; index + log.