portprism 2.0.3 → 2.0.5
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 +144 -0
- package/dist/index.js +557 -107
- package/package.json +22 -6
- package/dist/__tests__/inspector.test.d.ts +0 -2
- package/dist/__tests__/inspector.test.d.ts.map +0 -1
- package/dist/__tests__/inspector.test.js +0 -80
- package/dist/__tests__/inspector.test.js.map +0 -1
- package/dist/agent.d.ts +0 -78
- package/dist/agent.d.ts.map +0 -1
- package/dist/agent.js +0 -357
- package/dist/agent.js.map +0 -1
- package/dist/authStore.d.ts +0 -14
- package/dist/authStore.d.ts.map +0 -1
- package/dist/authStore.js +0 -34
- package/dist/authStore.js.map +0 -1
- package/dist/config.d.ts +0 -13
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -32
- package/dist/config.js.map +0 -1
- package/dist/display.d.ts +0 -37
- package/dist/display.d.ts.map +0 -1
- package/dist/display.js +0 -113
- package/dist/display.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/inspector.d.ts +0 -58
- package/dist/inspector.d.ts.map +0 -1
- package/dist/inspector.js +0 -328
- package/dist/inspector.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,16 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "portprism",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Share your local server with anyone, instantly.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"tunnel",
|
|
8
|
+
"localhost",
|
|
9
|
+
"localhost-tunnel",
|
|
10
|
+
"reverse-proxy",
|
|
11
|
+
"port-forwarding",
|
|
12
|
+
"expose",
|
|
13
|
+
"share",
|
|
14
|
+
"preview",
|
|
15
|
+
"webhook",
|
|
16
|
+
"webhook-testing",
|
|
17
|
+
"https",
|
|
18
|
+
"websocket",
|
|
19
|
+
"developer-tools",
|
|
20
|
+
"cli",
|
|
21
|
+
"mcp"
|
|
22
|
+
],
|
|
6
23
|
"type": "module",
|
|
7
24
|
"bin": {
|
|
8
25
|
"portprism": "dist/index.js"
|
|
9
26
|
},
|
|
27
|
+
"author": "Port Prism <info@portprism.io>",
|
|
10
28
|
"files": [
|
|
11
|
-
"dist"
|
|
29
|
+
"dist/index.js"
|
|
12
30
|
],
|
|
13
|
-
"homepage": "https://
|
|
31
|
+
"homepage": "https://portprism.io",
|
|
14
32
|
"publishConfig": {
|
|
15
33
|
"access": "public"
|
|
16
34
|
},
|
|
@@ -18,8 +36,7 @@
|
|
|
18
36
|
"build": "esbuild src/index.ts --bundle --platform=node --format=esm --outfile=dist/index.js --banner:js=\"#!/usr/bin/env node\nimport { createRequire as _createRequire } from 'module';\nimport { fileURLToPath as _fileURLToPath } from 'url';\nconst require = _createRequire(import.meta.url);\nconst __filename = _fileURLToPath(import.meta.url);\nconst __dirname = _fileURLToPath(new URL('.', import.meta.url));\"",
|
|
19
37
|
"dev": "tsc --watch",
|
|
20
38
|
"lint": "eslint src/",
|
|
21
|
-
"
|
|
22
|
-
"test": "echo \"No tests yet\" && exit 0"
|
|
39
|
+
"test": "tsc -p tsconfig.test.json && node --test dist/__tests__/inspector.test.js"
|
|
23
40
|
},
|
|
24
41
|
"dependencies": {
|
|
25
42
|
"chalk": "^4.1.2",
|
|
@@ -31,7 +48,6 @@
|
|
|
31
48
|
"ws": "^7.5.10"
|
|
32
49
|
},
|
|
33
50
|
"devDependencies": {
|
|
34
|
-
"@types/node": "^26.1.0",
|
|
35
51
|
"@types/qrcode": "^1.5.6",
|
|
36
52
|
"@types/ws": "^8.18.1",
|
|
37
53
|
"esbuild": "^0.25.12",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"inspector.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/inspector.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { describe, it, before, after } from "node:test";
|
|
2
|
-
import assert from "node:assert/strict";
|
|
3
|
-
import { Inspector } from "../inspector.js";
|
|
4
|
-
describe("Inspector", () => {
|
|
5
|
-
let insp;
|
|
6
|
-
let base;
|
|
7
|
-
before(async () => {
|
|
8
|
-
insp = new Inspector();
|
|
9
|
-
const url = await insp.start(0); // ephemeral port
|
|
10
|
-
assert.ok(url, "inspector should bind an ephemeral port");
|
|
11
|
-
base = url;
|
|
12
|
-
});
|
|
13
|
-
after(() => insp.stop());
|
|
14
|
-
const b64 = (s) => Buffer.from(s).toString("base64");
|
|
15
|
-
it("records a request, splits the query, and merges the response phase", async () => {
|
|
16
|
-
insp.record({
|
|
17
|
-
phase: "request",
|
|
18
|
-
id: "req-1",
|
|
19
|
-
ts: Date.now(),
|
|
20
|
-
method: "POST",
|
|
21
|
-
path: "/api/items?q=hello&limit=5",
|
|
22
|
-
headers: { "content-type": "application/json" },
|
|
23
|
-
body: b64('{"hello":"world"}'),
|
|
24
|
-
});
|
|
25
|
-
insp.record({
|
|
26
|
-
phase: "response",
|
|
27
|
-
id: "req-1",
|
|
28
|
-
status: 201,
|
|
29
|
-
headers: { "content-type": "application/json" },
|
|
30
|
-
body: b64('{"ok":true}'),
|
|
31
|
-
durationMs: 42,
|
|
32
|
-
});
|
|
33
|
-
const detail = (await (await fetch(`${base}/__pp/requests/req-1`)).json());
|
|
34
|
-
assert.equal(detail.method, "POST");
|
|
35
|
-
assert.equal(detail.path, "/api/items", "query must be split off the path");
|
|
36
|
-
assert.deepEqual(detail.query, { q: "hello", limit: "5" });
|
|
37
|
-
assert.equal(detail.reqBody.text, '{"hello":"world"}', "text body decoded, not base64");
|
|
38
|
-
assert.equal(detail.reqBody.binary, false);
|
|
39
|
-
assert.equal(detail.status, 201);
|
|
40
|
-
assert.equal(detail.resBody?.text, '{"ok":true}');
|
|
41
|
-
assert.equal(detail.durationMs, 42);
|
|
42
|
-
assert.equal(detail.pending, false, "record is no longer pending after response");
|
|
43
|
-
});
|
|
44
|
-
it("flags binary payloads and keeps them base64", async () => {
|
|
45
|
-
insp.record({
|
|
46
|
-
phase: "request",
|
|
47
|
-
id: "req-bin",
|
|
48
|
-
method: "PUT",
|
|
49
|
-
path: "/upload",
|
|
50
|
-
headers: { "content-type": "application/octet-stream" },
|
|
51
|
-
body: Buffer.from([0x00, 0x01, 0x02, 0xff]).toString("base64"),
|
|
52
|
-
});
|
|
53
|
-
const detail = (await (await fetch(`${base}/__pp/requests/req-bin`)).json());
|
|
54
|
-
assert.equal(detail.reqBody.binary, true);
|
|
55
|
-
assert.equal(detail.reqBody.text, Buffer.from([0x00, 0x01, 0x02, 0xff]).toString("base64"));
|
|
56
|
-
});
|
|
57
|
-
it("caps the ledger at 200 records (ring buffer)", async () => {
|
|
58
|
-
for (let i = 0; i < 250; i++) {
|
|
59
|
-
insp.record({
|
|
60
|
-
phase: "request",
|
|
61
|
-
id: `bulk-${i}`,
|
|
62
|
-
method: "GET",
|
|
63
|
-
path: `/x/${i}`,
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
const list = (await (await fetch(`${base}/__pp/requests`)).json());
|
|
67
|
-
assert.ok(list.length <= 200, `expected <=200 records, got ${list.length}`);
|
|
68
|
-
// Oldest bulk entry should have been evicted.
|
|
69
|
-
const gone = await fetch(`${base}/__pp/requests/bulk-0`);
|
|
70
|
-
assert.equal(gone.status, 404, "oldest record should be evicted");
|
|
71
|
-
});
|
|
72
|
-
it("serves the web UI and returns 404 for unknown ids", async () => {
|
|
73
|
-
const html = await fetch(`${base}/`);
|
|
74
|
-
assert.equal(html.status, 200);
|
|
75
|
-
assert.match(await html.text(), /PortPrism/);
|
|
76
|
-
const missing = await fetch(`${base}/__pp/requests/does-not-exist`);
|
|
77
|
-
assert.equal(missing.status, 404);
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
//# sourceMappingURL=inspector.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"inspector.test.js","sourceRoot":"","sources":["../../src/__tests__/inspector.test.ts"],"names":[],"mappings":"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"}
|
package/dist/agent.d.ts
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from "node:events";
|
|
2
|
-
/**
|
|
3
|
-
* Manages exponential-backoff reconnection with jitter.
|
|
4
|
-
*
|
|
5
|
-
* Usage:
|
|
6
|
-
* const mgr = new ReconnectionManager();
|
|
7
|
-
* await mgr.scheduleReconnect(() => openSocket(), onWaiting);
|
|
8
|
-
*/
|
|
9
|
-
export declare class ReconnectionManager {
|
|
10
|
-
private attempts;
|
|
11
|
-
private readonly maxAttempts;
|
|
12
|
-
private readonly baseDelay;
|
|
13
|
-
private readonly maxDelay;
|
|
14
|
-
/**
|
|
15
|
-
* Compute the next delay with full-jitter:
|
|
16
|
-
* base = min(baseDelay × 2^attempts, maxDelay)
|
|
17
|
-
* result = base + base × 0.2 × random()
|
|
18
|
-
*/
|
|
19
|
-
getDelay(): number;
|
|
20
|
-
/** Reset the attempt counter after a successful connection. */
|
|
21
|
-
reset(): void;
|
|
22
|
-
/** Returns true when the max retry budget has been exhausted. */
|
|
23
|
-
shouldGiveUp(): boolean;
|
|
24
|
-
/**
|
|
25
|
-
* Wait for the computed back-off delay, then call `connectFn`.
|
|
26
|
-
*
|
|
27
|
-
* @param connectFn Function that initiates a new WebSocket connection.
|
|
28
|
-
* @param onWaiting Optional callback fired just before sleeping.
|
|
29
|
-
* Receives `(delayMs, attempt, maxAttempts)` so callers
|
|
30
|
-
* can update the UI without coupling the manager to display code.
|
|
31
|
-
*/
|
|
32
|
-
scheduleReconnect(connectFn: () => void, onWaiting?: (delayMs: number, attempt: number, maxAttempts: number) => void): Promise<void>;
|
|
33
|
-
}
|
|
34
|
-
export interface AgentOptions {
|
|
35
|
-
name: string;
|
|
36
|
-
desc: string;
|
|
37
|
-
password?: string;
|
|
38
|
-
relay: string;
|
|
39
|
-
noOpen: boolean;
|
|
40
|
-
/** JWT from ~/.portlens/config.json — forwarded to relay for userId resolution */
|
|
41
|
-
jwtToken?: string;
|
|
42
|
-
/** Skip automatic screenshot capture after connect */
|
|
43
|
-
noScreenshot?: boolean;
|
|
44
|
-
}
|
|
45
|
-
export declare class Agent extends EventEmitter {
|
|
46
|
-
private readonly port;
|
|
47
|
-
private readonly options;
|
|
48
|
-
private ws;
|
|
49
|
-
private pingTimer;
|
|
50
|
-
private closing;
|
|
51
|
-
private screenshotDone;
|
|
52
|
-
/** Timestamp of the last agent-initiated ping; null when no ping is in-flight. */
|
|
53
|
-
private pingTimestamp;
|
|
54
|
-
private readonly reconnectionManager;
|
|
55
|
-
readonly token: string;
|
|
56
|
-
constructor(port: number, options: AgentOptions);
|
|
57
|
-
connect(): void;
|
|
58
|
-
close(): void;
|
|
59
|
-
private _openSocket;
|
|
60
|
-
private _startPing;
|
|
61
|
-
private _stopPing;
|
|
62
|
-
private _handleMessage;
|
|
63
|
-
private _forwardRequest;
|
|
64
|
-
/** Convert the relay WebSocket URL to its HTTP equivalent. */
|
|
65
|
-
private _relayHttp;
|
|
66
|
-
/**
|
|
67
|
-
* Try to locate a system Chrome / Chromium executable.
|
|
68
|
-
* Returns the first path that exists on disk, or null.
|
|
69
|
-
*/
|
|
70
|
-
private _findChrome;
|
|
71
|
-
/**
|
|
72
|
-
* Wait 2 s after connect, take a WebP screenshot of localhost:{port},
|
|
73
|
-
* and POST the base64 image to the relay for storage.
|
|
74
|
-
* All errors are caught and logged as warnings — never aborts the tunnel.
|
|
75
|
-
*/
|
|
76
|
-
private _captureScreenshot;
|
|
77
|
-
}
|
|
78
|
-
//# sourceMappingURL=agent.d.ts.map
|
package/dist/agent.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAqC3C;;;;;;GAMG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAM;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAa;IAEtC;;;;OAIG;IACH,QAAQ,IAAI,MAAM;IAMlB,+DAA+D;IAC/D,KAAK,IAAI,IAAI;IAIb,iEAAiE;IACjE,YAAY,IAAI,OAAO;IAIvB;;;;;;;OAOG;IACG,iBAAiB,CACrB,SAAS,EAAE,MAAM,IAAI,EACrB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,GAC1E,OAAO,CAAC,IAAI,CAAC;CAkBjB;AAID,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAID,qBAAa,KAAM,SAAQ,YAAY;IAcnC,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAd1B,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAS;IAE/B,kFAAkF;IAClF,OAAO,CAAC,aAAa,CAAuB;IAE5C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA6B;IAEjE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAGJ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY;IAMxC,OAAO,IAAI,IAAI;IAKf,KAAK,IAAI,IAAI;IAWb,OAAO,CAAC,WAAW;IAyDnB,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,cAAc;IAkCtB,OAAO,CAAC,eAAe;IAiEvB,8DAA8D;IAC9D,OAAO,CAAC,UAAU;IAMlB;;;OAGG;IACH,OAAO,CAAC,WAAW;IA2BnB;;;;OAIG;YACW,kBAAkB;CAwEjC"}
|
package/dist/agent.js
DELETED
|
@@ -1,357 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import http from "node:http";
|
|
3
|
-
import { EventEmitter } from "node:events";
|
|
4
|
-
import WebSocket from "ws";
|
|
5
|
-
import chalk from "chalk";
|
|
6
|
-
// ── Inlined from @portlens/shared (kept private / not on npm) ────────────────
|
|
7
|
-
import { createHash, randomBytes } from "node:crypto";
|
|
8
|
-
const BASE58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
9
|
-
function base58Encode(buf) {
|
|
10
|
-
let num = BigInt("0x" + buf.toString("hex"));
|
|
11
|
-
const chars = [];
|
|
12
|
-
while (num > 0n) {
|
|
13
|
-
chars.unshift(BASE58[Number(num % 58n)]);
|
|
14
|
-
num /= 58n;
|
|
15
|
-
}
|
|
16
|
-
for (const byte of buf) {
|
|
17
|
-
if (byte !== 0)
|
|
18
|
-
break;
|
|
19
|
-
chars.unshift(BASE58[0]);
|
|
20
|
-
}
|
|
21
|
-
return chars.join("");
|
|
22
|
-
}
|
|
23
|
-
function generateToken(length) {
|
|
24
|
-
return base58Encode(randomBytes(Math.ceil(length * 0.75))).slice(0, length);
|
|
25
|
-
}
|
|
26
|
-
function hashPassword(password) {
|
|
27
|
-
return createHash("sha256").update(password).digest("hex");
|
|
28
|
-
}
|
|
29
|
-
// ── Timing constants ──────────────────────────────────────────────────────────
|
|
30
|
-
/** How often the agent sends its own health-check ping to the relay. */
|
|
31
|
-
const PING_INTERVAL_MS = 30_000;
|
|
32
|
-
// ── ReconnectionManager ───────────────────────────────────────────────────────
|
|
33
|
-
/**
|
|
34
|
-
* Manages exponential-backoff reconnection with jitter.
|
|
35
|
-
*
|
|
36
|
-
* Usage:
|
|
37
|
-
* const mgr = new ReconnectionManager();
|
|
38
|
-
* await mgr.scheduleReconnect(() => openSocket(), onWaiting);
|
|
39
|
-
*/
|
|
40
|
-
export class ReconnectionManager {
|
|
41
|
-
attempts = 0;
|
|
42
|
-
maxAttempts = 10;
|
|
43
|
-
baseDelay = 1_000; // 1 s
|
|
44
|
-
maxDelay = 30_000; // 30 s
|
|
45
|
-
/**
|
|
46
|
-
* Compute the next delay with full-jitter:
|
|
47
|
-
* base = min(baseDelay × 2^attempts, maxDelay)
|
|
48
|
-
* result = base + base × 0.2 × random()
|
|
49
|
-
*/
|
|
50
|
-
getDelay() {
|
|
51
|
-
const base = Math.min(this.baseDelay * 2 ** this.attempts, this.maxDelay);
|
|
52
|
-
const jitter = base * 0.2 * Math.random();
|
|
53
|
-
return base + jitter;
|
|
54
|
-
}
|
|
55
|
-
/** Reset the attempt counter after a successful connection. */
|
|
56
|
-
reset() {
|
|
57
|
-
this.attempts = 0;
|
|
58
|
-
}
|
|
59
|
-
/** Returns true when the max retry budget has been exhausted. */
|
|
60
|
-
shouldGiveUp() {
|
|
61
|
-
return this.attempts >= this.maxAttempts;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Wait for the computed back-off delay, then call `connectFn`.
|
|
65
|
-
*
|
|
66
|
-
* @param connectFn Function that initiates a new WebSocket connection.
|
|
67
|
-
* @param onWaiting Optional callback fired just before sleeping.
|
|
68
|
-
* Receives `(delayMs, attempt, maxAttempts)` so callers
|
|
69
|
-
* can update the UI without coupling the manager to display code.
|
|
70
|
-
*/
|
|
71
|
-
async scheduleReconnect(connectFn, onWaiting) {
|
|
72
|
-
if (this.shouldGiveUp()) {
|
|
73
|
-
console.error(chalk.red("\n Max reconnection attempts reached. " +
|
|
74
|
-
"Run `portlens` again to retry."));
|
|
75
|
-
process.exit(1);
|
|
76
|
-
}
|
|
77
|
-
const delay = this.getDelay();
|
|
78
|
-
onWaiting?.(delay, this.attempts, this.maxAttempts);
|
|
79
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
80
|
-
this.attempts++;
|
|
81
|
-
connectFn();
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
// ── Agent ─────────────────────────────────────────────────────────────────────
|
|
85
|
-
export class Agent extends EventEmitter {
|
|
86
|
-
port;
|
|
87
|
-
options;
|
|
88
|
-
ws = null;
|
|
89
|
-
pingTimer = null;
|
|
90
|
-
closing = false;
|
|
91
|
-
screenshotDone = false;
|
|
92
|
-
/** Timestamp of the last agent-initiated ping; null when no ping is in-flight. */
|
|
93
|
-
pingTimestamp = null;
|
|
94
|
-
reconnectionManager = new ReconnectionManager();
|
|
95
|
-
token;
|
|
96
|
-
constructor(port, options) {
|
|
97
|
-
super();
|
|
98
|
-
this.port = port;
|
|
99
|
-
this.options = options;
|
|
100
|
-
this.token = generateToken(8);
|
|
101
|
-
}
|
|
102
|
-
connect() {
|
|
103
|
-
if (this.closing)
|
|
104
|
-
return;
|
|
105
|
-
this._openSocket();
|
|
106
|
-
}
|
|
107
|
-
close() {
|
|
108
|
-
this.closing = true;
|
|
109
|
-
this._stopPing();
|
|
110
|
-
if (this.ws) {
|
|
111
|
-
this.ws.removeAllListeners();
|
|
112
|
-
this.ws.close();
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
// ── Private ───────────────────────────────────────────────────────────────
|
|
116
|
-
_openSocket() {
|
|
117
|
-
const { relay, name, desc, password, jwtToken } = this.options;
|
|
118
|
-
const url = `${relay}/agent?token=${this.token}`;
|
|
119
|
-
const ws = new WebSocket(url);
|
|
120
|
-
this.ws = ws;
|
|
121
|
-
ws.on("open", () => {
|
|
122
|
-
// A successful open resets the back-off counter.
|
|
123
|
-
this.reconnectionManager.reset();
|
|
124
|
-
this.pingTimestamp = null;
|
|
125
|
-
const msg = {
|
|
126
|
-
type: "register",
|
|
127
|
-
token: this.token,
|
|
128
|
-
appName: name,
|
|
129
|
-
appDesc: desc,
|
|
130
|
-
...(password ? { passwordHash: hashPassword(password) } : {}),
|
|
131
|
-
...(jwtToken ? { jwtToken } : {}),
|
|
132
|
-
};
|
|
133
|
-
ws.send(JSON.stringify(msg));
|
|
134
|
-
this._startPing(ws);
|
|
135
|
-
/**
|
|
136
|
-
* Emit "connected" — two listeners in index.ts:
|
|
137
|
-
* - once("connected") → first-time box render
|
|
138
|
-
* - on("connected") → subsequent reconnect box updates
|
|
139
|
-
*/
|
|
140
|
-
this.emit("connected");
|
|
141
|
-
// Take screenshot on first successful connect only (not on reconnects).
|
|
142
|
-
if (!this.options.noScreenshot && !this.screenshotDone) {
|
|
143
|
-
this.screenshotDone = true;
|
|
144
|
-
this._captureScreenshot().catch(() => { });
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
ws.on("message", (data) => this._handleMessage(data));
|
|
148
|
-
ws.on("close", () => {
|
|
149
|
-
this._stopPing();
|
|
150
|
-
if (!this.closing) {
|
|
151
|
-
void this.reconnectionManager.scheduleReconnect(() => { if (!this.closing)
|
|
152
|
-
this._openSocket(); }, (delayMs, attempt, maxAttempts) => {
|
|
153
|
-
this.emit("reconnecting", delayMs, attempt, maxAttempts);
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
ws.on("error", (err) => {
|
|
158
|
-
// "close" fires after "error" — let close handle reconnect.
|
|
159
|
-
console.error(chalk.red(`\n Error: ${err.message}`));
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
_startPing(ws) {
|
|
163
|
-
this._stopPing();
|
|
164
|
-
this.pingTimer = setInterval(() => {
|
|
165
|
-
if (ws.readyState !== WebSocket.OPEN)
|
|
166
|
-
return;
|
|
167
|
-
// Record send-time so we can compute RTT when the pong arrives.
|
|
168
|
-
this.pingTimestamp = Date.now();
|
|
169
|
-
ws.send(JSON.stringify({ type: "ping" }));
|
|
170
|
-
}, PING_INTERVAL_MS);
|
|
171
|
-
}
|
|
172
|
-
_stopPing() {
|
|
173
|
-
if (this.pingTimer) {
|
|
174
|
-
clearInterval(this.pingTimer);
|
|
175
|
-
this.pingTimer = null;
|
|
176
|
-
this.pingTimestamp = null;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
_handleMessage(data) {
|
|
180
|
-
let msg;
|
|
181
|
-
try {
|
|
182
|
-
msg = JSON.parse(data.toString());
|
|
183
|
-
}
|
|
184
|
-
catch {
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
// Relay-initiated ping — reply immediately.
|
|
188
|
-
if (msg.type === "ping") {
|
|
189
|
-
this.ws?.send(JSON.stringify({ type: "pong" }));
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
// Pong in response to our own ping — measure RTT and emit.
|
|
193
|
-
if (msg.type === "pong") {
|
|
194
|
-
if (this.pingTimestamp !== null) {
|
|
195
|
-
const rtt = Date.now() - this.pingTimestamp;
|
|
196
|
-
this.pingTimestamp = null;
|
|
197
|
-
this.emit("rtt", rtt);
|
|
198
|
-
}
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
if (msg.type === "request") {
|
|
202
|
-
this._forwardRequest(msg);
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
if (msg.type === "error") {
|
|
206
|
-
console.error(chalk.red(`\n Relay error [${msg.code}]: ${msg.message}`));
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
_forwardRequest(msg) {
|
|
210
|
-
const { requestId, method, path, headers, body } = msg;
|
|
211
|
-
const reqBody = body ? Buffer.from(body, "base64") : undefined;
|
|
212
|
-
const options = {
|
|
213
|
-
hostname: "localhost",
|
|
214
|
-
port: this.port,
|
|
215
|
-
method,
|
|
216
|
-
path,
|
|
217
|
-
headers: {
|
|
218
|
-
...headers,
|
|
219
|
-
host: `localhost:${this.port}`,
|
|
220
|
-
...(reqBody ? { "content-length": String(reqBody.length) } : {}),
|
|
221
|
-
},
|
|
222
|
-
};
|
|
223
|
-
const respond = (statusCode, respHeaders, respBody) => {
|
|
224
|
-
const outMsg = {
|
|
225
|
-
type: "response",
|
|
226
|
-
requestId,
|
|
227
|
-
statusCode,
|
|
228
|
-
headers: respHeaders,
|
|
229
|
-
body: respBody.toString("base64"),
|
|
230
|
-
};
|
|
231
|
-
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
232
|
-
this.ws.send(JSON.stringify(outMsg));
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
const req = http.request(options, (res) => {
|
|
236
|
-
const chunks = [];
|
|
237
|
-
res.on("data", (chunk) => chunks.push(chunk));
|
|
238
|
-
res.on("end", () => {
|
|
239
|
-
const respHeaders = {};
|
|
240
|
-
for (const [k, v] of Object.entries(res.headers)) {
|
|
241
|
-
if (typeof v === "string")
|
|
242
|
-
respHeaders[k] = v;
|
|
243
|
-
else if (Array.isArray(v))
|
|
244
|
-
respHeaders[k] = v.join(", ");
|
|
245
|
-
}
|
|
246
|
-
respond(res.statusCode ?? 500, respHeaders, Buffer.concat(chunks));
|
|
247
|
-
});
|
|
248
|
-
});
|
|
249
|
-
req.on("error", (err) => {
|
|
250
|
-
console.error(chalk.red(` Local request failed: ${err.message}`));
|
|
251
|
-
respond(502, { "content-type": "application/json" }, Buffer.from(JSON.stringify({ error: "Local server unreachable", detail: err.message })));
|
|
252
|
-
});
|
|
253
|
-
if (reqBody)
|
|
254
|
-
req.write(reqBody);
|
|
255
|
-
req.end();
|
|
256
|
-
}
|
|
257
|
-
// ── Screenshot capture ────────────────────────────────────────────────────
|
|
258
|
-
/** Convert the relay WebSocket URL to its HTTP equivalent. */
|
|
259
|
-
_relayHttp() {
|
|
260
|
-
return this.options.relay
|
|
261
|
-
.replace(/^wss:\/\//, "https://")
|
|
262
|
-
.replace(/^ws:\/\//, "http://");
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Try to locate a system Chrome / Chromium executable.
|
|
266
|
-
* Returns the first path that exists on disk, or null.
|
|
267
|
-
*/
|
|
268
|
-
_findChrome() {
|
|
269
|
-
const candidates = [
|
|
270
|
-
// macOS
|
|
271
|
-
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
272
|
-
"/Applications/Chromium.app/Contents/MacOS/Chromium",
|
|
273
|
-
"/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary",
|
|
274
|
-
// Linux
|
|
275
|
-
"/usr/bin/google-chrome",
|
|
276
|
-
"/usr/bin/google-chrome-stable",
|
|
277
|
-
"/usr/bin/chromium",
|
|
278
|
-
"/usr/bin/chromium-browser",
|
|
279
|
-
"/snap/bin/chromium",
|
|
280
|
-
// Windows
|
|
281
|
-
"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
|
|
282
|
-
"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
|
|
283
|
-
];
|
|
284
|
-
for (const p of candidates) {
|
|
285
|
-
try {
|
|
286
|
-
fs.accessSync(p, fs.constants.X_OK);
|
|
287
|
-
return p;
|
|
288
|
-
}
|
|
289
|
-
catch {
|
|
290
|
-
// not found / not executable — try next
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
return null;
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* Wait 2 s after connect, take a WebP screenshot of localhost:{port},
|
|
297
|
-
* and POST the base64 image to the relay for storage.
|
|
298
|
-
* All errors are caught and logged as warnings — never aborts the tunnel.
|
|
299
|
-
*/
|
|
300
|
-
async _captureScreenshot() {
|
|
301
|
-
await new Promise((r) => setTimeout(r, 2_000));
|
|
302
|
-
if (this.closing)
|
|
303
|
-
return;
|
|
304
|
-
const executablePath = process.env["PUPPETEER_EXECUTABLE_PATH"] ?? this._findChrome() ?? undefined;
|
|
305
|
-
if (!executablePath) {
|
|
306
|
-
console.log(chalk.dim(" Screenshot skipped — no Chrome found. " +
|
|
307
|
-
"Set PUPPETEER_EXECUTABLE_PATH to enable."));
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
let puppeteer;
|
|
311
|
-
try {
|
|
312
|
-
puppeteer = await import("puppeteer-core");
|
|
313
|
-
}
|
|
314
|
-
catch {
|
|
315
|
-
console.log(chalk.dim(" Screenshot skipped — puppeteer-core not available."));
|
|
316
|
-
return;
|
|
317
|
-
}
|
|
318
|
-
let browser = null;
|
|
319
|
-
try {
|
|
320
|
-
browser = await puppeteer.launch({
|
|
321
|
-
executablePath,
|
|
322
|
-
headless: true,
|
|
323
|
-
args: [
|
|
324
|
-
"--no-sandbox",
|
|
325
|
-
"--disable-setuid-sandbox",
|
|
326
|
-
"--disable-dev-shm-usage",
|
|
327
|
-
],
|
|
328
|
-
});
|
|
329
|
-
const page = await browser.newPage();
|
|
330
|
-
await page.setViewport({ width: 1280, height: 800 });
|
|
331
|
-
await page.goto(`http://localhost:${this.port}`, {
|
|
332
|
-
waitUntil: "load",
|
|
333
|
-
timeout: 15_000,
|
|
334
|
-
});
|
|
335
|
-
const shot = await page.screenshot({ type: "webp", quality: 80 });
|
|
336
|
-
const imageBase64 = Buffer.from(shot).toString("base64");
|
|
337
|
-
const res = await fetch(`${this._relayHttp()}/session/${this.token}/screenshot`, {
|
|
338
|
-
method: "POST",
|
|
339
|
-
headers: { "content-type": "application/json" },
|
|
340
|
-
body: JSON.stringify({ imageBase64 }),
|
|
341
|
-
});
|
|
342
|
-
if (res.ok) {
|
|
343
|
-
console.log(chalk.dim(" Screenshot captured."));
|
|
344
|
-
}
|
|
345
|
-
else {
|
|
346
|
-
console.log(chalk.dim(` Screenshot upload failed (HTTP ${res.status}).`));
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
catch (err) {
|
|
350
|
-
console.log(chalk.yellow(` Screenshot warning: ${err instanceof Error ? err.message : String(err)}`));
|
|
351
|
-
}
|
|
352
|
-
finally {
|
|
353
|
-
await browser?.close();
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
//# sourceMappingURL=agent.js.map
|
package/dist/agent.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|
package/dist/authStore.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export interface AuthData {
|
|
2
|
-
token: string;
|
|
3
|
-
user: {
|
|
4
|
-
id: string;
|
|
5
|
-
email: string;
|
|
6
|
-
plan: "free" | "pro";
|
|
7
|
-
customSubdomain: string | null;
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
export declare const AUTH_FILE: string;
|
|
11
|
-
export declare function readAuth(): AuthData | null;
|
|
12
|
-
export declare function writeAuth(data: AuthData): void;
|
|
13
|
-
export declare function deleteAuth(): void;
|
|
14
|
-
//# sourceMappingURL=authStore.d.ts.map
|
package/dist/authStore.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"authStore.d.ts","sourceRoot":"","sources":["../src/authStore.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;QACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;KAChC,CAAC;CACH;AAGD,eAAO,MAAM,SAAS,QAAmC,CAAC;AAE1D,wBAAgB,QAAQ,IAAI,QAAQ,GAAG,IAAI,CAO1C;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAS9C;AAED,wBAAgB,UAAU,IAAI,IAAI,CAMjC"}
|
package/dist/authStore.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import os from "node:os";
|
|
4
|
-
const AUTH_DIR = path.join(os.homedir(), ".portlens");
|
|
5
|
-
export const AUTH_FILE = path.join(AUTH_DIR, "auth.json");
|
|
6
|
-
export function readAuth() {
|
|
7
|
-
try {
|
|
8
|
-
const raw = fs.readFileSync(AUTH_FILE, "utf8");
|
|
9
|
-
return JSON.parse(raw);
|
|
10
|
-
}
|
|
11
|
-
catch {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
export function writeAuth(data) {
|
|
16
|
-
fs.mkdirSync(AUTH_DIR, { recursive: true });
|
|
17
|
-
fs.writeFileSync(AUTH_FILE, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
18
|
-
// Restrict to owner read/write only (chmod 600)
|
|
19
|
-
try {
|
|
20
|
-
fs.chmodSync(AUTH_FILE, 0o600);
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
// chmod is a best-effort — Windows doesn't support POSIX mode bits
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
export function deleteAuth() {
|
|
27
|
-
try {
|
|
28
|
-
fs.unlinkSync(AUTH_FILE);
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
// Already gone — that's fine
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=authStore.js.map
|