@hooklink/cli 0.1.69 → 0.1.70
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/__tests__/agent/lease.test.d.ts +2 -0
- package/dist/__tests__/agent/lease.test.d.ts.map +1 -0
- package/dist/__tests__/agent/lease.test.js +31 -0
- package/dist/__tests__/agent/lease.test.js.map +1 -0
- package/dist/__tests__/agent/local-server.test.d.ts +9 -0
- package/dist/__tests__/agent/local-server.test.d.ts.map +1 -0
- package/dist/__tests__/agent/local-server.test.js +218 -0
- package/dist/__tests__/agent/local-server.test.js.map +1 -0
- package/dist/__tests__/agent/local-token.test.d.ts +2 -0
- package/dist/__tests__/agent/local-token.test.d.ts.map +1 -0
- package/dist/__tests__/agent/local-token.test.js +42 -0
- package/dist/__tests__/agent/local-token.test.js.map +1 -0
- package/dist/__tests__/agent/state.test.d.ts +2 -0
- package/dist/__tests__/agent/state.test.d.ts.map +1 -0
- package/dist/__tests__/agent/state.test.js +63 -0
- package/dist/__tests__/agent/state.test.js.map +1 -0
- package/dist/__tests__/agent/supervisor.test.d.ts +2 -0
- package/dist/__tests__/agent/supervisor.test.d.ts.map +1 -0
- package/dist/__tests__/agent/supervisor.test.js +126 -0
- package/dist/__tests__/agent/supervisor.test.js.map +1 -0
- package/dist/__tests__/json-events.test.d.ts +2 -0
- package/dist/__tests__/json-events.test.d.ts.map +1 -0
- package/dist/__tests__/json-events.test.js +101 -0
- package/dist/__tests__/json-events.test.js.map +1 -0
- package/dist/agent/endpoint-resolver.d.ts +35 -0
- package/dist/agent/endpoint-resolver.d.ts.map +1 -0
- package/dist/agent/endpoint-resolver.js +181 -0
- package/dist/agent/endpoint-resolver.js.map +1 -0
- package/dist/agent/lease.d.ts +18 -0
- package/dist/agent/lease.d.ts.map +1 -0
- package/dist/agent/lease.js +40 -0
- package/dist/agent/lease.js.map +1 -0
- package/dist/agent/local-server.d.ts +69 -0
- package/dist/agent/local-server.d.ts.map +1 -0
- package/dist/agent/local-server.js +426 -0
- package/dist/agent/local-server.js.map +1 -0
- package/dist/agent/local-token.d.ts +18 -0
- package/dist/agent/local-token.d.ts.map +1 -0
- package/dist/agent/local-token.js +65 -0
- package/dist/agent/local-token.js.map +1 -0
- package/dist/agent/paths.d.ts +12 -0
- package/dist/agent/paths.d.ts.map +1 -0
- package/dist/agent/paths.js +37 -0
- package/dist/agent/paths.js.map +1 -0
- package/dist/agent/preflight.d.ts +18 -0
- package/dist/agent/preflight.d.ts.map +1 -0
- package/dist/agent/preflight.js +87 -0
- package/dist/agent/preflight.js.map +1 -0
- package/dist/agent/resolve-bin.d.ts +26 -0
- package/dist/agent/resolve-bin.d.ts.map +1 -0
- package/dist/agent/resolve-bin.js +55 -0
- package/dist/agent/resolve-bin.js.map +1 -0
- package/dist/agent/service/darwin.d.ts +9 -0
- package/dist/agent/service/darwin.d.ts.map +1 -0
- package/dist/agent/service/darwin.js +85 -0
- package/dist/agent/service/darwin.js.map +1 -0
- package/dist/agent/service/index.d.ts +24 -0
- package/dist/agent/service/index.d.ts.map +1 -0
- package/dist/agent/service/index.js +71 -0
- package/dist/agent/service/index.js.map +1 -0
- package/dist/agent/service/linux.d.ts +10 -0
- package/dist/agent/service/linux.d.ts.map +1 -0
- package/dist/agent/service/linux.js +75 -0
- package/dist/agent/service/linux.js.map +1 -0
- package/dist/agent/service/win32.d.ts +9 -0
- package/dist/agent/service/win32.d.ts.map +1 -0
- package/dist/agent/service/win32.js +109 -0
- package/dist/agent/service/win32.js.map +1 -0
- package/dist/agent/state.d.ts +25 -0
- package/dist/agent/state.d.ts.map +1 -0
- package/dist/agent/state.js +63 -0
- package/dist/agent/state.js.map +1 -0
- package/dist/agent/supervisor.d.ts +116 -0
- package/dist/agent/supervisor.d.ts.map +1 -0
- package/dist/agent/supervisor.js +353 -0
- package/dist/agent/supervisor.js.map +1 -0
- package/dist/agent/zombie-cleanup.d.ts +20 -0
- package/dist/agent/zombie-cleanup.d.ts.map +1 -0
- package/dist/agent/zombie-cleanup.js +124 -0
- package/dist/agent/zombie-cleanup.js.map +1 -0
- package/dist/commands/agent.d.ts +12 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +173 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +106 -8
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +103 -4
- package/dist/commands/tunnel.js.map +1 -1
- package/dist/core/websocket-client.d.ts +2 -0
- package/dist/core/websocket-client.d.ts.map +1 -1
- package/dist/core/websocket-client.js +6 -0
- package/dist/core/websocket-client.js.map +1 -1
- package/dist/core/websocket-pool.d.ts +1 -0
- package/dist/core/websocket-pool.d.ts.map +1 -1
- package/dist/core/websocket-pool.js +3 -0
- package/dist/core/websocket-pool.js.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/json-events.d.ts +32 -0
- package/dist/utils/json-events.d.ts.map +1 -0
- package/dist/utils/json-events.js +71 -0
- package/dist/utils/json-events.js.map +1 -0
- package/dist/utils/logger.d.ts +6 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +30 -0
- package/dist/utils/logger.js.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The agent's localhost HTTP surface. Binds 127.0.0.1:7878 by default
|
|
4
|
+
* (override via HOOKLINK_AGENT_PORT). On port collision the server
|
|
5
|
+
* exits with an actionable error rather than silently falling back to
|
|
6
|
+
* a random port, because the WP plugin probes by fixed port and a
|
|
7
|
+
* random fallback would leave it unable to find us.
|
|
8
|
+
*
|
|
9
|
+
* Routes:
|
|
10
|
+
* GET /v1/health (no auth; used for discovery)
|
|
11
|
+
* GET /v1/status (local token)
|
|
12
|
+
* POST /v1/tunnels (local token)
|
|
13
|
+
* DELETE /v1/tunnels (local token)
|
|
14
|
+
* DELETE /v1/tunnels/:id (local token)
|
|
15
|
+
* GET /v1/tunnels/:id/recent (local token)
|
|
16
|
+
*
|
|
17
|
+
* `Authorization: Bearer <local-token>` gates every non-health route.
|
|
18
|
+
* Identity for tunnel ownership comes from either
|
|
19
|
+
* - `X-Hooklink-Api-Key` header (authenticated tunnels), or
|
|
20
|
+
* - `X-Hooklink-Owner-Id` header (trial tunnels, plugin-generated ULID).
|
|
21
|
+
*/
|
|
22
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.LocalServer = void 0;
|
|
27
|
+
const http_1 = __importDefault(require("http"));
|
|
28
|
+
const url_1 = require("url");
|
|
29
|
+
const lease_1 = require("./lease");
|
|
30
|
+
const local_token_1 = require("./local-token");
|
|
31
|
+
const preflight_1 = require("./preflight");
|
|
32
|
+
const endpoint_resolver_1 = require("./endpoint-resolver");
|
|
33
|
+
const state_1 = require("./state");
|
|
34
|
+
const DEFAULT_PORT = 7878;
|
|
35
|
+
class LocalServer {
|
|
36
|
+
constructor(opts) {
|
|
37
|
+
/** Track public_url per tunnel so authenticated-mode responses can
|
|
38
|
+
* include it even before the subprocess emits tunnel_ready. */
|
|
39
|
+
this.publicUrlById = new Map();
|
|
40
|
+
const envPort = process.env.HOOKLINK_AGENT_PORT
|
|
41
|
+
? Number(process.env.HOOKLINK_AGENT_PORT)
|
|
42
|
+
: NaN;
|
|
43
|
+
this.port = opts.port ?? (Number.isFinite(envPort) ? envPort : DEFAULT_PORT);
|
|
44
|
+
// Default to loopback-only. Docker-hosted WP (and similar
|
|
45
|
+
// cross-boundary setups) should set `HOOKLINK_AGENT_HOST=0.0.0.0`
|
|
46
|
+
// explicitly; the local bearer token keeps it safe.
|
|
47
|
+
this.host = opts.host ?? process.env.HOOKLINK_AGENT_HOST ?? '127.0.0.1';
|
|
48
|
+
this.supervisor = opts.supervisor;
|
|
49
|
+
this.lease = new lease_1.LeaseManager();
|
|
50
|
+
this.localToken = opts.localToken;
|
|
51
|
+
this.apiUrl = opts.apiUrl;
|
|
52
|
+
this.version = opts.version;
|
|
53
|
+
this.resolver = opts.resolver ?? endpoint_resolver_1.resolveEndpoint;
|
|
54
|
+
this.server = http_1.default.createServer((req, res) => {
|
|
55
|
+
this.handle(req, res).catch((err) => {
|
|
56
|
+
this.sendJson(res, 500, {
|
|
57
|
+
error: 'internal_error',
|
|
58
|
+
message: err?.message || 'Internal error',
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
// Periodically enforce expired leases.
|
|
63
|
+
const sweep = setInterval(() => this.sweepExpired(), 5000);
|
|
64
|
+
sweep.unref?.();
|
|
65
|
+
}
|
|
66
|
+
async listen() {
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
this.server.once('error', (err) => {
|
|
69
|
+
if (err.code === 'EADDRINUSE') {
|
|
70
|
+
reject(new Error(`Port ${this.port} is already in use. Another agent may be running. ` +
|
|
71
|
+
`Stop it with \`hooklink agent uninstall\` or set HOOKLINK_AGENT_PORT.`));
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
reject(err);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
this.server.listen(this.port, this.host, () => {
|
|
78
|
+
const addr = this.server.address();
|
|
79
|
+
this.port = addr.port;
|
|
80
|
+
resolve(this.port);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async close() {
|
|
85
|
+
return new Promise((resolve) => this.server.close(() => resolve()));
|
|
86
|
+
}
|
|
87
|
+
async handle(req, res) {
|
|
88
|
+
const url = new url_1.URL(req.url ?? '/', `http://${req.headers.host || '127.0.0.1'}`);
|
|
89
|
+
// Health is the discovery probe; never auth-gated, never cached.
|
|
90
|
+
if (url.pathname === '/v1/health' && req.method === 'GET') {
|
|
91
|
+
this.sendJson(res, 200, {
|
|
92
|
+
ok: true,
|
|
93
|
+
version: this.version,
|
|
94
|
+
active_tunnel_count: this.supervisor.listTunnels().length,
|
|
95
|
+
});
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (!this.authorize(req, res))
|
|
99
|
+
return;
|
|
100
|
+
if (url.pathname === '/v1/status' && req.method === 'GET') {
|
|
101
|
+
return this.handleStatus(req, res);
|
|
102
|
+
}
|
|
103
|
+
if (url.pathname === '/v1/tunnels' && req.method === 'POST') {
|
|
104
|
+
return this.handleCreateTunnel(req, res);
|
|
105
|
+
}
|
|
106
|
+
if (url.pathname === '/v1/tunnels' && req.method === 'DELETE') {
|
|
107
|
+
return this.handleDeleteAll(req, res);
|
|
108
|
+
}
|
|
109
|
+
const tunnelMatch = url.pathname.match(/^\/v1\/tunnels\/([^/]+)$/);
|
|
110
|
+
if (tunnelMatch && req.method === 'DELETE') {
|
|
111
|
+
return this.handleDeleteOne(req, res, tunnelMatch[1]);
|
|
112
|
+
}
|
|
113
|
+
const recentMatch = url.pathname.match(/^\/v1\/tunnels\/([^/]+)\/recent$/);
|
|
114
|
+
if (recentMatch && req.method === 'GET') {
|
|
115
|
+
return this.handleRecent(req, res, recentMatch[1], url);
|
|
116
|
+
}
|
|
117
|
+
this.sendJson(res, 404, { error: 'not_found' });
|
|
118
|
+
}
|
|
119
|
+
authorize(req, res) {
|
|
120
|
+
const header = req.headers.authorization || '';
|
|
121
|
+
const [scheme, token] = header.split(' ');
|
|
122
|
+
if (scheme !== 'Bearer' || !token) {
|
|
123
|
+
this.sendJson(res, 401, { error: 'unauthorized' });
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
if (!(0, local_token_1.tokenMatches)(token, this.localToken)) {
|
|
127
|
+
this.sendJson(res, 401, { error: 'unauthorized' });
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
ownerKey(req) {
|
|
133
|
+
const apiKey = readHeader(req, 'x-hooklink-api-key');
|
|
134
|
+
const ownerId = readHeader(req, 'x-hooklink-owner-id');
|
|
135
|
+
return {
|
|
136
|
+
api_key: apiKey,
|
|
137
|
+
api_key_hash: apiKey ? (0, state_1.hashApiKey)(apiKey) : null,
|
|
138
|
+
owner_id: ownerId,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
isOwner(info, owner) {
|
|
142
|
+
if (info.api_key_hash)
|
|
143
|
+
return info.api_key_hash === owner.api_key_hash;
|
|
144
|
+
if (info.owner_id)
|
|
145
|
+
return info.owner_id === owner.owner_id;
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
handleStatus(req, res) {
|
|
149
|
+
const owner = this.ownerKey(req);
|
|
150
|
+
const all = this.supervisor.listTunnels((info) => this.isOwner(info, owner));
|
|
151
|
+
// Refresh leases on every status poll — this is how callers
|
|
152
|
+
// implicitly release tunnels by stopping polling.
|
|
153
|
+
for (const t of all)
|
|
154
|
+
this.lease.refresh(t.tunnel_id);
|
|
155
|
+
this.sendJson(res, 200, {
|
|
156
|
+
running: true,
|
|
157
|
+
version: this.version,
|
|
158
|
+
active_tunnels: all.map((t) => this.publicTunnel(t)),
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
async handleCreateTunnel(req, res) {
|
|
162
|
+
const body = await readJsonBody(req);
|
|
163
|
+
const localTarget = typeof body.local_target === 'string' ? body.local_target.trim() : '';
|
|
164
|
+
if (!localTarget) {
|
|
165
|
+
this.sendJson(res, 400, {
|
|
166
|
+
error: 'invalid_request',
|
|
167
|
+
message: '`local_target` is required.',
|
|
168
|
+
});
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const owner = this.ownerKey(req);
|
|
172
|
+
const authenticated = owner.api_key !== null;
|
|
173
|
+
if (!authenticated && !owner.owner_id) {
|
|
174
|
+
this.sendJson(res, 400, {
|
|
175
|
+
error: 'invalid_request',
|
|
176
|
+
message: 'Trial mode requires an X-Hooklink-Owner-Id header (a stable id the plugin generates).',
|
|
177
|
+
});
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
// Idempotency: same (owner, local_target) returns the existing tunnel.
|
|
181
|
+
const existing = this.findExistingTunnel(localTarget, owner);
|
|
182
|
+
if (existing) {
|
|
183
|
+
this.lease.refresh(existing.tunnel_id);
|
|
184
|
+
this.sendJson(res, 200, this.publicTunnel(existing));
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const flight = await (0, preflight_1.preflight)(localTarget, { timeoutMs: 2000 });
|
|
188
|
+
if (!flight.ok) {
|
|
189
|
+
const statusCode = flight.code === 'invalid_url' ? 400 : 422;
|
|
190
|
+
this.sendJson(res, statusCode, {
|
|
191
|
+
error: flight.code,
|
|
192
|
+
message: flight.detail || 'Local target is unreachable.',
|
|
193
|
+
attempted_target: localTarget,
|
|
194
|
+
});
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
if (authenticated) {
|
|
199
|
+
const resolved = await this.resolver({
|
|
200
|
+
apiKey: owner.api_key,
|
|
201
|
+
apiUrl: this.apiUrl,
|
|
202
|
+
localTarget,
|
|
203
|
+
});
|
|
204
|
+
const publicUrl = this.publicUrlFor(resolved);
|
|
205
|
+
this.publicUrlById.set(resolved.id, publicUrl);
|
|
206
|
+
const info = await this.supervisor.startTunnel({
|
|
207
|
+
mode: 'authenticated',
|
|
208
|
+
tunnel_id: resolved.id,
|
|
209
|
+
keyword: resolved.keyword,
|
|
210
|
+
api_key: owner.api_key,
|
|
211
|
+
api_key_hash: owner.api_key_hash,
|
|
212
|
+
local_target: localTarget,
|
|
213
|
+
public_url: publicUrl,
|
|
214
|
+
});
|
|
215
|
+
this.lease.refresh(info.tunnel_id);
|
|
216
|
+
this.sendJson(res, 200, this.publicTunnel(info));
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
const info = await this.supervisor.startTunnel({
|
|
220
|
+
mode: 'trial',
|
|
221
|
+
owner_id: owner.owner_id,
|
|
222
|
+
local_target: localTarget,
|
|
223
|
+
});
|
|
224
|
+
this.lease.refresh(info.tunnel_id);
|
|
225
|
+
this.sendJson(res, 200, this.publicTunnel(info));
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
catch (err) {
|
|
229
|
+
this.sendSpawnError(res, err);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
sendSpawnError(res, err) {
|
|
233
|
+
if (err instanceof endpoint_resolver_1.ResolveError) {
|
|
234
|
+
const statusMap = {
|
|
235
|
+
hooklink_auth_failed: 401,
|
|
236
|
+
quota_exceeded: 403,
|
|
237
|
+
keyword_collision: 409,
|
|
238
|
+
target_port_rejected: 422,
|
|
239
|
+
hooklink_unreachable: 502,
|
|
240
|
+
invalid_request: 400,
|
|
241
|
+
};
|
|
242
|
+
this.sendJson(res, statusMap[err.code] ?? 500, {
|
|
243
|
+
error: err.code,
|
|
244
|
+
message: err.message,
|
|
245
|
+
...err.extra,
|
|
246
|
+
});
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
const e = err;
|
|
250
|
+
if (e?.code === 'too_many_local_tunnels') {
|
|
251
|
+
this.sendJson(res, 503, {
|
|
252
|
+
error: 'too_many_local_tunnels',
|
|
253
|
+
message: 'Agent is at its 20-tunnel cap.',
|
|
254
|
+
});
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
if (e?.code === 'spawn_timeout') {
|
|
258
|
+
this.sendJson(res, 504, {
|
|
259
|
+
error: 'spawn_timeout',
|
|
260
|
+
message: e.message || 'Subprocess did not emit tunnel_ready in time.',
|
|
261
|
+
});
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
if (e?.code === 'trial_daily_limit') {
|
|
265
|
+
this.sendJson(res, 429, {
|
|
266
|
+
error: 'trial_daily_limit',
|
|
267
|
+
message: e.message,
|
|
268
|
+
});
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
this.sendJson(res, 500, {
|
|
272
|
+
error: 'internal_error',
|
|
273
|
+
message: e?.message || 'Failed to start tunnel',
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
async handleDeleteOne(req, res, tunnelId) {
|
|
277
|
+
const owner = this.ownerKey(req);
|
|
278
|
+
const info = this.supervisor.getTunnel(tunnelId);
|
|
279
|
+
if (!info) {
|
|
280
|
+
this.sendJson(res, 404, { error: 'tunnel_not_found' });
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
if (!this.isOwner(info, owner)) {
|
|
284
|
+
this.sendJson(res, 403, { error: 'not_owner' });
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
await this.supervisor.stopTunnel(tunnelId);
|
|
288
|
+
this.lease.release(tunnelId);
|
|
289
|
+
this.publicUrlById.delete(tunnelId);
|
|
290
|
+
this.sendJson(res, 200, {
|
|
291
|
+
tunnel_id: tunnelId,
|
|
292
|
+
stopped_at: new Date().toISOString(),
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
async handleDeleteAll(req, res) {
|
|
296
|
+
const owner = this.ownerKey(req);
|
|
297
|
+
const ids = this.supervisor
|
|
298
|
+
.listTunnels((info) => this.isOwner(info, owner))
|
|
299
|
+
.map((t) => t.tunnel_id);
|
|
300
|
+
for (const id of ids) {
|
|
301
|
+
await this.supervisor.stopTunnel(id);
|
|
302
|
+
this.lease.release(id);
|
|
303
|
+
this.publicUrlById.delete(id);
|
|
304
|
+
}
|
|
305
|
+
this.sendJson(res, 200, { stopped: ids });
|
|
306
|
+
}
|
|
307
|
+
handleRecent(req, res, tunnelId, url) {
|
|
308
|
+
const owner = this.ownerKey(req);
|
|
309
|
+
const info = this.supervisor.getTunnel(tunnelId);
|
|
310
|
+
if (!info) {
|
|
311
|
+
this.sendJson(res, 404, { error: 'tunnel_not_found' });
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
if (!this.isOwner(info, owner)) {
|
|
315
|
+
this.sendJson(res, 403, { error: 'not_owner' });
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const limit = Math.min(100, Math.max(1, parseInt(url.searchParams.get('limit') ?? '20', 10)));
|
|
319
|
+
const requests = this.supervisor.getRecentRequests(tunnelId, limit);
|
|
320
|
+
this.sendJson(res, 200, { tunnel_id: tunnelId, requests });
|
|
321
|
+
}
|
|
322
|
+
findExistingTunnel(localTarget, owner) {
|
|
323
|
+
const matches = this.supervisor.listTunnels((info) => this.isOwner(info, owner) && info.local_target === localTarget);
|
|
324
|
+
return matches[0] ?? null;
|
|
325
|
+
}
|
|
326
|
+
sweepExpired() {
|
|
327
|
+
for (const id of this.lease.getExpired()) {
|
|
328
|
+
const info = this.supervisor.getTunnel(id);
|
|
329
|
+
if (info) {
|
|
330
|
+
this.supervisor.stopTunnel(id).catch(() => { });
|
|
331
|
+
}
|
|
332
|
+
this.lease.release(id);
|
|
333
|
+
this.publicUrlById.delete(id);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
publicUrlFor(resolved) {
|
|
337
|
+
const host = new url_1.URL(this.apiUrl).hostname;
|
|
338
|
+
const webhookDomain = host.replace(/^(staging-)?api\./, (_, prefix) => prefix ? 'staging.' : '');
|
|
339
|
+
// We don't ship the username in the resolver response; fall back
|
|
340
|
+
// to the keyword as public host fragment. The subprocess's
|
|
341
|
+
// `tunnel_ready` event overrides this with the authoritative URL.
|
|
342
|
+
return `https://${resolved.keyword}.${webhookDomain}`;
|
|
343
|
+
}
|
|
344
|
+
publicTunnel(t) {
|
|
345
|
+
const out = {
|
|
346
|
+
tunnel_id: t.tunnel_id,
|
|
347
|
+
public_url: t.public_url,
|
|
348
|
+
local_target: t.local_target,
|
|
349
|
+
pid: t.pid,
|
|
350
|
+
started_at: t.started_at,
|
|
351
|
+
state: t.state,
|
|
352
|
+
trial: t.trial,
|
|
353
|
+
};
|
|
354
|
+
if (t.trial) {
|
|
355
|
+
if (t.expires_at)
|
|
356
|
+
out.expires_at = t.expires_at;
|
|
357
|
+
if (t.limits)
|
|
358
|
+
out.limits = t.limits;
|
|
359
|
+
if (t.usage) {
|
|
360
|
+
out.usage = { requests: t.usage.requests, bytes: t.usage.bytes };
|
|
361
|
+
out.remaining_seconds = t.usage.remaining_seconds;
|
|
362
|
+
if (t.limits) {
|
|
363
|
+
out.remaining_requests = Math.max(0, t.limits.max_requests - t.usage.requests);
|
|
364
|
+
out.remaining_bandwidth_bytes = Math.max(0, t.limits.max_bandwidth_bytes - t.usage.bytes);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
if (t.last_error) {
|
|
369
|
+
out.last_error = t.last_error;
|
|
370
|
+
}
|
|
371
|
+
return out;
|
|
372
|
+
}
|
|
373
|
+
sendJson(res, status, body) {
|
|
374
|
+
const payload = Buffer.from(JSON.stringify(body));
|
|
375
|
+
res.writeHead(status, {
|
|
376
|
+
'content-type': 'application/json',
|
|
377
|
+
'content-length': payload.length,
|
|
378
|
+
'cache-control': 'no-store',
|
|
379
|
+
});
|
|
380
|
+
res.end(payload);
|
|
381
|
+
}
|
|
382
|
+
/** Test-only hooks. */
|
|
383
|
+
getLeaseManager() {
|
|
384
|
+
return this.lease;
|
|
385
|
+
}
|
|
386
|
+
getPort() {
|
|
387
|
+
return this.port;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
exports.LocalServer = LocalServer;
|
|
391
|
+
function readHeader(req, name) {
|
|
392
|
+
const v = req.headers[name];
|
|
393
|
+
if (typeof v === 'string' && v.trim().length > 0)
|
|
394
|
+
return v.trim();
|
|
395
|
+
if (Array.isArray(v) && v.length > 0)
|
|
396
|
+
return v[0];
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
399
|
+
async function readJsonBody(req) {
|
|
400
|
+
return new Promise((resolve, reject) => {
|
|
401
|
+
let raw = '';
|
|
402
|
+
let total = 0;
|
|
403
|
+
req.on('data', (chunk) => {
|
|
404
|
+
total += chunk.length;
|
|
405
|
+
if (total > 64 * 1024) {
|
|
406
|
+
reject(new Error('payload_too_large'));
|
|
407
|
+
req.destroy();
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
raw += chunk.toString('utf8');
|
|
411
|
+
});
|
|
412
|
+
req.on('end', () => {
|
|
413
|
+
if (!raw)
|
|
414
|
+
return resolve({});
|
|
415
|
+
try {
|
|
416
|
+
const parsed = JSON.parse(raw);
|
|
417
|
+
resolve(typeof parsed === 'object' && parsed !== null ? parsed : {});
|
|
418
|
+
}
|
|
419
|
+
catch {
|
|
420
|
+
reject(new Error('invalid_json'));
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
req.on('error', reject);
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
//# sourceMappingURL=local-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-server.js","sourceRoot":"","sources":["../../src/agent/local-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local auth token. Generated on first agent startup, stored at
|
|
3
|
+
* `~/.hooklink/local-token` with 0600 perms. Every authenticated
|
|
4
|
+
* request to the agent's localhost HTTP surface carries the token
|
|
5
|
+
* in `Authorization: Bearer <token>`.
|
|
6
|
+
*
|
|
7
|
+
* The token is the agent's only guard against other users on the
|
|
8
|
+
* same machine poking at `127.0.0.1:7878`. It is NOT a secret that
|
|
9
|
+
* leaves the machine.
|
|
10
|
+
*/
|
|
11
|
+
export declare function ensureLocalToken(): string;
|
|
12
|
+
export declare function readLocalToken(): string | null;
|
|
13
|
+
/**
|
|
14
|
+
* Constant-time comparison. Prevents timing side channels even
|
|
15
|
+
* though the attack surface here is tiny.
|
|
16
|
+
*/
|
|
17
|
+
export declare function tokenMatches(candidate: string, expected: string): boolean;
|
|
18
|
+
//# sourceMappingURL=local-token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-token.d.ts","sourceRoot":"","sources":["../../src/agent/local-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,wBAAgB,gBAAgB,IAAI,MAAM,CAkBzC;AAED,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAO9C;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAKzE"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Local auth token. Generated on first agent startup, stored at
|
|
4
|
+
* `~/.hooklink/local-token` with 0600 perms. Every authenticated
|
|
5
|
+
* request to the agent's localhost HTTP surface carries the token
|
|
6
|
+
* in `Authorization: Bearer <token>`.
|
|
7
|
+
*
|
|
8
|
+
* The token is the agent's only guard against other users on the
|
|
9
|
+
* same machine poking at `127.0.0.1:7878`. It is NOT a secret that
|
|
10
|
+
* leaves the machine.
|
|
11
|
+
*/
|
|
12
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
13
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
|
+
};
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.ensureLocalToken = ensureLocalToken;
|
|
17
|
+
exports.readLocalToken = readLocalToken;
|
|
18
|
+
exports.tokenMatches = tokenMatches;
|
|
19
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
20
|
+
const fs_1 = __importDefault(require("fs"));
|
|
21
|
+
const path_1 = __importDefault(require("path"));
|
|
22
|
+
const paths_1 = require("./paths");
|
|
23
|
+
function ensureLocalToken() {
|
|
24
|
+
const tokenPath = (0, paths_1.getLocalTokenPath)();
|
|
25
|
+
try {
|
|
26
|
+
const existing = fs_1.default.readFileSync(tokenPath, 'utf8').trim();
|
|
27
|
+
if (existing && existing.length >= 32)
|
|
28
|
+
return existing;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// File doesn't exist yet, fall through to generation.
|
|
32
|
+
}
|
|
33
|
+
const token = crypto_1.default.randomBytes(32).toString('hex');
|
|
34
|
+
fs_1.default.mkdirSync(path_1.default.dirname(tokenPath), { recursive: true, mode: 0o700 });
|
|
35
|
+
fs_1.default.writeFileSync(tokenPath, token, { mode: 0o600 });
|
|
36
|
+
// Ensure the directory itself isn't world-readable.
|
|
37
|
+
try {
|
|
38
|
+
fs_1.default.chmodSync((0, paths_1.getAgentHome)(), 0o700);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Windows or a filesystem that doesn't honor chmod. Best-effort.
|
|
42
|
+
}
|
|
43
|
+
return token;
|
|
44
|
+
}
|
|
45
|
+
function readLocalToken() {
|
|
46
|
+
try {
|
|
47
|
+
const raw = fs_1.default.readFileSync((0, paths_1.getLocalTokenPath)(), 'utf8').trim();
|
|
48
|
+
return raw.length >= 32 ? raw : null;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Constant-time comparison. Prevents timing side channels even
|
|
56
|
+
* though the attack surface here is tiny.
|
|
57
|
+
*/
|
|
58
|
+
function tokenMatches(candidate, expected) {
|
|
59
|
+
const a = Buffer.from(candidate);
|
|
60
|
+
const b = Buffer.from(expected);
|
|
61
|
+
if (a.length !== b.length)
|
|
62
|
+
return false;
|
|
63
|
+
return crypto_1.default.timingSafeEqual(a, b);
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=local-token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-token.js","sourceRoot":"","sources":["../../src/agent/local-token.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;AAOH,4CAkBC;AAED,wCAOC;AAMD,oCAKC;AA3CD,oDAA4B;AAC5B,4CAAoB;AACpB,gDAAwB;AACxB,mCAA0D;AAE1D,SAAgB,gBAAgB;IAC9B,MAAM,SAAS,GAAG,IAAA,yBAAiB,GAAE,CAAC;IACtC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,YAAE,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3D,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,IAAI,EAAE;YAAE,OAAO,QAAQ,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,sDAAsD;IACxD,CAAC;IACD,MAAM,KAAK,GAAG,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACrD,YAAE,CAAC,SAAS,CAAC,cAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACxE,YAAE,CAAC,aAAa,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACpD,oDAAoD;IACpD,IAAI,CAAC;QACH,YAAE,CAAC,SAAS,CAAC,IAAA,oBAAY,GAAE,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,iEAAiE;IACnE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAgB,cAAc;IAC5B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAE,CAAC,YAAY,CAAC,IAAA,yBAAiB,GAAE,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAChE,OAAO,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,YAAY,CAAC,SAAiB,EAAE,QAAgB;IAC9D,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,gBAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Central resolver for every on-disk path the agent owns. Keeping
|
|
3
|
+
* these in one place simplifies install, uninstall, and tests
|
|
4
|
+
* (which override `HOOKLINK_HOME` to a tmpdir).
|
|
5
|
+
*/
|
|
6
|
+
export declare function getAgentHome(): string;
|
|
7
|
+
export declare function getLocalTokenPath(): string;
|
|
8
|
+
export declare function getStatePath(): string;
|
|
9
|
+
export declare function getAgentLogPath(): string;
|
|
10
|
+
export declare function getTunnelsDir(): string;
|
|
11
|
+
export declare function getTunnelLogPath(tunnelId: string): string;
|
|
12
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/agent/paths.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEzD"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Central resolver for every on-disk path the agent owns. Keeping
|
|
4
|
+
* these in one place simplifies install, uninstall, and tests
|
|
5
|
+
* (which override `HOOKLINK_HOME` to a tmpdir).
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.getAgentHome = getAgentHome;
|
|
12
|
+
exports.getLocalTokenPath = getLocalTokenPath;
|
|
13
|
+
exports.getStatePath = getStatePath;
|
|
14
|
+
exports.getAgentLogPath = getAgentLogPath;
|
|
15
|
+
exports.getTunnelsDir = getTunnelsDir;
|
|
16
|
+
exports.getTunnelLogPath = getTunnelLogPath;
|
|
17
|
+
const os_1 = __importDefault(require("os"));
|
|
18
|
+
const path_1 = __importDefault(require("path"));
|
|
19
|
+
function getAgentHome() {
|
|
20
|
+
return process.env.HOOKLINK_HOME || path_1.default.join(os_1.default.homedir(), '.hooklink');
|
|
21
|
+
}
|
|
22
|
+
function getLocalTokenPath() {
|
|
23
|
+
return path_1.default.join(getAgentHome(), 'local-token');
|
|
24
|
+
}
|
|
25
|
+
function getStatePath() {
|
|
26
|
+
return path_1.default.join(getAgentHome(), 'agent.state');
|
|
27
|
+
}
|
|
28
|
+
function getAgentLogPath() {
|
|
29
|
+
return path_1.default.join(getAgentHome(), 'agent.log');
|
|
30
|
+
}
|
|
31
|
+
function getTunnelsDir() {
|
|
32
|
+
return path_1.default.join(getAgentHome(), 'tunnels');
|
|
33
|
+
}
|
|
34
|
+
function getTunnelLogPath(tunnelId) {
|
|
35
|
+
return path_1.default.join(getTunnelsDir(), `${tunnelId}.log`);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/agent/paths.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;AAKH,oCAEC;AAED,8CAEC;AAED,oCAEC;AAED,0CAEC;AAED,sCAEC;AAED,4CAEC;AAzBD,4CAAoB;AACpB,gDAAwB;AAExB,SAAgB,YAAY;IAC1B,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AAC3E,CAAC;AAED,SAAgB,iBAAiB;IAC/B,OAAO,cAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa,CAAC,CAAC;AAClD,CAAC;AAED,SAAgB,YAAY;IAC1B,OAAO,cAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa,CAAC,CAAC;AAClD,CAAC;AAED,SAAgB,eAAe;IAC7B,OAAO,cAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,WAAW,CAAC,CAAC;AAChD,CAAC;AAED,SAAgB,aAAa;IAC3B,OAAO,cAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,SAAS,CAAC,CAAC;AAC9C,CAAC;AAED,SAAgB,gBAAgB,CAAC,QAAgB;IAC/C,OAAO,cAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,GAAG,QAAQ,MAAM,CAAC,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HEAD/GET reachability check for a prospective tunnel target.
|
|
3
|
+
*
|
|
4
|
+
* Accepts any HTTP status (including 4xx/5xx) as proof the target
|
|
5
|
+
* is alive. A WP login page returning 302 or 401 still counts as
|
|
6
|
+
* reachable. ECONNREFUSED / DNS / timeout all produce
|
|
7
|
+
* `target_unreachable`.
|
|
8
|
+
*/
|
|
9
|
+
export interface PreflightResult {
|
|
10
|
+
ok: boolean;
|
|
11
|
+
code?: 'target_unreachable' | 'invalid_url';
|
|
12
|
+
detail?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface PreflightOptions {
|
|
15
|
+
timeoutMs?: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function preflight(target: string, options?: PreflightOptions): Promise<PreflightResult>;
|
|
18
|
+
//# sourceMappingURL=preflight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight.d.ts","sourceRoot":"","sources":["../../src/agent/preflight.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,CAAC,EAAE,oBAAoB,GAAG,aAAa,CAAC;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,SAAS,CAC7B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC,CA6B1B"}
|