dsh-multi-chat 0.6.7 → 1.0.0

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.
Files changed (63) hide show
  1. package/README.md +20 -21
  2. package/README.zh.md +20 -21
  3. package/bin/dsh-multi-chat.mjs +5 -9
  4. package/lib/client.js +778 -0
  5. package/lib/client.js.map +1 -0
  6. package/{plugin/dsh-client-ui-multi-wall/lib → lib}/index.js +57 -69
  7. package/lib/tsconfig.tsbuildinfo +1 -0
  8. package/{plugin/dsh-client-ui-multi-wall/lib → lib}/types/client/WallToggle.d.ts +1 -1
  9. package/lib/types/client/WallToggle.d.ts.map +1 -0
  10. package/lib/types/client/WallToggle.js +36 -0
  11. package/lib/types/client/WallToggle.js.map +1 -0
  12. package/{plugin/dsh-client-ui-multi-wall/lib → lib}/types/client/WallView.d.ts +1 -1
  13. package/lib/types/client/WallView.d.ts.map +1 -0
  14. package/lib/types/client/WallView.js +218 -0
  15. package/lib/types/client/WallView.js.map +1 -0
  16. package/lib/types/client/index.d.ts.map +1 -0
  17. package/lib/types/client/index.js +59 -0
  18. package/lib/types/client/index.js.map +1 -0
  19. package/lib/types/client/locales.d.ts.map +1 -0
  20. package/lib/types/client/locales.js +96 -0
  21. package/lib/types/client/locales.js.map +1 -0
  22. package/lib/types/client/store.d.ts.map +1 -0
  23. package/lib/types/client/store.js +27 -0
  24. package/lib/types/client/store.js.map +1 -0
  25. package/lib/types/client/wall-injected.d.ts.map +1 -0
  26. package/lib/types/client/wall-injected.js +76 -0
  27. package/lib/types/client/wall-injected.js.map +1 -0
  28. package/lib/types/gateway.d.ts +57 -0
  29. package/lib/types/gateway.d.ts.map +1 -0
  30. package/lib/types/gateway.js +566 -0
  31. package/lib/types/gateway.js.map +1 -0
  32. package/{plugin/dsh-client-ui-multi-wall/lib → lib}/types/index.d.ts +1 -16
  33. package/lib/types/index.d.ts.map +1 -0
  34. package/lib/types/index.js +550 -0
  35. package/lib/types/index.js.map +1 -0
  36. package/lib/types/invariant.d.ts.map +1 -0
  37. package/lib/types/invariant.js +26 -0
  38. package/lib/types/invariant.js.map +1 -0
  39. package/package.json +31 -17
  40. package/scripts/install-plugin.ps1 +6 -9
  41. package/src/client/WallToggle.module.css +26 -0
  42. package/src/client/WallToggle.tsx +52 -0
  43. package/src/client/WallView.module.css +190 -0
  44. package/src/client/WallView.tsx +406 -0
  45. package/src/client/index.ts +103 -0
  46. package/src/client/locales.ts +100 -0
  47. package/src/client/store.ts +40 -0
  48. package/src/client/wall-injected.ts +123 -0
  49. package/src/css-modules.d.ts +5 -0
  50. package/src/gateway.ts +627 -0
  51. package/src/index.ts +618 -0
  52. package/src/invariant.ts +34 -0
  53. package/plugin/dsh-client-ui-multi-wall/README.md +0 -26
  54. package/plugin/dsh-client-ui-multi-wall/README.zh.md +0 -26
  55. package/plugin/dsh-client-ui-multi-wall/cordis.patch.yml +0 -7
  56. package/plugin/dsh-client-ui-multi-wall/lib/client.js +0 -781
  57. package/plugin/dsh-client-ui-multi-wall/lib/invariant.js +0 -27
  58. package/plugin/dsh-client-ui-multi-wall/package.json +0 -88
  59. /package/{plugin/dsh-client-ui-multi-wall/lib → lib}/types/client/index.d.ts +0 -0
  60. /package/{plugin/dsh-client-ui-multi-wall/lib → lib}/types/client/locales.d.ts +0 -0
  61. /package/{plugin/dsh-client-ui-multi-wall/lib → lib}/types/client/store.d.ts +0 -0
  62. /package/{plugin/dsh-client-ui-multi-wall/lib → lib}/types/client/wall-injected.d.ts +0 -0
  63. /package/{plugin/dsh-client-ui-multi-wall/lib → lib}/types/invariant.d.ts +0 -0
@@ -0,0 +1,566 @@
1
+ /**
2
+ * Inline authenticated gateway for the multi-wall plugin's node half.
3
+ *
4
+ * The official `dsh web` CLI forbids `--host 0.0.0.0` (it would expose remote
5
+ * code execution to the network), so reaching a loopback-only DSH instance
6
+ * from a phone/another machine needs an auth-gated gateway in front of it.
7
+ *
8
+ * This module embeds that gateway directly in the plugin (no external
9
+ * `gateway.mjs` file needed at runtime): a raw TCP listener that authenticates
10
+ * a token (HMAC-signed session cookie), then transparently proxies to
11
+ * `127.0.0.1:<target-port>`, rewriting Host/Origin so the official `/api`
12
+ * browser-trust fence treats it as a local request. WebSocket upgrades pass
13
+ * through untouched because the socket is piped byte-for-byte after the head.
14
+ * The HTML document response is buffered once so a `crypto.randomUUID`
15
+ * polyfill can be injected for phones (insecure-origin HTTP); all other
16
+ * responses stream through unchanged.
17
+ *
18
+ * Zero dependencies: node:net + node:crypto only.
19
+ * @module @deepseek-ai/dsh-client-ui-multi-wall/gateway
20
+ */
21
+ import { connect as netConnect } from 'node:net';
22
+ import { createServer } from 'node:net';
23
+ import { createHmac, timingSafeEqual } from 'node:crypto';
24
+ /** Constant-time hex string comparison (length-guarded). */
25
+ function safeEqualHex(left, right) {
26
+ const a = Buffer.from(left, 'hex');
27
+ const b = Buffer.from(right, 'hex');
28
+ return a.length !== 0 && a.length === b.length && timingSafeEqual(a, b);
29
+ }
30
+ /** Minimal HTTP/1.1 head parse; null until the head is complete. */
31
+ function parseHead(buffer) {
32
+ const idx = buffer.indexOf('\r\n\r\n');
33
+ if (idx === -1)
34
+ return null;
35
+ const head = buffer.subarray(0, idx + 4).toString('latin1');
36
+ const lines = head.split('\r\n');
37
+ const requestLine = lines[0]?.match(/^(\S+)\s+(\S+)\s+(HTTP\/\d\.\d)$/);
38
+ const headers = [];
39
+ const map = {};
40
+ for (const line of lines.slice(1)) {
41
+ const ci = line.indexOf(':');
42
+ if (ci === -1)
43
+ continue;
44
+ const name = line.slice(0, ci).trim().toLowerCase();
45
+ const value = line.slice(ci + 1).trim();
46
+ map[name] = value;
47
+ headers.push([name, value]);
48
+ }
49
+ return {
50
+ malformed: requestLine === null,
51
+ headBytes: idx + 4,
52
+ method: requestLine?.[1] ?? '',
53
+ target: requestLine?.[2] ?? '',
54
+ version: requestLine?.[3] ?? '',
55
+ headers,
56
+ map,
57
+ };
58
+ }
59
+ /** Pathname of a request target (defaults to '/' on parse failure). */
60
+ function targetPath(target) {
61
+ try {
62
+ return new URL(target, 'http://gateway.local').pathname;
63
+ }
64
+ catch {
65
+ return '/';
66
+ }
67
+ }
68
+ /** The dark-themed login page. */
69
+ function loginPage(name, next) {
70
+ const nxt = (next ?? '').replace(/"/g, '&quot;');
71
+ return `<!doctype html>
72
+ <html lang="zh-CN">
73
+ <head>
74
+ <meta charset="utf-8">
75
+ <meta name="viewport" content="width=device-width, initial-scale=1">
76
+ <title>${name} · 访问认证</title>
77
+ <style>
78
+ body { font-family: system-ui, sans-serif; background:#0d1117; color:#e6edf3;
79
+ display:flex; align-items:center; justify-content:center; min-height:100vh; margin:0; }
80
+ form { background:#161b22; border:1px solid #30363d; border-radius:12px;
81
+ padding:32px 36px; width:min(320px, 90vw); box-shadow:0 8px 30px #0006; }
82
+ h1 { font-size:16px; margin:0 0 18px; font-weight:600; }
83
+ label { font-size:13px; color:#8b949e; }
84
+ input { width:100%; box-sizing:border-box; margin:6px 0 16px; padding:9px 10px;
85
+ border-radius:8px; border:1px solid #30363d; background:#0d1117; color:#e6edf3; font-size:14px; }
86
+ button { width:100%; padding:10px; border:none; border-radius:8px; background:#2f81f7;
87
+ color:#fff; font-size:14px; font-weight:600; cursor:pointer; }
88
+ button:hover { background:#388bfd; }
89
+ </style>
90
+ </head>
91
+ <body>
92
+ <form method="post" action="/__gw__/login">
93
+ <h1>${name} · 需要访问口令</h1>
94
+ <label for="token">访问口令</label>
95
+ <input id="token" name="token" type="password" autofocus autocomplete="current-password">
96
+ <input type="hidden" name="next" value="${nxt}">
97
+ <button type="submit">进入</button>
98
+ </form>
99
+ </body>
100
+ </html>`;
101
+ }
102
+ /** Send the login page as a 401 HTML response. */
103
+ function respondLogin(socket, name, next) {
104
+ const body = Buffer.from(loginPage(name, next), 'utf8');
105
+ socket.write('HTTP/1.1 401 Unauthorized\r\n'
106
+ + 'content-type: text/html; charset=utf-8\r\n'
107
+ + `content-length: ${body.length}\r\n`
108
+ + 'connection: close\r\n'
109
+ + 'cache-control: no-store\r\n\r\n');
110
+ socket.write(body);
111
+ socket.end();
112
+ }
113
+ /** Send a small plain-text response and close the socket. */
114
+ function respondPlain(socket, status, text) {
115
+ const body = Buffer.from(text, 'utf8');
116
+ socket.write(`HTTP/1.1 ${status}\r\n`
117
+ + 'content-type: text/plain; charset=utf-8\r\n'
118
+ + `content-length: ${body.length}\r\n`
119
+ + 'connection: close\r\n'
120
+ + 'cache-control: no-store\r\n\r\n');
121
+ socket.write(body);
122
+ socket.end();
123
+ }
124
+ /**
125
+ * Send a 302 that mints a session cookie and drops the `token` query param.
126
+ * A `?token=` URL authenticates exactly one request, so on first arrival the
127
+ * gateway exchanges it for an HMAC-signed cookie and redirects to the same
128
+ * path without `token=` (keeps the secret out of the address bar / history).
129
+ */
130
+ function respondSessionRedirect(socket, parsed, cookie) {
131
+ let location = parsed.target;
132
+ try {
133
+ const url = new URL(parsed.target, 'http://gateway.local');
134
+ url.searchParams.delete('token');
135
+ location = url.pathname + url.search;
136
+ }
137
+ catch { /* keep raw target */ }
138
+ socket.write('HTTP/1.1 302 Found\r\n'
139
+ + `location: ${location}\r\n`
140
+ + `set-cookie: ${cookie}\r\n`
141
+ + 'content-length: 0\r\n'
142
+ + 'connection: close\r\n'
143
+ + 'cache-control: no-store\r\n\r\n');
144
+ socket.end();
145
+ }
146
+ /**
147
+ * `crypto.randomUUID` exists only in a *secure context* (HTTPS or localhost).
148
+ * A phone reaching the instance via `http://<LAN-IP>:<gateway-port>` is an
149
+ * insecure origin, so the official DSH client throws
150
+ * `crypto.randomUUID is not a function` on its first RPC and renders blank.
151
+ * This polyfill supplies the same RFC-4122 v4 form using
152
+ * `crypto.getRandomValues`, which insecure origins still expose.
153
+ */
154
+ const POLYFILL_SCRIPT = '<script>(function(){'
155
+ + 'if(typeof crypto!=="undefined"&&typeof crypto.randomUUID==="undefined"&&typeof crypto.getRandomValues==="function"){'
156
+ + 'crypto.randomUUID=function(){'
157
+ + 'var b=crypto.getRandomValues(new Uint8Array(16));'
158
+ + 'b[6]=(b[6]&15)|64;b[8]=(b[8]&63)|128;'
159
+ + 'var h=Array.prototype.map.call(b,function(x){return x.toString(16).padStart(2,"0")}).join("");'
160
+ + 'return h.slice(0,8)+"-"+h.slice(8,12)+"-"+h.slice(12,16)+"-"+h.slice(16,20)+"-"+h.slice(20);'
161
+ + '};}})();</script>';
162
+ /**
163
+ * Rewrite a buffered HTML response body to inject the `randomUUID` polyfill
164
+ * into the top of `<head>` (before the DSH bootstrap script runs). Returns the
165
+ * new body, or `null` when the polyfill is not needed (already present, or the
166
+ * response carries no `<head>` to inject into).
167
+ */
168
+ function injectPolyfill(body) {
169
+ const html = body.toString('utf8');
170
+ if (html.includes('randomUUID'))
171
+ return null;
172
+ const headMatch = /<head[^>]*>/i.exec(html);
173
+ if (headMatch === null)
174
+ return null;
175
+ const insertAt = headMatch.index + headMatch[0].length;
176
+ return Buffer.from(html.slice(0, insertAt) + POLYFILL_SCRIPT + html.slice(insertAt), 'utf8');
177
+ }
178
+ /**
179
+ * Rebuild the request head for the loopback target. Host and Origin point at
180
+ * `127.0.0.1:<target-port>` so the DSH `/api` browser-trust fence sees a local
181
+ * request. Non-upgrade requests get `connection: close` (fresh connection per
182
+ * request keeps keep-alive from smuggling unrewritten Host headers); upgrades
183
+ * (WebSocket) keep `connection: Upgrade`. When `pathOverride` is set (a
184
+ * `/gw/<port>` route), the request line's path becomes the de-prefixed path.
185
+ */
186
+ function rewriteHead(parsed, targetPort, pathOverride) {
187
+ const upgrade = parsed.map.upgrade !== undefined;
188
+ const requestTarget = pathOverride !== undefined ? pathOverride : parsed.target;
189
+ const lines = [`${parsed.method} ${requestTarget} ${parsed.version}`];
190
+ for (const [name, value] of parsed.headers) {
191
+ if (name === 'host') {
192
+ lines.push(`host: 127.0.0.1:${targetPort}`);
193
+ }
194
+ else if (name === 'origin') {
195
+ lines.push(`origin: http://127.0.0.1:${targetPort}`);
196
+ }
197
+ else if (name === 'connection' || name === 'proxy-connection') {
198
+ // dropped; re-added below with the right semantics
199
+ }
200
+ else {
201
+ lines.push(`${name}: ${value}`);
202
+ }
203
+ }
204
+ lines.push(upgrade ? 'connection: Upgrade' : 'connection: close');
205
+ return lines.join('\r\n') + '\r\n\r\n';
206
+ }
207
+ /**
208
+ * Start an in-process authenticated gateway for one loopback DSH instance.
209
+ * @param options - target, listen port, token, label, and lifetime.
210
+ * @returns a handle with the assigned port and token, and a close().
211
+ */
212
+ export function startGateway(options) {
213
+ const { targetPort, port: requestedPort, token, name, maxAgeHours = 12, routedPorts, log = () => { }, } = options;
214
+ const allowedRouted = new Set(routedPorts ?? []);
215
+ const hmac = (data) => createHmac('sha256', token).update(data).digest('hex');
216
+ const signSession = (exp) => {
217
+ const payload = Buffer.from(JSON.stringify({ exp })).toString('base64url');
218
+ return `${payload}.${hmac(payload)}`;
219
+ };
220
+ const verifySession = (value) => {
221
+ const dot = value.lastIndexOf('.');
222
+ if (dot <= 0)
223
+ return false;
224
+ const payload = value.slice(0, dot);
225
+ const sig = value.slice(dot + 1);
226
+ if (!safeEqualHex(sig, hmac(payload)))
227
+ return false;
228
+ try {
229
+ const parsed = JSON.parse(Buffer.from(payload, 'base64url').toString());
230
+ return typeof parsed.exp === 'number' && parsed.exp > Date.now();
231
+ }
232
+ catch {
233
+ return false;
234
+ }
235
+ };
236
+ const authKind = (parsed) => {
237
+ const cookie = parsed.map.cookie ?? '';
238
+ const session = /(?:^|;\s*)dsh_gw_session=([^;]+)/.exec(cookie);
239
+ if (session !== null && verifySession(session[1] ?? ''))
240
+ return 'cookie';
241
+ const bearer = parsed.map.authorization ?? '';
242
+ if (bearer.startsWith('Bearer ') && bearer.slice(7) === token)
243
+ return 'bearer';
244
+ try {
245
+ if (new URL(parsed.target, 'http://gateway.local').searchParams.get('token') === token)
246
+ return 'query';
247
+ }
248
+ catch { /* fall through */ }
249
+ return 'none';
250
+ };
251
+ // Rate limiting per source IP (login POST only).
252
+ const attempts = new Map();
253
+ const isBlocked = (ip) => {
254
+ const entry = attempts.get(ip);
255
+ return entry !== undefined && entry.blockedUntil !== undefined && entry.blockedUntil > Date.now();
256
+ };
257
+ const registerFailure = (ip) => {
258
+ const now = Date.now();
259
+ const entry = attempts.get(ip) ?? { fails: 0 };
260
+ if (entry.blockedUntil !== undefined && entry.blockedUntil > now)
261
+ return;
262
+ entry.fails += 1;
263
+ if (entry.fails >= 5) {
264
+ entry.fails = 0;
265
+ entry.blockedUntil = now + 60_000;
266
+ log(`rate-limited ${ip} for 60s`);
267
+ }
268
+ attempts.set(ip, entry);
269
+ if (attempts.size > 512) {
270
+ for (const [key, value] of attempts) {
271
+ if (value.fails === 0 && value.blockedUntil === undefined)
272
+ attempts.delete(key);
273
+ }
274
+ }
275
+ };
276
+ const handleLogin = (socket, parsed, initialBody) => {
277
+ let next = '/';
278
+ try {
279
+ next = new URL(parsed.target, 'http://gateway.local').searchParams.get('next') ?? '/';
280
+ }
281
+ catch { /* keep default */ }
282
+ if (!/^\/(?!\/)/.test(next))
283
+ next = '/';
284
+ if (parsed.method !== 'POST') {
285
+ respondLogin(socket, name, next);
286
+ return;
287
+ }
288
+ const ip = socket.remoteAddress ?? 'unknown';
289
+ if (isBlocked(ip)) {
290
+ respondPlain(socket, '429', 'too many login attempts, try again later');
291
+ return;
292
+ }
293
+ const contentLength = Number(parsed.map['content-length'] ?? 0);
294
+ if (!Number.isFinite(contentLength) || contentLength < 0 || contentLength > 16384) {
295
+ respondPlain(socket, '413', 'login body too large');
296
+ return;
297
+ }
298
+ let collected = Buffer.from(initialBody);
299
+ const done = () => {
300
+ socket.off('data', onBody);
301
+ const submitted = new URLSearchParams(collected.toString('utf8')).get('token') ?? '';
302
+ if (submitted === token) {
303
+ const cookie = `dsh_gw_session=${signSession(Date.now() + maxAgeHours * 3600_000)}; Path=/; HttpOnly; SameSite=Strict; Max-Age=${maxAgeHours * 3600}`;
304
+ socket.write('HTTP/1.1 302 Found\r\n'
305
+ + `location: ${next}\r\n`
306
+ + `set-cookie: ${cookie}\r\n`
307
+ + 'content-length: 0\r\n'
308
+ + 'connection: close\r\n\r\n');
309
+ socket.end();
310
+ log(`login ok from ${ip}`);
311
+ }
312
+ else {
313
+ registerFailure(ip);
314
+ log(`login FAILED from ${ip}`);
315
+ respondLogin(socket, name, next);
316
+ }
317
+ };
318
+ const onBody = (chunk) => {
319
+ collected = Buffer.concat([collected, chunk]);
320
+ if (collected.length >= contentLength)
321
+ done();
322
+ };
323
+ if (collected.length >= contentLength) {
324
+ done();
325
+ }
326
+ else {
327
+ socket.on('data', onBody);
328
+ socket.once('end', done);
329
+ }
330
+ };
331
+ /**
332
+ * Decode an HTTP/1.1 `transfer-encoding: chunked` body back to its raw
333
+ * bytes. Returns `null` on malformed framing (caller then relays verbatim).
334
+ */
335
+ const decodeChunked = (raw) => {
336
+ const out = [];
337
+ let i = 0;
338
+ const text = raw.toString('latin1');
339
+ while (true) {
340
+ const crlf = text.indexOf('\r\n', i);
341
+ if (crlf === -1)
342
+ return null;
343
+ const sizeHex = text.slice(i, crlf).trim();
344
+ const size = parseInt(sizeHex, 16);
345
+ if (!Number.isFinite(size) || size < 0)
346
+ return null;
347
+ i = crlf + 2;
348
+ if (size === 0) {
349
+ // trailing chunk: consume optional trailers up to the terminating CRLF.
350
+ return Buffer.concat(out);
351
+ }
352
+ if (i + size > raw.length)
353
+ return null;
354
+ out.push(raw.subarray(i, i + size));
355
+ i += size + 2; // skip data + CRLF
356
+ }
357
+ };
358
+ /**
359
+ * Relay the DSH target's response to the phone client. HTML document
360
+ * responses (the DSH shell) are buffered so the `randomUUID` polyfill can be
361
+ * injected before the bootstrap script runs; every other response
362
+ * (assets, API JSON, SSE streams, WebSocket upgrades) is piped byte-for-byte
363
+ * so streaming and framing stay untouched.
364
+ */
365
+ const relayTarget = (socket, target) => {
366
+ let head = Buffer.alloc(0);
367
+ let bodyParts = null;
368
+ let relayed = false;
369
+ const pipeThrough = () => {
370
+ if (relayed)
371
+ return;
372
+ relayed = true;
373
+ if (head.length > 0)
374
+ socket.write(head);
375
+ if (bodyParts !== null && bodyParts.length > 0) {
376
+ socket.write(Buffer.concat(bodyParts));
377
+ bodyParts = null;
378
+ }
379
+ target.pipe(socket);
380
+ };
381
+ const finishInjection = (fullHead, fullBody) => {
382
+ const rewritten = injectPolyfill(fullBody);
383
+ if (rewritten === null) {
384
+ socket.write(fullHead);
385
+ socket.write(fullBody);
386
+ socket.end();
387
+ return;
388
+ }
389
+ // Strip framing we can no longer honor (chunked / keep-alive) and emit
390
+ // the whole document with an exact content-length + connection: close.
391
+ const lines = fullHead.toString('latin1').split('\r\n');
392
+ const filtered = [];
393
+ for (const line of lines) {
394
+ const lower = line.toLowerCase();
395
+ if (lower.startsWith('transfer-encoding:'))
396
+ continue;
397
+ if (lower.startsWith('content-length:'))
398
+ continue;
399
+ if (lower.startsWith('connection:'))
400
+ continue;
401
+ filtered.push(line);
402
+ }
403
+ // Drop the trailing blank line(s) that separate head from body.
404
+ while (filtered.length > 0 && filtered[filtered.length - 1] === '')
405
+ filtered.pop();
406
+ filtered.push(`content-length: ${rewritten.length}`, 'connection: close', '', '');
407
+ socket.write(Buffer.from(filtered.join('\r\n'), 'latin1'));
408
+ socket.write(rewritten);
409
+ socket.end();
410
+ };
411
+ target.on('data', (chunk) => {
412
+ if (relayed)
413
+ return;
414
+ const idx = head.indexOf('\r\n\r\n');
415
+ if (idx === -1) {
416
+ head = head.length === 0 ? chunk : Buffer.concat([head, chunk]);
417
+ const newIdx = head.indexOf('\r\n\r\n');
418
+ if (newIdx === -1) {
419
+ if (head.length > 65536)
420
+ pipeThrough();
421
+ return;
422
+ }
423
+ // Head just completed: decide now whether to buffer the body.
424
+ const headBuf = head.subarray(0, newIdx + 4);
425
+ const bodyStart = head.subarray(newIdx + 4);
426
+ const headText = headBuf.toString('latin1');
427
+ const status = /^HTTP\/\d\.\d (\d{3})/.exec(headText)?.[1] ?? '';
428
+ const contentType = /^content-type:\s*([^\r\n]+)/im.exec(headText)?.[1] ?? '';
429
+ const ce = /^content-encoding:\s*([^\r\n]+)/im.exec(headText)?.[1] ?? '';
430
+ const isHtml = status === '200' && /text\/html/i.test(contentType);
431
+ const compressed = ce !== '' && !/identity/i.test(ce);
432
+ if (!isHtml || compressed) {
433
+ pipeThrough();
434
+ return;
435
+ }
436
+ bodyParts = bodyStart.length > 0 ? [bodyStart] : [];
437
+ return;
438
+ }
439
+ // Head already parsed and we chose to buffer: append body.
440
+ if (bodyParts !== null)
441
+ bodyParts.push(chunk);
442
+ });
443
+ target.once('end', () => {
444
+ if (relayed || bodyParts === null) {
445
+ if (!relayed)
446
+ socket.end();
447
+ return;
448
+ }
449
+ const headBuf = head.subarray(0, head.indexOf('\r\n\r\n') + 4);
450
+ const headText = headBuf.toString('latin1');
451
+ const rawBody = Buffer.concat(bodyParts);
452
+ const te = /^transfer-encoding:\s*([^\r\n]+)/im.exec(headText)?.[1] ?? '';
453
+ const body = /chunked/i.test(te) ? (decodeChunked(rawBody) ?? rawBody) : rawBody;
454
+ finishInjection(headBuf, body);
455
+ });
456
+ target.once('error', () => socket.destroy());
457
+ };
458
+ const handleSocket = (socket) => {
459
+ let buffer = Buffer.alloc(0);
460
+ let headDone = false;
461
+ let proxying = false;
462
+ const onData = (chunk) => {
463
+ if (headDone)
464
+ return;
465
+ buffer = buffer.length === 0 ? chunk : Buffer.concat([buffer, chunk]);
466
+ if (buffer.length > 65536) {
467
+ headDone = true;
468
+ respondPlain(socket, '431', 'request head too large');
469
+ return;
470
+ }
471
+ const parsed = parseHead(buffer);
472
+ if (parsed === null)
473
+ return;
474
+ headDone = true;
475
+ if (parsed.malformed) {
476
+ respondPlain(socket, '400', 'malformed request');
477
+ return;
478
+ }
479
+ const path = targetPath(parsed.target);
480
+ if (path === '/__gw__/login') {
481
+ handleLogin(socket, parsed, buffer.subarray(parsed.headBytes));
482
+ return;
483
+ }
484
+ // `/gw/<port>/<path>` routes to a sibling loopback instance (the wall's
485
+ // phone panes). Only ports the host explicitly allowed are reachable, so
486
+ // the phone cannot probe arbitrary loopback services.
487
+ let routePort = null;
488
+ let routePath;
489
+ const routeMatch = /^\/gw\/(\d+)(\/.*)?$/.exec(path);
490
+ if (routeMatch !== null) {
491
+ const candidate = Number(routeMatch[1]);
492
+ if (!Number.isInteger(candidate) || candidate <= 0 || !allowedRouted.has(candidate)) {
493
+ respondPlain(socket, '403', 'port not routable');
494
+ return;
495
+ }
496
+ routePort = candidate;
497
+ routePath = routeMatch[2] && routeMatch[2] !== '' ? routeMatch[2] : '/';
498
+ }
499
+ const effectivePort = routePort ?? targetPort;
500
+ const kind = authKind(parsed);
501
+ if (kind === 'none') {
502
+ respondLogin(socket, name, path === '/' ? '/' : path);
503
+ return;
504
+ }
505
+ // A `?token=` query authenticates only this request; exchange it for a
506
+ // session cookie and redirect (token dropped) so the browser stays
507
+ // authorized across the page's follow-up fetches without carrying the
508
+ // secret in every URL.
509
+ if (kind === 'query') {
510
+ const cookie = `dsh_gw_session=${signSession(Date.now() + maxAgeHours * 3600_000)}; Path=/; HttpOnly; SameSite=Strict; Max-Age=${maxAgeHours * 3600}`;
511
+ respondSessionRedirect(socket, parsed, cookie);
512
+ return;
513
+ }
514
+ const target = netConnect(effectivePort, '127.0.0.1');
515
+ const rest = buffer.subarray(parsed.headBytes);
516
+ let connected = false;
517
+ target.on('connect', () => {
518
+ connected = true;
519
+ target.write(rewriteHead(parsed, effectivePort, routePath));
520
+ if (rest.length > 0)
521
+ target.write(rest);
522
+ proxying = true;
523
+ socket.pipe(target);
524
+ relayTarget(socket, target);
525
+ });
526
+ target.on('error', (error) => {
527
+ if (!connected) {
528
+ respondPlain(socket, '502', `cannot reach target 127.0.0.1:${effectivePort}: ${error.message}`);
529
+ }
530
+ socket.destroy();
531
+ });
532
+ socket.on('error', () => target.destroy());
533
+ socket.on('close', () => { if (proxying)
534
+ target.destroy(); });
535
+ };
536
+ socket.on('data', onData);
537
+ socket.on('error', () => { socket.destroy(); });
538
+ };
539
+ return new Promise((resolve, reject) => {
540
+ const server = createServer(handleSocket);
541
+ const onError = (error) => {
542
+ // EACCES (Windows excluded port range / no bind permission) and
543
+ // EADDRINUSE (port taken) fall back to an OS-assigned free port.
544
+ if ((error.code === 'EACCES' || error.code === 'EADDRINUSE') && requestedPort !== 0) {
545
+ log(`gateway port ${requestedPort} unavailable (${error.code}), using an OS-assigned port`);
546
+ server.listen(0, '0.0.0.0');
547
+ return;
548
+ }
549
+ server.removeListener('error', onError);
550
+ reject(error);
551
+ };
552
+ server.on('error', onError);
553
+ server.listen(requestedPort, '0.0.0.0', () => {
554
+ server.removeListener('error', onError);
555
+ const address = server.address();
556
+ const assignedPort = typeof address === 'object' && address !== null ? address.port : requestedPort;
557
+ log(`gateway listening 0.0.0.0:${assignedPort} -> 127.0.0.1:${targetPort}`);
558
+ resolve({
559
+ port: assignedPort,
560
+ token,
561
+ close: () => { server.close(); },
562
+ });
563
+ });
564
+ });
565
+ }
566
+ //# sourceMappingURL=gateway.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.js","sourceRoot":"","sources":["../../src/gateway.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,6 @@
7
7
  * @module @deepseek-ai/dsh-client-ui-multi-wall
8
8
  */
9
9
  import type { Context } from '@deepseek-ai/cordis';
10
- import z from '@deepseek-ai/schemastery';
11
10
  /** Stable Cordis plugin name. */
12
11
  export declare const name = "client-ui-multi-wall";
13
12
  /** Services required before the probe routes can be registered. */
@@ -38,21 +37,7 @@ export interface MultiWallConfig {
38
37
  gatewayToken?: string;
39
38
  }
40
39
  /** Schema-validated config (the Loader resolves defaults for absent keys). */
41
- export declare const Config: z<Schemastery.ObjectS<{
42
- scanFrom: z<number, number>;
43
- scanTo: z<number, number>;
44
- ports: z<number[], number[]>;
45
- publicUrl: z<string, string>;
46
- gatewayPort: z<number, number>;
47
- gatewayToken: z<string, string>;
48
- }>, Schemastery.ObjectT<{
49
- scanFrom: z<number, number>;
50
- scanTo: z<number, number>;
51
- ports: z<number[], number[]>;
52
- publicUrl: z<string, string>;
53
- gatewayPort: z<number, number>;
54
- gatewayToken: z<string, string>;
55
- }>>;
40
+ export declare const Config: any;
56
41
  /** One stop result row from /multi/api/stop. */
57
42
  export interface StopRow {
58
43
  port: number;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAKlD,iCAAiC;AACjC,eAAO,MAAM,IAAI,yBAAyB,CAAA;AAE1C,mEAAmE;AACnE,eAAO,MAAM,MAAM,UAAgB,CAAA;AAEnC,2DAA2D;AAC3D,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,8EAA8E;AAC9E,eAAO,MAAM,MAAM,KAOjB,CAAA;AAkDF,gDAAgD;AAChD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,OAAO,CAAA;IACX,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAgED;;;;;;;;GAQG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiB/E;AAiND;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,eAAoB,GAAG,IAAI,CAqMtE"}