dsh-remote-control-plugin 0.3.1 → 0.3.2
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/INSTALL.md +5 -4
- package/host/fabric.js +23 -7
- package/index.js +6 -1
- package/package.json +1 -1
package/INSTALL.md
CHANGED
|
@@ -5,7 +5,7 @@ build step, no postinstall script.
|
|
|
5
5
|
|
|
6
6
|
## 1. Install it
|
|
7
7
|
|
|
8
|
-
In the Web GUI: **Plugins → Add plugin**, enter `dsh-remote-control-plugin@0.3.
|
|
8
|
+
In the Web GUI: **Plugins → Add plugin**, enter `dsh-remote-control-plugin@0.3.2`, keep the
|
|
9
9
|
official npm registry selected, then **Install** and **Enable now**. Restart DSH.
|
|
10
10
|
|
|
11
11
|
A **Devices** icon appears in the sidebar.
|
|
@@ -13,7 +13,7 @@ A **Devices** icon appears in the sidebar.
|
|
|
13
13
|
From a chat, the same install works where the plugin tool is enabled (Standard or Creator
|
|
14
14
|
preset — PTC disables `tool-plugin-manager`):
|
|
15
15
|
|
|
16
|
-
> Install the DSH plugin bundle `dsh-remote-control-plugin@0.3.
|
|
16
|
+
> Install the DSH plugin bundle `dsh-remote-control-plugin@0.3.2` with plugin_manager, then tell me when it is applied.
|
|
17
17
|
|
|
18
18
|
## 2. Connect two machines
|
|
19
19
|
|
|
@@ -34,5 +34,6 @@ paste `http://<host>:8787 <workspace key>` into both panels.
|
|
|
34
34
|
- Approvals persist in `$DSH_HOME/remote-control-peers.json`; deleting it revokes every peer.
|
|
35
35
|
- The relay and the control API share one port (default `57330`), so one forwarded port is enough.
|
|
36
36
|
- Peer traffic is signed but not encrypted. Use a private network or TLS in front of the port.
|
|
37
|
-
- 0.3.
|
|
38
|
-
|
|
37
|
+
- 0.3.2 fixes three relay bugs: a hosted relay now survives a restart, peers no
|
|
38
|
+
longer linger as `503 relay-offline` after a relay goes away, and a blocked
|
|
39
|
+
direct LAN route falls back to the outbound relay instead of failing.
|
package/host/fabric.js
CHANGED
|
@@ -374,8 +374,17 @@ export function createFabric({ log, config, self, sessions, stateFile }) {
|
|
|
374
374
|
*/
|
|
375
375
|
async function peerCall(peer, method, pathname, body, secret) {
|
|
376
376
|
if (peer.proto !== 'relay') {
|
|
377
|
-
|
|
377
|
+
const direct = await callRaw(peer, method, pathname, body, secret, self().deviceId)
|
|
378
|
+
// A direct LAN route can be silently blocked (firewall profile, VPN
|
|
379
|
+
// change). The relay is outbound-only, so fall back instead of failing.
|
|
380
|
+
if (!direct.error || !relay) return direct
|
|
381
|
+
const viaRelay = await relayCall(peer, method, pathname, body, secret)
|
|
382
|
+
return viaRelay.ok || viaRelay.status !== 503 ? viaRelay : direct
|
|
378
383
|
}
|
|
384
|
+
return relayCall(peer, method, pathname, body, secret)
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
async function relayCall(peer, method, pathname, body, secret) {
|
|
379
388
|
if (!relay) return { ok: false, status: 503, json: { error: 'relay-offline' } }
|
|
380
389
|
const callerId = self().deviceId
|
|
381
390
|
const timestamp = String(Date.now())
|
|
@@ -439,17 +448,18 @@ export function createFabric({ log, config, self, sessions, stateFile }) {
|
|
|
439
448
|
}, res)
|
|
440
449
|
return
|
|
441
450
|
}
|
|
451
|
+
const streamHeaders = {
|
|
452
|
+
accept: 'text/event-stream',
|
|
453
|
+
'x-dsh-peer-id': callerId,
|
|
454
|
+
'x-dsh-peer-ts': timestamp,
|
|
455
|
+
'x-dsh-peer-sig': sign(approval.secret, callerId, 'GET', target, timestamp, ''),
|
|
456
|
+
}
|
|
442
457
|
const upstream = http.request({
|
|
443
458
|
host: peer.address,
|
|
444
459
|
port: peer.port,
|
|
445
460
|
path: target,
|
|
446
461
|
method: 'GET',
|
|
447
|
-
headers:
|
|
448
|
-
accept: 'text/event-stream',
|
|
449
|
-
'x-dsh-peer-id': callerId,
|
|
450
|
-
'x-dsh-peer-ts': timestamp,
|
|
451
|
-
'x-dsh-peer-sig': sign(approval.secret, callerId, 'GET', target, timestamp, ''),
|
|
452
|
-
},
|
|
462
|
+
headers: streamHeaders,
|
|
453
463
|
}, (response) => {
|
|
454
464
|
res.writeHead(response.statusCode ?? 502, {
|
|
455
465
|
'content-type': response.headers['content-type'] || 'text/event-stream; charset=utf-8',
|
|
@@ -461,6 +471,12 @@ export function createFabric({ log, config, self, sessions, stateFile }) {
|
|
|
461
471
|
response.on('end', () => { try { res.end() } catch { /* ignore */ } })
|
|
462
472
|
})
|
|
463
473
|
upstream.on('error', () => {
|
|
474
|
+
// Same fallback as peerCall: a blocked LAN route may still reach the
|
|
475
|
+
// peer through the outbound relay.
|
|
476
|
+
if (relay && !res.headersSent) {
|
|
477
|
+
relay.stream(peer.deviceId, { path: target, headers: streamHeaders }, res)
|
|
478
|
+
return
|
|
479
|
+
}
|
|
464
480
|
try { json(res, 502, { error: 'peer-unreachable' }) } catch { /* ignore */ }
|
|
465
481
|
})
|
|
466
482
|
res.on('close', () => { try { upstream.destroy() } catch { /* ignore */ } })
|
package/index.js
CHANGED
|
@@ -157,7 +157,12 @@ export function apply(ctx, rawConfig) {
|
|
|
157
157
|
async function loadRelayConfig() {
|
|
158
158
|
try {
|
|
159
159
|
const raw = JSON.parse(await readFile(relayFile, 'utf8'))
|
|
160
|
-
if (raw && typeof raw.url === 'string' && typeof raw.key === 'string')
|
|
160
|
+
if (raw && typeof raw.url === 'string' && typeof raw.key === 'string') {
|
|
161
|
+
// `hosted` decides whether boot remounts the relay before connecting.
|
|
162
|
+
// Dropping it made every restart fall into the join branch, which then
|
|
163
|
+
// pointed at an unmounted /v1/* and left the relay dead.
|
|
164
|
+
return { hosted: raw.hosted === true, url: raw.url, key: raw.key }
|
|
165
|
+
}
|
|
161
166
|
} catch (error) {
|
|
162
167
|
if (error?.code !== 'ENOENT') log.warn(`[remote-control] could not read ${relayFile}: ${error?.message || error}`)
|
|
163
168
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-remote-control-plugin",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Remote control for DSH: a Devices panel that discovers other DSH desktops, pairs with them once, and drives their sessions across LAN or a relay.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|