elit 3.6.8 → 3.7.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 (50) hide show
  1. package/Cargo.lock +380 -449
  2. package/Cargo.toml +3 -3
  3. package/dist/build.cjs +1 -1
  4. package/dist/build.d.ts +1 -1
  5. package/dist/build.js +14 -10
  6. package/dist/build.mjs +1 -1
  7. package/dist/cli.cjs +1838 -6399
  8. package/dist/cli.d.ts +10 -3
  9. package/dist/cli.mjs +1858 -6419
  10. package/dist/config.cjs +7 -2
  11. package/dist/config.d.ts +4 -4
  12. package/dist/config.js +20 -11
  13. package/dist/config.mjs +7 -2
  14. package/dist/{contracts-D7KIS-TK.d.ts → contracts-Av9yuqDM.d.ts} +11 -4
  15. package/dist/dev-build.d.ts +2 -1
  16. package/dist/dev-build.js +13 -9
  17. package/dist/https.cjs +7 -2
  18. package/dist/https.js +7 -2
  19. package/dist/https.mjs +7 -2
  20. package/dist/index.cjs +340 -52
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.js +340 -52
  23. package/dist/index.mjs +340 -52
  24. package/dist/native.cjs +340 -52
  25. package/dist/native.js +340 -52
  26. package/dist/native.mjs +340 -52
  27. package/dist/pm.cjs +316 -48
  28. package/dist/pm.d.ts +3 -3
  29. package/dist/pm.js +329 -57
  30. package/dist/pm.mjs +316 -48
  31. package/dist/preview-build.d.ts +2 -2
  32. package/dist/preview-build.js +13 -9
  33. package/dist/server.cjs +861 -5998
  34. package/dist/server.d.ts +3 -2
  35. package/dist/server.js +12178 -4468
  36. package/dist/server.mjs +861 -5998
  37. package/dist/smtp-server.js +514 -44
  38. package/dist/test-runtime.cjs +20 -0
  39. package/dist/test-runtime.js +33 -9
  40. package/dist/test-runtime.mjs +20 -0
  41. package/dist/test.cjs +27 -2
  42. package/dist/test.js +40 -11
  43. package/dist/test.mjs +27 -2
  44. package/dist/{types-BayMVo_k.d.ts → types-CLGrLRTl.d.ts} +8 -2
  45. package/dist/{types-fiLday0L.d.ts → types-CYEpzeEi.d.ts} +10 -0
  46. package/dist/types.d.ts +52 -36
  47. package/dist/wss.cjs +7 -2
  48. package/dist/wss.js +7 -2
  49. package/dist/wss.mjs +7 -2
  50. package/package.json +7 -2
package/dist/pm.js CHANGED
@@ -12,11 +12,20 @@
12
12
  if (typeof require !== "undefined") return require.apply(this, arguments);
13
13
  throw Error('Dynamic require of "' + x + '" is not supported');
14
14
  });
15
- var __esm = (fn, res) => function __init() {
16
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
15
+ var __esm = (fn, res, err) => function __init() {
16
+ if (err) throw err[0];
17
+ try {
18
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
19
+ } catch (e) {
20
+ throw err = [e], e;
21
+ }
17
22
  };
18
23
  var __commonJS = (cb, mod) => function __require2() {
19
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
24
+ try {
25
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
26
+ } catch (e) {
27
+ throw mod = 0, e;
28
+ }
20
29
  };
21
30
  var __export = (target, all) => {
22
31
  for (var name in all)
@@ -1388,8 +1397,8 @@ is not a problem with esbuild. You need to fix your environment instead.
1388
1397
  if (isFirstPacket) {
1389
1398
  isFirstPacket = false;
1390
1399
  let binaryVersion = String.fromCharCode(...bytes);
1391
- if (binaryVersion !== "0.27.7") {
1392
- throw new Error(`Cannot start service: Host version "${"0.27.7"}" does not match binary version ${quote(binaryVersion)}`);
1400
+ if (binaryVersion !== "0.28.1") {
1401
+ throw new Error(`Cannot start service: Host version "${"0.28.1"}" does not match binary version ${quote(binaryVersion)}`);
1393
1402
  }
1394
1403
  return;
1395
1404
  }
@@ -2522,7 +2531,7 @@ for your current platform.`);
2522
2531
  "node_modules",
2523
2532
  ".cache",
2524
2533
  "esbuild",
2525
- `pnpapi-${pkg.replace("/", "-")}-${"0.27.7"}-${path.basename(subpath)}`
2534
+ `pnpapi-${pkg.replace("/", "-")}-${"0.28.1"}-${path.basename(subpath)}`
2526
2535
  );
2527
2536
  if (!fs2.existsSync(binTargetPath)) {
2528
2537
  fs2.mkdirSync(path.dirname(binTargetPath), { recursive: true });
@@ -2555,7 +2564,7 @@ for your current platform.`);
2555
2564
  }
2556
2565
  }
2557
2566
  var _a;
2558
- var isInternalWorkerThread = ((_a = worker_threads == null ? void 0 : worker_threads.workerData) == null ? void 0 : _a.esbuildVersion) === "0.27.7";
2567
+ var isInternalWorkerThread = ((_a = worker_threads == null ? void 0 : worker_threads.workerData) == null ? void 0 : _a.esbuildVersion) === "0.28.1";
2559
2568
  var esbuildCommandAndArgs = () => {
2560
2569
  if ((!ESBUILD_BINARY_PATH || false) && (path2.basename(__filename) !== "main.js" || path2.basename(__dirname) !== "lib")) {
2561
2570
  throw new Error(
@@ -2622,7 +2631,7 @@ More information: The file containing the code for esbuild's JavaScript API (${_
2622
2631
  }
2623
2632
  }
2624
2633
  };
2625
- var version = "0.27.7";
2634
+ var version = "0.28.1";
2626
2635
  var build = (options) => ensureServiceIsRunning().build(options);
2627
2636
  var context = (buildOptions) => ensureServiceIsRunning().context(buildOptions);
2628
2637
  var transform = (input, options) => ensureServiceIsRunning().transform(input, options);
@@ -2725,7 +2734,7 @@ More information: The file containing the code for esbuild's JavaScript API (${_
2725
2734
  var ensureServiceIsRunning = () => {
2726
2735
  if (longLivedService) return longLivedService;
2727
2736
  let [command, args] = esbuildCommandAndArgs();
2728
- let child = child_process.spawn(command, args.concat(`--service=${"0.27.7"}`, "--ping"), {
2737
+ let child = child_process.spawn(command, args.concat(`--service=${"0.28.1"}`, "--ping"), {
2729
2738
  windowsHide: true,
2730
2739
  stdio: ["pipe", "pipe", "inherit"],
2731
2740
  cwd: defaultWD
@@ -2829,7 +2838,7 @@ More information: The file containing the code for esbuild's JavaScript API (${_
2829
2838
  esbuild: node_exports
2830
2839
  });
2831
2840
  callback(service);
2832
- let stdout = child_process.execFileSync(command, args.concat(`--service=${"0.27.7"}`), {
2841
+ let stdout = child_process.execFileSync(command, args.concat(`--service=${"0.28.1"}`), {
2833
2842
  cwd: defaultWD,
2834
2843
  windowsHide: true,
2835
2844
  input: stdin,
@@ -2849,7 +2858,7 @@ More information: The file containing the code for esbuild's JavaScript API (${_
2849
2858
  var startWorkerThreadService = (worker_threads2) => {
2850
2859
  let { port1: mainPort, port2: workerPort } = new worker_threads2.MessageChannel();
2851
2860
  let worker = new worker_threads2.Worker(__filename, {
2852
- workerData: { workerPort, defaultWD, esbuildVersion: "0.27.7" },
2861
+ workerData: { workerPort, defaultWD, esbuildVersion: "0.28.1" },
2853
2862
  transferList: [workerPort],
2854
2863
  // From node's documentation: https://nodejs.org/api/worker_threads.html
2855
2864
  //
@@ -5203,6 +5212,217 @@ error: ${text}`);
5203
5212
  var import_node_http = __require("http");
5204
5213
  var import_node_https = __require("https");
5205
5214
  var import_node_net = __require("net");
5215
+ var import_promises = __require("dns/promises");
5216
+ var BLOCKED_IPV4_PREFIXES = [
5217
+ "0.",
5218
+ "10.",
5219
+ "100.64.",
5220
+ "100.65.",
5221
+ "100.66.",
5222
+ "100.67.",
5223
+ "100.68.",
5224
+ "100.69.",
5225
+ "100.70.",
5226
+ "100.71.",
5227
+ "100.72.",
5228
+ "100.73.",
5229
+ "100.74.",
5230
+ "100.75.",
5231
+ "100.76.",
5232
+ "100.77.",
5233
+ "100.78.",
5234
+ "100.79.",
5235
+ "100.80.",
5236
+ "100.81.",
5237
+ "100.82.",
5238
+ "100.83.",
5239
+ "100.84.",
5240
+ "100.85.",
5241
+ "100.86.",
5242
+ "100.87.",
5243
+ "100.88.",
5244
+ "100.89.",
5245
+ "100.90.",
5246
+ "100.91.",
5247
+ "100.92.",
5248
+ "100.93.",
5249
+ "100.94.",
5250
+ "100.95.",
5251
+ "100.96.",
5252
+ "100.97.",
5253
+ "100.98.",
5254
+ "100.99.",
5255
+ "100.100.",
5256
+ "100.101.",
5257
+ "100.102.",
5258
+ "100.103.",
5259
+ "100.104.",
5260
+ "100.105.",
5261
+ "100.106.",
5262
+ "100.107.",
5263
+ "100.108.",
5264
+ "100.109.",
5265
+ "100.110.",
5266
+ "100.111.",
5267
+ "100.112.",
5268
+ "100.113.",
5269
+ "100.114.",
5270
+ "100.115.",
5271
+ "100.116.",
5272
+ "100.117.",
5273
+ "100.118.",
5274
+ "100.119.",
5275
+ "100.120.",
5276
+ "100.121.",
5277
+ "100.122.",
5278
+ "100.123.",
5279
+ "100.124.",
5280
+ "100.125.",
5281
+ "100.126.",
5282
+ "100.127.",
5283
+ "127.",
5284
+ "169.254.",
5285
+ "172.16.",
5286
+ "172.17.",
5287
+ "172.18.",
5288
+ "172.19.",
5289
+ "172.20.",
5290
+ "172.21.",
5291
+ "172.22.",
5292
+ "172.23.",
5293
+ "172.24.",
5294
+ "172.25.",
5295
+ "172.26.",
5296
+ "172.27.",
5297
+ "172.28.",
5298
+ "172.29.",
5299
+ "172.30.",
5300
+ "172.31.",
5301
+ "192.0.2.",
5302
+ "192.88.99.",
5303
+ "192.168.",
5304
+ "198.18.",
5305
+ "198.19.",
5306
+ "198.51.100.",
5307
+ "203.0.113.",
5308
+ "224.",
5309
+ "225.",
5310
+ "226.",
5311
+ "227.",
5312
+ "228.",
5313
+ "229.",
5314
+ "230.",
5315
+ "231.",
5316
+ "232.",
5317
+ "233.",
5318
+ "234.",
5319
+ "235.",
5320
+ "236.",
5321
+ "237.",
5322
+ "238.",
5323
+ "239.",
5324
+ "240.",
5325
+ "241.",
5326
+ "242.",
5327
+ "243.",
5328
+ "244.",
5329
+ "245.",
5330
+ "246.",
5331
+ "247.",
5332
+ "248.",
5333
+ "249.",
5334
+ "250.",
5335
+ "251.",
5336
+ "252.",
5337
+ "253.",
5338
+ "254.",
5339
+ "255."
5340
+ ];
5341
+ var ALLOWED_PROXY_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
5342
+ function isBlockedIpv4(hostname) {
5343
+ const octets = hostname.split(".");
5344
+ if (octets.length !== 4) return false;
5345
+ const joined = hostname;
5346
+ return BLOCKED_IPV4_PREFIXES.some((prefix) => joined.startsWith(prefix));
5347
+ }
5348
+ function isBlockedIpv6(hostname) {
5349
+ const lower = hostname.toLowerCase();
5350
+ if (lower === "::1" || lower === "::" || lower === "0:0:0:0:0:0:0:1" || lower === "0:0:0:0:0:0:0:0") {
5351
+ return true;
5352
+ }
5353
+ const ffffMatch = lower.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/);
5354
+ if (ffffMatch) {
5355
+ return isBlockedIpv4(ffffMatch[1]);
5356
+ }
5357
+ const compatMatch = lower.match(/^::(\d+\.\d+\.\d+\.\d+)$/);
5358
+ if (compatMatch) {
5359
+ return isBlockedIpv4(compatMatch[1]);
5360
+ }
5361
+ return false;
5362
+ }
5363
+ function isSafeHostname(hostname) {
5364
+ if (!hostname) return false;
5365
+ if (/^\d{1,3}(\.\d{1,3}){3}$/.test(hostname)) return !isBlockedIpv4(hostname);
5366
+ if (/^\[.*\]$/.test(hostname)) return !isBlockedIpv6(hostname.slice(1, -1));
5367
+ if (hostname.includes(":")) return !isBlockedIpv6(hostname);
5368
+ return true;
5369
+ }
5370
+ async function safeResolveHostname(hostname) {
5371
+ try {
5372
+ const result = await (0, import_promises.lookup)(hostname);
5373
+ const ip = result.address;
5374
+ if (isBlockedIpv4(ip) || isBlockedIpv6(ip)) {
5375
+ throw new Error(`PM proxy target resolved to a blocked address: ${ip}`);
5376
+ }
5377
+ return ip;
5378
+ } catch (error) {
5379
+ if (error instanceof Error && error.message.includes("blocked address")) {
5380
+ throw error;
5381
+ }
5382
+ throw new Error(`PM proxy failed to resolve target hostname "${hostname}": ${error instanceof Error ? error.message : String(error)}`);
5383
+ }
5384
+ }
5385
+ async function validateProxyTargetUrl(target) {
5386
+ if (!ALLOWED_PROXY_PROTOCOLS.has(target.protocol)) {
5387
+ throw new Error(`PM proxy target protocol "${target.protocol}" is not allowed. Only http: and https: are permitted.`);
5388
+ }
5389
+ const hostname = target.hostname;
5390
+ if (!isSafeHostname(hostname)) {
5391
+ throw new Error(`PM proxy target "${hostname}" resolves to a blocked address and is not allowed.`);
5392
+ }
5393
+ if (!/^\d{1,3}(\.\d{1,3}){3}$/.test(hostname) && !/^\[.*\]$/.test(hostname)) {
5394
+ await safeResolveHostname(hostname);
5395
+ }
5396
+ }
5397
+ function sanitizeProxyRequestPath(requestUrl) {
5398
+ if (!requestUrl || requestUrl === "/") return "/";
5399
+ try {
5400
+ const normalizedInput = requestUrl.replace(/\\/g, "/");
5401
+ const parsed = new URL(normalizedInput, "http://placeholder");
5402
+ if (parsed.username || parsed.password || parsed.hostname !== "placeholder" || parsed.port) {
5403
+ return "/";
5404
+ }
5405
+ const pathname = parsed.pathname || "/";
5406
+ let decodedPathname = pathname;
5407
+ try {
5408
+ decodedPathname = decodeURIComponent(pathname);
5409
+ } catch {
5410
+ return "/";
5411
+ }
5412
+ const lowerPath = pathname.toLowerCase();
5413
+ if (lowerPath.includes("%2f") || lowerPath.includes("%5c") || lowerPath.includes("%40") || lowerPath.includes("%00")) {
5414
+ return "/";
5415
+ }
5416
+ const segments = decodedPathname.split("/");
5417
+ if (segments.some((segment) => segment === "." || segment === "..")) {
5418
+ return "/";
5419
+ }
5420
+ const sanitized = pathname + parsed.search;
5421
+ return sanitized.startsWith("/") ? sanitized || "/" : `/${sanitized}`;
5422
+ } catch {
5423
+ return "/";
5424
+ }
5425
+ }
5206
5426
  function resolvePmProxyHost(proxy) {
5207
5427
  return proxy.host?.trim() || "0.0.0.0";
5208
5428
  }
@@ -5292,6 +5512,9 @@ error: ${text}`);
5292
5512
  nextTargetIndex = (nextTargetIndex + 1) % targets.length;
5293
5513
  return target;
5294
5514
  };
5515
+ const validateTarget = async (target) => {
5516
+ await validateProxyTargetUrl(target);
5517
+ };
5295
5518
  const server = (0, import_node_http.createServer)((req, res) => {
5296
5519
  const target = pickTarget();
5297
5520
  if (!target) {
@@ -5299,29 +5522,45 @@ error: ${text}`);
5299
5522
  res.end("PM proxy target is not ready.");
5300
5523
  return;
5301
5524
  }
5525
+ const sanitizedPath = sanitizeProxyRequestPath(req.url || "/");
5302
5526
  const requestLib = target.protocol === "https:" ? import_node_https.request : import_node_http.request;
5303
- const targetUrl = new URL(req.url || "/", target);
5304
5527
  const headers = buildPmProxyHeaders(req.headers, target.host);
5305
- const proxyReq = requestLib(targetUrl, {
5306
- method: req.method,
5307
- headers
5308
- }, (proxyRes) => {
5309
- const outgoingHeaders = {};
5310
- for (const [key, value] of Object.entries(proxyRes.headers)) {
5311
- if (value !== void 0) {
5312
- outgoingHeaders[key] = value;
5528
+ if (!ALLOWED_PROXY_PROTOCOLS.has(target.protocol)) {
5529
+ res.statusCode = 400;
5530
+ res.end("PM proxy rejected unsafe target protocol.");
5531
+ return;
5532
+ }
5533
+ validateTarget(target).then(() => {
5534
+ const proxyReq = requestLib({
5535
+ protocol: target.protocol,
5536
+ hostname: target.hostname,
5537
+ port: target.port || void 0,
5538
+ path: sanitizedPath,
5539
+ method: req.method,
5540
+ headers
5541
+ }, (proxyRes) => {
5542
+ const outgoingHeaders = {};
5543
+ for (const [key, value] of Object.entries(proxyRes.headers)) {
5544
+ if (value !== void 0) {
5545
+ outgoingHeaders[key] = value;
5546
+ }
5313
5547
  }
5314
- }
5315
- res.writeHead(proxyRes.statusCode || 200, outgoingHeaders);
5316
- proxyRes.pipe(res);
5317
- });
5318
- proxyReq.on("error", (error) => {
5548
+ res.writeHead(proxyRes.statusCode || 200, outgoingHeaders);
5549
+ proxyRes.pipe(res);
5550
+ });
5551
+ proxyReq.on("error", (error) => {
5552
+ if (!res.headersSent) {
5553
+ res.statusCode = 502;
5554
+ }
5555
+ res.end(`PM proxy error: ${error.message}`);
5556
+ });
5557
+ req.pipe(proxyReq);
5558
+ }).catch((error) => {
5319
5559
  if (!res.headersSent) {
5320
- res.statusCode = 502;
5560
+ res.statusCode = 403;
5321
5561
  }
5322
- res.end(`PM proxy error: ${error.message}`);
5562
+ res.end(`PM proxy blocked target: ${error instanceof Error ? error.message : String(error)}`);
5323
5563
  });
5324
- req.pipe(proxyReq);
5325
5564
  });
5326
5565
  server.on("upgrade", (req, socket, head) => {
5327
5566
  const target = pickTarget();
@@ -5333,38 +5572,56 @@ error: ${text}`);
5333
5572
  socket.destroy();
5334
5573
  return;
5335
5574
  }
5575
+ const sanitizedPath = sanitizeProxyRequestPath(req.url || "/");
5336
5576
  const requestLib = target.protocol === "https:" ? import_node_https.request : import_node_http.request;
5337
- const targetUrl = new URL(req.url || "/", target);
5338
- const proxyReq = requestLib(targetUrl, {
5339
- method: req.method,
5340
- headers: buildPmProxyHeaders(req.headers, target.host)
5341
- });
5342
- proxyReq.on("upgrade", (proxyRes, proxySocket, proxyHead) => {
5343
- writeRawHttpResponse(socket, proxyRes.statusCode || 101, proxyRes.statusMessage || "Switching Protocols", proxyRes.headers);
5344
- if (head.length > 0) {
5345
- proxySocket.write(head);
5346
- }
5347
- if (proxyHead.length > 0) {
5348
- socket.write(proxyHead);
5349
- }
5350
- socket.on("error", () => proxySocket.destroy());
5351
- proxySocket.on("error", () => socket.destroy());
5352
- proxySocket.pipe(socket);
5353
- socket.pipe(proxySocket);
5354
- });
5355
- proxyReq.on("response", (proxyRes) => {
5356
- writeRawHttpResponse(socket, proxyRes.statusCode || 502, proxyRes.statusMessage || "Bad Gateway", proxyRes.headers);
5357
- proxyRes.pipe(socket);
5358
- });
5359
- proxyReq.on("error", (error) => {
5360
- writeRawHttpResponse(socket, 502, "Bad Gateway", {
5577
+ const targetUrl = new URL(sanitizedPath, target);
5578
+ if (targetUrl.hostname !== target.hostname || targetUrl.port !== target.port || !ALLOWED_PROXY_PROTOCOLS.has(targetUrl.protocol)) {
5579
+ writeRawHttpResponse(socket, 400, "Bad Request", {
5580
+ connection: "close",
5581
+ "content-length": 0
5582
+ });
5583
+ socket.destroy();
5584
+ return;
5585
+ }
5586
+ validateTarget(target).then(() => {
5587
+ const proxyReq = requestLib(targetUrl, {
5588
+ method: req.method,
5589
+ headers: buildPmProxyHeaders(req.headers, target.host)
5590
+ });
5591
+ proxyReq.on("upgrade", (proxyRes, proxySocket, proxyHead) => {
5592
+ writeRawHttpResponse(socket, proxyRes.statusCode || 101, proxyRes.statusMessage || "Switching Protocols", proxyRes.headers);
5593
+ if (head.length > 0) {
5594
+ proxySocket.write(head);
5595
+ }
5596
+ if (proxyHead.length > 0) {
5597
+ socket.write(proxyHead);
5598
+ }
5599
+ socket.on("error", () => proxySocket.destroy());
5600
+ proxySocket.on("error", () => socket.destroy());
5601
+ proxySocket.pipe(socket);
5602
+ socket.pipe(proxySocket);
5603
+ });
5604
+ proxyReq.on("response", (proxyRes) => {
5605
+ writeRawHttpResponse(socket, proxyRes.statusCode || 502, proxyRes.statusMessage || "Bad Gateway", proxyRes.headers);
5606
+ proxyRes.pipe(socket);
5607
+ });
5608
+ proxyReq.on("error", (error) => {
5609
+ writeRawHttpResponse(socket, 502, "Bad Gateway", {
5610
+ connection: "close",
5611
+ "content-type": "text/plain; charset=utf-8",
5612
+ "content-length": Buffer.byteLength(`PM proxy error: ${error.message}`)
5613
+ });
5614
+ socket.end(`PM proxy error: ${error.message}`);
5615
+ });
5616
+ proxyReq.end();
5617
+ }).catch((error) => {
5618
+ writeRawHttpResponse(socket, 403, "Forbidden", {
5361
5619
  connection: "close",
5362
5620
  "content-type": "text/plain; charset=utf-8",
5363
- "content-length": Buffer.byteLength(`PM proxy error: ${error.message}`)
5621
+ "content-length": Buffer.byteLength(`PM proxy blocked target: ${error instanceof Error ? error.message : String(error)}`)
5364
5622
  });
5365
- socket.end(`PM proxy error: ${error.message}`);
5623
+ socket.end(`PM proxy blocked target: ${error instanceof Error ? error.message : String(error)}`);
5366
5624
  });
5367
- proxyReq.end();
5368
5625
  });
5369
5626
  await new Promise((resolve7, reject) => {
5370
5627
  server.once("error", reject);
@@ -5372,10 +5629,25 @@ error: ${text}`);
5372
5629
  });
5373
5630
  return {
5374
5631
  setTarget(targetUrl) {
5375
- setResolvedTargets(targetUrl ? [new URL(targetUrl)] : []);
5632
+ if (targetUrl) {
5633
+ const parsed = new URL(targetUrl);
5634
+ validateProxyTargetUrl(parsed).then(() => {
5635
+ setResolvedTargets([parsed]);
5636
+ }).catch((error) => {
5637
+ console.error(`[PM proxy] Blocked setTarget: ${error instanceof Error ? error.message : String(error)}`);
5638
+ setResolvedTargets([]);
5639
+ });
5640
+ } else {
5641
+ setResolvedTargets([]);
5642
+ }
5376
5643
  },
5377
5644
  setTargets(targetUrls) {
5378
- setResolvedTargets(targetUrls.map((targetUrl) => new URL(targetUrl)));
5645
+ Promise.all(targetUrls.map((url) => validateProxyTargetUrl(new URL(url)))).then(() => {
5646
+ setResolvedTargets(targetUrls.map((targetUrl) => new URL(targetUrl)));
5647
+ }).catch((error) => {
5648
+ console.error(`[PM proxy] Blocked setTargets: ${error instanceof Error ? error.message : String(error)}`);
5649
+ setResolvedTargets([]);
5650
+ });
5379
5651
  },
5380
5652
  close() {
5381
5653
  return new Promise((resolve7, reject) => {