@dainprotocol/tunnel 1.1.29 → 1.1.30
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/dist/client/index.js +35 -2
- package/package.json +10 -11
package/dist/client/index.js
CHANGED
|
@@ -31,6 +31,9 @@ class DainTunnel extends events_1.EventEmitter {
|
|
|
31
31
|
this.webSocketClients = new Map();
|
|
32
32
|
this.sseClients = new Map();
|
|
33
33
|
this.heartbeatInterval = null;
|
|
34
|
+
console.log('[DainTunnel] ========================================');
|
|
35
|
+
console.log('[DainTunnel] FIXED VERSION WITH X-FORWARDED-HOST SUPPORT');
|
|
36
|
+
console.log('[DainTunnel] ========================================');
|
|
34
37
|
const parsed = (0, auth_1.parseAPIKey)(apiKey);
|
|
35
38
|
if (!parsed) {
|
|
36
39
|
throw new Error('Invalid API key format. Expected: sk_agent_{agentId}_{orgId}_{secret}');
|
|
@@ -270,8 +273,16 @@ class DainTunnel extends events_1.EventEmitter {
|
|
|
270
273
|
this.safeSend({ type: 'websocket', id: message.id, event, data });
|
|
271
274
|
};
|
|
272
275
|
try {
|
|
276
|
+
// Preserve original host for JWT audience validation
|
|
277
|
+
const headers = { ...message.headers };
|
|
278
|
+
const originalHost = message.headers.host;
|
|
279
|
+
if (originalHost && !headers['x-forwarded-host']) {
|
|
280
|
+
headers['x-forwarded-host'] = originalHost;
|
|
281
|
+
headers['x-forwarded-proto'] = 'https';
|
|
282
|
+
}
|
|
283
|
+
delete headers.host; // Remove so WebSocket library doesn't send tunnel host to localhost
|
|
273
284
|
const client = new ws_1.default(`ws://localhost:${this.port}${message.path}`, {
|
|
274
|
-
headers
|
|
285
|
+
headers
|
|
275
286
|
});
|
|
276
287
|
this.webSocketClients.set(message.id, client);
|
|
277
288
|
client.on('message', (data) => {
|
|
@@ -315,8 +326,17 @@ class DainTunnel extends events_1.EventEmitter {
|
|
|
315
326
|
};
|
|
316
327
|
try {
|
|
317
328
|
const headers = { ...message.headers };
|
|
329
|
+
// Preserve original host for JWT audience validation
|
|
330
|
+
const originalHost = message.headers.host;
|
|
331
|
+
console.log(`[TunnelClient SSE] Original host from request: ${originalHost}`);
|
|
332
|
+
if (originalHost && !headers['x-forwarded-host']) {
|
|
333
|
+
headers['x-forwarded-host'] = originalHost;
|
|
334
|
+
headers['x-forwarded-proto'] = 'https';
|
|
335
|
+
console.log(`[TunnelClient SSE] Set x-forwarded-host: ${originalHost}`);
|
|
336
|
+
}
|
|
318
337
|
delete headers.host;
|
|
319
338
|
headers['accept-encoding'] = 'identity';
|
|
339
|
+
console.log(`[TunnelClient SSE] Forwarding to localhost:${this.port}${message.path} with x-forwarded-host: ${headers['x-forwarded-host']}`);
|
|
320
340
|
const req = http_1.default.request({
|
|
321
341
|
hostname: 'localhost',
|
|
322
342
|
port: this.port,
|
|
@@ -326,9 +346,11 @@ class DainTunnel extends events_1.EventEmitter {
|
|
|
326
346
|
agent: this.httpAgent,
|
|
327
347
|
}, (res) => {
|
|
328
348
|
if (res.statusCode !== 200) {
|
|
349
|
+
console.log(`[TunnelClient SSE] Got non-200 status: ${res.statusCode}`);
|
|
329
350
|
let errorBody = '';
|
|
330
351
|
res.on('data', (chunk) => { errorBody += chunk.toString(); });
|
|
331
352
|
res.on('end', () => {
|
|
353
|
+
console.log(`[TunnelClient SSE] Error body: ${errorBody.substring(0, 500)}`);
|
|
332
354
|
sendSseEvent('error', `Status ${res.statusCode}: ${errorBody.substring(0, 200)}`);
|
|
333
355
|
});
|
|
334
356
|
return;
|
|
@@ -419,12 +441,23 @@ class DainTunnel extends events_1.EventEmitter {
|
|
|
419
441
|
resolve(response);
|
|
420
442
|
}
|
|
421
443
|
};
|
|
444
|
+
// Preserve original host for JWT audience validation
|
|
445
|
+
const headers = { ...request.headers };
|
|
446
|
+
const originalHost = request.headers.host;
|
|
447
|
+
console.log(`[TunnelClient] Original host from request: ${originalHost}`);
|
|
448
|
+
if (originalHost && !headers['x-forwarded-host']) {
|
|
449
|
+
headers['x-forwarded-host'] = originalHost;
|
|
450
|
+
headers['x-forwarded-proto'] = 'https';
|
|
451
|
+
console.log(`[TunnelClient] Set x-forwarded-host: ${originalHost}`);
|
|
452
|
+
}
|
|
453
|
+
delete headers.host; // Remove so Node.js doesn't send the tunnel host to localhost
|
|
454
|
+
console.log(`[TunnelClient] Forwarding to localhost:${this.port}${request.path} with x-forwarded-host: ${headers['x-forwarded-host']}`);
|
|
422
455
|
const options = {
|
|
423
456
|
hostname: 'localhost',
|
|
424
457
|
port: this.port,
|
|
425
458
|
path: request.path,
|
|
426
459
|
method: request.method,
|
|
427
|
-
headers
|
|
460
|
+
headers,
|
|
428
461
|
agent: this.httpAgent,
|
|
429
462
|
timeout: TIMEOUTS.REQUEST,
|
|
430
463
|
};
|
package/package.json
CHANGED
|
@@ -1,21 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dainprotocol/tunnel",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.30",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"private": false,
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
10
|
-
"scripts": {
|
|
11
|
-
"build": "tsc",
|
|
12
|
-
"build:types": "tsc --emitDeclarationOnly",
|
|
13
|
-
"test": "jest",
|
|
14
|
-
"test:watch": "jest --watch",
|
|
15
|
-
"prepublishOnly": "npm run build && npm run build:types",
|
|
16
|
-
"start": "node dist/server/start.js",
|
|
17
|
-
"start-server": "ts-node src/server/start.ts"
|
|
18
|
-
},
|
|
19
10
|
"keywords": [],
|
|
20
11
|
"author": "Ryan",
|
|
21
12
|
"license": "ISC",
|
|
@@ -77,5 +68,13 @@
|
|
|
77
68
|
"./dist/server/*.d.ts"
|
|
78
69
|
]
|
|
79
70
|
}
|
|
71
|
+
},
|
|
72
|
+
"scripts": {
|
|
73
|
+
"build": "tsc",
|
|
74
|
+
"build:types": "tsc --emitDeclarationOnly",
|
|
75
|
+
"test": "jest",
|
|
76
|
+
"test:watch": "jest --watch",
|
|
77
|
+
"start": "node dist/server/start.js",
|
|
78
|
+
"start-server": "ts-node src/server/start.ts"
|
|
80
79
|
}
|
|
81
|
-
}
|
|
80
|
+
}
|