@apocaliss92/nodelink-js 0.1.9 → 0.1.17

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.
package/README.md CHANGED
@@ -1,12 +1,12 @@
1
- <p align="center">
2
- <img src="assets/icon.png" alt="nodelink.js" width="128" height="128">
3
- </p>
4
-
5
- <h1 align="center">nodelink.js</h1>
6
-
7
- <p align="center">
8
- A TypeScript library for interacting with Reolink IP cameras and NVRs using the proprietary Baichuan protocol and CGI API.
9
- </p>
1
+ <table>
2
+ <tr>
3
+ <td><img src="app/client/public/icon-512x512.png" alt="nodelink.js" width="256" height="256"></td>
4
+ <td>
5
+ <h1>nodelink.js</h1>
6
+ <p>A TypeScript library for interacting with Reolink IP cameras and NVRs using the proprietary Baichuan protocol and CGI API.</p>
7
+ </td>
8
+ </tr>
9
+ </table>
10
10
 
11
11
  ## Credits
12
12
 
@@ -30,6 +30,254 @@ This library is inspired by and based on the reverse engineering work done by:
30
30
 
31
31
  ---
32
32
 
33
+ ## 🖥️ Manager UI (Web Dashboard)
34
+
35
+ The library includes a **complete web-based management interface** for easy camera configuration and streaming control without writing code.
36
+
37
+ <p align="center">
38
+ <b>Features:</b>
39
+ </p>
40
+
41
+ - 🎛️ **Camera Management** - Add, configure, and monitor multiple cameras
42
+ - 📹 **Live Streaming** - Preview streams via MJPEG, WebRTC, or RTSP
43
+ - 📊 **Real-time Logs** - Monitor camera events and system logs
44
+ - ⚙️ **Settings** - Configure RTSP proxy, ports, and auto-start options
45
+ - 📱 **PWA Support** - Install as a Progressive Web App on mobile devices
46
+ - 🌐 **Responsive Design** - Works on desktop, tablet, and mobile
47
+
48
+ ### External Requirements
49
+
50
+ To run the Manager UI outside Docker, you need:
51
+
52
+ Some features also rely on external binaries that must be available on the host when running outside Docker:
53
+
54
+ Install examples:
55
+
56
+ ```bash
57
+ # macOS
58
+ brew install ffmpeg
59
+
60
+ # Debian/Ubuntu
61
+ sudo apt-get update && sudo apt-get install -y ffmpeg
62
+ ```
63
+
64
+ If you use the Docker image, FFmpeg is already included (see Docker Deployment below).
65
+
66
+ ### Quick Start (Development)
67
+
68
+ ```bash
69
+ cd app
70
+ npm install
71
+ npm run dev
72
+ ```
73
+
74
+ ## Trusted Proxy Authentication (NGINX + Authentik)
75
+
76
+ If you want to hide the UI behind SSO (e.g. Authentik), you can delegate authentication to a reverse proxy and let this app **trust** specific headers **only** when requests come from an allowlisted proxy IP.
77
+
78
+ ### Server configuration
79
+
80
+ Set these env vars for the app:
81
+
82
+ - `AUTH_ENABLED=1`
83
+ - `TRUST_PROXY_AUTH=1`
84
+ - `TRUST_PROXY_IPS=127.0.0.1,::1` (comma-separated allowlist; use the _real_ proxy/container IPs)
85
+ - `TRUST_PROXY_USERNAME_HEADER=x-authentik-username`
86
+ - `TRUST_PROXY_GROUPS_HEADER=x-authentik-groups`
87
+ - `TRUST_PROXY_ADMIN_GROUP=admin` (if present in groups header → user becomes `admin`)
88
+
89
+ Security notes:
90
+
91
+ - **Never expose the app directly to the Internet** when `TRUST_PROXY_AUTH=1`.
92
+ - Always put it behind your reverse proxy and restrict inbound traffic to the proxy only.
93
+ - The app will ignore trusted headers unless the TCP peer IP matches `TRUST_PROXY_IPS`.
94
+
95
+ ### NGINX example (Authentik outpost)
96
+
97
+ This example assumes:
98
+
99
+ - Authentik outpost is available at `http://authentik-outpost:9000`.
100
+ - The app is at `http://nodelink-manager:3000`.
101
+
102
+ ```nginx
103
+ # Authentik integration (auth_request)
104
+ location = /outpost.goauthentik.io/auth/nginx {
105
+ internal;
106
+ proxy_pass http://authentik-outpost:9000/outpost.goauthentik.io/auth/nginx;
107
+ proxy_pass_request_body off;
108
+ proxy_set_header Content-Length "";
109
+ proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
110
+ proxy_set_header X-Original-Method $request_method;
111
+ proxy_set_header X-Original-Host $http_host;
112
+ }
113
+
114
+ location / {
115
+ auth_request /outpost.goauthentik.io/auth/nginx;
116
+ error_page 401 = @ak_unauthorized;
117
+
118
+ # Pull identity from Authentik response
119
+ auth_request_set $ak_username $upstream_http_x_authentik_username;
120
+ auth_request_set $ak_groups $upstream_http_x_authentik_groups;
121
+
122
+ proxy_pass http://nodelink-manager:3000;
123
+
124
+ # Forward identity headers to the app
125
+ proxy_set_header X-Authentik-Username $ak_username;
126
+ proxy_set_header X-Authentik-Groups $ak_groups;
127
+
128
+ # Good hygiene
129
+ proxy_set_header Host $host;
130
+ proxy_set_header X-Real-IP $remote_addr;
131
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
132
+ proxy_set_header X-Forwarded-Proto $scheme;
133
+ }
134
+
135
+ location @ak_unauthorized {
136
+ return 302 /outpost.goauthentik.io/start?rd=$scheme://$http_host$request_uri;
137
+ }
138
+ ```
139
+
140
+ If you run NGINX and the app on the same Docker network, set `TRUST_PROXY_IPS` to the **NGINX container IP** (or keep it `127.0.0.1,::1` only if NGINX is on the same host network namespace).
141
+
142
+ ### Production Build
143
+
144
+ ```bash
145
+ cd app
146
+ npm run build
147
+ npm start
148
+ ```
149
+
150
+ Open http://localhost:3000 in your browser.
151
+
152
+ ### Docker Deployment (Recommended)
153
+
154
+ The easiest way to run the Manager UI is with Docker:
155
+
156
+ ```bash
157
+ # Using pre-built image
158
+ docker pull ghcr.io/apocaliss92/nodelink-js-manager:latest
159
+
160
+ docker run -d \
161
+ --name nodelink-manager \
162
+ --network host \
163
+ -v nodelink-data:/data \
164
+ ghcr.io/apocaliss92/nodelink-js-manager:latest
165
+ ```
166
+
167
+ Or with Docker Compose:
168
+
169
+ ```bash
170
+ docker-compose up -d
171
+ ```
172
+
173
+ **Environment Variables:**
174
+
175
+ | Variable | Default | Description |
176
+ | ----------- | ------- | ------------------------------------ |
177
+ | `PORT` | `3000` | HTTP server port |
178
+ | `RTSP_PORT` | `8554` | RTSP proxy port |
179
+ | `DATA_PATH` | `/data` | Directory for settings.json and logs |
180
+
181
+ **Dashboard authentication (optional):**
182
+
183
+ | Variable | Default | Description |
184
+ | ---------------- | ------- | ----------------------------------------------------------------------------------------------------------------------- |
185
+ | `AUTH_ENABLED` | (unset) | Enable auth when set to `1/true` (or disable with `0/false`). If unset, auth auto-enables when `ADMIN_PASSWORD` is set. |
186
+ | `ADMIN_PASSWORD` | (unset) | Sets the `admin` password. This credential works for both the web login form and HTTP Basic auth. |
187
+
188
+ ### Streaming Authentication (RTSP / MJPEG / HLS / WebRTC)
189
+
190
+ When authentication is enabled (see `AUTH_ENABLED` / `ADMIN_PASSWORD`), **all streaming endpoints are protected**.
191
+
192
+ #### Step-by-step
193
+
194
+ 1. **Login to the Manager UI** (or use the API login) to obtain an auth token.
195
+ 2. (Recommended) **Generate a long-lived personal token** from **Settings → Personal token**.
196
+ 3. Use the correct auth mechanism depending on the streaming protocol:
197
+
198
+ - RTSP: **Digest** with username/password
199
+ - MJPEG/HLS: token in query string `?token=...`
200
+ - WebRTC signaling + status endpoints: `Authorization: Bearer ...`
201
+ - WebSocket logs: `?token=...` in the WS URL
202
+
203
+ There are two auth mechanisms depending on the protocol:
204
+
205
+ 1. **RTSP (RTSP proxy): Digest auth with username/password**
206
+
207
+ - URL format: `rtsp://<host>:<RTSP_PORT>/<camera>/<main|sub|ext>`
208
+ - Credentials: the same **Users** list used by the dashboard.
209
+ - Digest realm: `RTSP Proxy`
210
+ - You can toggle whether auth is required via the Manager UI setting **“Require auth for RTSP connections”**.
211
+
212
+ Examples:
213
+
214
+ ```bash
215
+ # ffmpeg (Digest)
216
+ ffmpeg -rtsp_transport tcp -i "rtsp://USERNAME:PASSWORD@HOST:8554/camera/main" -f null -
217
+
218
+ # VLC (it will prompt for credentials, or use URL user:pass)
219
+ vlc "rtsp://USERNAME:PASSWORD@HOST:8554/camera/main"
220
+ ```
221
+
222
+ 2. **HTTP-based streaming (MJPEG / HLS): token in query string**
223
+
224
+ Browsers cannot reliably attach custom headers (like `Authorization`) to media tags (`<img>`, `<video>`), so MJPEG/HLS streams must be accessed with the auth token in the URL query string:
225
+
226
+ - MJPEG: `/api/mpeg/<camera>/<profile>?token=...`
227
+ - HLS playlist: `/api/hls/<camera>/<profile>/playlist.m3u8?token=...` (and segment requests will inherit the query param)
228
+
229
+ Examples:
230
+
231
+ ```text
232
+ MJPEG:
233
+ http://HOST:3000/api/mpeg/camera/main?token=YOUR_TOKEN
234
+
235
+ HLS:
236
+ http://HOST:3000/api/hls/camera/main/playlist.m3u8?token=YOUR_TOKEN
237
+ ```
238
+
239
+ Security note: query tokens may end up in logs/history. Treat them like passwords.
240
+
241
+ 3. **WebRTC control endpoints: Bearer token in Authorization header**
242
+
243
+ WebRTC signaling uses JSON endpoints (create session, send ICE candidates, send answer) and supports standard Bearer auth:
244
+
245
+ ```bash
246
+ # 1) Login to obtain a token
247
+ curl -sS -X POST http://HOST:3000/api/auth/login \
248
+ -H 'content-type: application/json' \
249
+ -d '{"username":"admin","password":"YOUR_PASSWORD"}'
250
+
251
+ # 2) Use the returned token for WebRTC signaling
252
+ curl -sS http://HOST:3000/api/webrtc/status \
253
+ -H "Authorization: Bearer YOUR_TOKEN"
254
+ ```
255
+
256
+ You can also generate a personal token via API (requires an existing valid token):
257
+
258
+ ```bash
259
+ curl -sS -X POST http://HOST:3000/api/auth/personal-token \
260
+ -H "Authorization: Bearer YOUR_TOKEN" \
261
+ -H 'content-type: application/json' \
262
+ -d '{}'
263
+ ```
264
+
265
+ 4. **WebSocket logs: token in query string**
266
+
267
+ The browser WebSocket handshake cannot reliably attach custom headers, so use:
268
+
269
+ ```text
270
+ ws://HOST:3000/ws/logs?token=YOUR_TOKEN
271
+ ```
272
+
273
+ If authentication is disabled, these endpoints work without credentials.
274
+
275
+ Tip: a personal token is ideal for integrations (Home Assistant, scripts, etc.) because it does not expire.
276
+
277
+ 📖 **[Full Docker documentation →](./DOCKER.md)**
278
+
279
+ ---
280
+
33
281
  ## 📚 Full API Documentation
34
282
 
35
283
  For detailed method-by-method documentation, see the [documentation](./documentation/) folder:
@@ -9,7 +9,7 @@ import {
9
9
  runMultifocalDiagnosticsConsecutively,
10
10
  sampleStreams,
11
11
  testChannelStreams
12
- } from "./chunk-TZFZ5WJX.js";
12
+ } from "./chunk-ZE7D7LI4.js";
13
13
  export {
14
14
  collectCgiDiagnostics,
15
15
  collectMultifocalDiagnostics,
@@ -22,4 +22,4 @@ export {
22
22
  sampleStreams,
23
23
  testChannelStreams
24
24
  };
25
- //# sourceMappingURL=DiagnosticsTools-EC7DADEQ.js.map
25
+ //# sourceMappingURL=DiagnosticsTools-6WEMO4L4.js.map