dsh-relay-phone 0.11.2 → 0.11.3
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/package.json +1 -1
- package/src/index.js +18 -0
- package/src/pump.js +17 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-relay-phone",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.3",
|
|
4
4
|
"description": "Remote-control your local DeepSeek Harness from a phone through your own zero-knowledge relay: phone-first page, QR pairing, end-to-end encryption, approvals, full desktop UI fallback.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
package/src/index.js
CHANGED
|
@@ -165,6 +165,23 @@ export default class RelayBridgeService extends Service {
|
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
/**
|
|
169
|
+
* The root token DSH 0.2 wants on the index exchange. A browser that opens the
|
|
170
|
+
* desktop UI locally already has it in its URL; one arriving through the relay
|
|
171
|
+
* does not, which is why that shell used to come back unauthenticated.
|
|
172
|
+
*/
|
|
173
|
+
upstreamIndexToken() {
|
|
174
|
+
const connection = this.ctx.get('connection')
|
|
175
|
+
if (!connection || typeof connection.authenticatedUrl !== 'function') return null
|
|
176
|
+
try {
|
|
177
|
+
const target = this.upstreamTarget()
|
|
178
|
+
const url = new URL(connection.authenticatedUrl(`${target.protocol}//${target.authority}/`))
|
|
179
|
+
return url.searchParams.get('token')
|
|
180
|
+
} catch {
|
|
181
|
+
return null
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
168
185
|
mergeConfig(base, stored) {
|
|
169
186
|
return {
|
|
170
187
|
relayScheme: stored.relayScheme ?? base.relayScheme ?? 'http',
|
|
@@ -219,6 +236,7 @@ export default class RelayBridgeService extends Service {
|
|
|
219
236
|
dshPort: this.config.dshPort,
|
|
220
237
|
resolveTarget: () => this.upstreamTarget(),
|
|
221
238
|
resolveAuthCookie: () => this.upstreamAuthCookie(),
|
|
239
|
+
resolveIndexToken: () => this.upstreamIndexToken(),
|
|
222
240
|
pairing: this.pairing,
|
|
223
241
|
cryptoBox: this.cryptoBox,
|
|
224
242
|
mobile: this.mobile,
|
package/src/pump.js
CHANGED
|
@@ -59,6 +59,8 @@ export class PumpManager {
|
|
|
59
59
|
protocol: 'http:',
|
|
60
60
|
}))
|
|
61
61
|
this.resolveAuthCookie = options.resolveAuthCookie ?? (() => null)
|
|
62
|
+
// Root token for DSH 0.2's index exchange; null on older hosts.
|
|
63
|
+
this.resolveIndexToken = options.resolveIndexToken ?? (() => null)
|
|
62
64
|
this.pairing = options.pairing // PairingService
|
|
63
65
|
this.cryptoBox = options.cryptoBox
|
|
64
66
|
this.client = options.client
|
|
@@ -641,7 +643,21 @@ export class PumpManager {
|
|
|
641
643
|
// Any inbound copy was dropped in the loop above, so a client cannot forge it.
|
|
642
644
|
rewritten.push('x-dsh-relay: 1')
|
|
643
645
|
if (authCookie) rewritten.push(`Cookie: ${authCookie}`)
|
|
644
|
-
|
|
646
|
+
|
|
647
|
+
// DSH 0.2 guards the index exchange with a root token, and the pump already
|
|
648
|
+
// uses that token to mint the API cookie. A browser arriving through the
|
|
649
|
+
// relay has no token of its own, so the desktop shell it received came back
|
|
650
|
+
// unauthenticated even though every later API call would have worked.
|
|
651
|
+
let requestLine = lines[0]
|
|
652
|
+
if (stream.relay && isDocument && !isUpgrade && info.path === '/') {
|
|
653
|
+
const token = this.resolveIndexToken()
|
|
654
|
+
if (token) {
|
|
655
|
+
const query = new URLSearchParams(info.query)
|
|
656
|
+
query.set('token', token)
|
|
657
|
+
requestLine = `${info.method} /?${query.toString()} ${info.version}`
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
const out = `${requestLine}\r\n${rewritten.join('\r\n')}\r\n\r\n`
|
|
645
661
|
|
|
646
662
|
if (isUpgrade) {
|
|
647
663
|
const upstream = net.connect({ host: target.host, port: target.port })
|