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.cjs CHANGED
@@ -5,8 +5,13 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __esm = (fn, res) => function __init() {
9
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ var __esm = (fn, res, err) => function __init() {
9
+ if (err) throw err[0];
10
+ try {
11
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
12
+ } catch (e) {
13
+ throw err = [e], e;
14
+ }
10
15
  };
11
16
  var __export = (target, all) => {
12
17
  for (var name in all)
@@ -2796,6 +2801,217 @@ function watch(paths, options) {
2796
2801
  var import_node_http = require("http");
2797
2802
  var import_node_https = require("https");
2798
2803
  var import_node_net = require("net");
2804
+ var import_promises = require("dns/promises");
2805
+ var BLOCKED_IPV4_PREFIXES = [
2806
+ "0.",
2807
+ "10.",
2808
+ "100.64.",
2809
+ "100.65.",
2810
+ "100.66.",
2811
+ "100.67.",
2812
+ "100.68.",
2813
+ "100.69.",
2814
+ "100.70.",
2815
+ "100.71.",
2816
+ "100.72.",
2817
+ "100.73.",
2818
+ "100.74.",
2819
+ "100.75.",
2820
+ "100.76.",
2821
+ "100.77.",
2822
+ "100.78.",
2823
+ "100.79.",
2824
+ "100.80.",
2825
+ "100.81.",
2826
+ "100.82.",
2827
+ "100.83.",
2828
+ "100.84.",
2829
+ "100.85.",
2830
+ "100.86.",
2831
+ "100.87.",
2832
+ "100.88.",
2833
+ "100.89.",
2834
+ "100.90.",
2835
+ "100.91.",
2836
+ "100.92.",
2837
+ "100.93.",
2838
+ "100.94.",
2839
+ "100.95.",
2840
+ "100.96.",
2841
+ "100.97.",
2842
+ "100.98.",
2843
+ "100.99.",
2844
+ "100.100.",
2845
+ "100.101.",
2846
+ "100.102.",
2847
+ "100.103.",
2848
+ "100.104.",
2849
+ "100.105.",
2850
+ "100.106.",
2851
+ "100.107.",
2852
+ "100.108.",
2853
+ "100.109.",
2854
+ "100.110.",
2855
+ "100.111.",
2856
+ "100.112.",
2857
+ "100.113.",
2858
+ "100.114.",
2859
+ "100.115.",
2860
+ "100.116.",
2861
+ "100.117.",
2862
+ "100.118.",
2863
+ "100.119.",
2864
+ "100.120.",
2865
+ "100.121.",
2866
+ "100.122.",
2867
+ "100.123.",
2868
+ "100.124.",
2869
+ "100.125.",
2870
+ "100.126.",
2871
+ "100.127.",
2872
+ "127.",
2873
+ "169.254.",
2874
+ "172.16.",
2875
+ "172.17.",
2876
+ "172.18.",
2877
+ "172.19.",
2878
+ "172.20.",
2879
+ "172.21.",
2880
+ "172.22.",
2881
+ "172.23.",
2882
+ "172.24.",
2883
+ "172.25.",
2884
+ "172.26.",
2885
+ "172.27.",
2886
+ "172.28.",
2887
+ "172.29.",
2888
+ "172.30.",
2889
+ "172.31.",
2890
+ "192.0.2.",
2891
+ "192.88.99.",
2892
+ "192.168.",
2893
+ "198.18.",
2894
+ "198.19.",
2895
+ "198.51.100.",
2896
+ "203.0.113.",
2897
+ "224.",
2898
+ "225.",
2899
+ "226.",
2900
+ "227.",
2901
+ "228.",
2902
+ "229.",
2903
+ "230.",
2904
+ "231.",
2905
+ "232.",
2906
+ "233.",
2907
+ "234.",
2908
+ "235.",
2909
+ "236.",
2910
+ "237.",
2911
+ "238.",
2912
+ "239.",
2913
+ "240.",
2914
+ "241.",
2915
+ "242.",
2916
+ "243.",
2917
+ "244.",
2918
+ "245.",
2919
+ "246.",
2920
+ "247.",
2921
+ "248.",
2922
+ "249.",
2923
+ "250.",
2924
+ "251.",
2925
+ "252.",
2926
+ "253.",
2927
+ "254.",
2928
+ "255."
2929
+ ];
2930
+ var ALLOWED_PROXY_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
2931
+ function isBlockedIpv4(hostname) {
2932
+ const octets = hostname.split(".");
2933
+ if (octets.length !== 4) return false;
2934
+ const joined = hostname;
2935
+ return BLOCKED_IPV4_PREFIXES.some((prefix) => joined.startsWith(prefix));
2936
+ }
2937
+ function isBlockedIpv6(hostname) {
2938
+ const lower = hostname.toLowerCase();
2939
+ if (lower === "::1" || lower === "::" || lower === "0:0:0:0:0:0:0:1" || lower === "0:0:0:0:0:0:0:0") {
2940
+ return true;
2941
+ }
2942
+ const ffffMatch = lower.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/);
2943
+ if (ffffMatch) {
2944
+ return isBlockedIpv4(ffffMatch[1]);
2945
+ }
2946
+ const compatMatch = lower.match(/^::(\d+\.\d+\.\d+\.\d+)$/);
2947
+ if (compatMatch) {
2948
+ return isBlockedIpv4(compatMatch[1]);
2949
+ }
2950
+ return false;
2951
+ }
2952
+ function isSafeHostname(hostname) {
2953
+ if (!hostname) return false;
2954
+ if (/^\d{1,3}(\.\d{1,3}){3}$/.test(hostname)) return !isBlockedIpv4(hostname);
2955
+ if (/^\[.*\]$/.test(hostname)) return !isBlockedIpv6(hostname.slice(1, -1));
2956
+ if (hostname.includes(":")) return !isBlockedIpv6(hostname);
2957
+ return true;
2958
+ }
2959
+ async function safeResolveHostname(hostname) {
2960
+ try {
2961
+ const result = await (0, import_promises.lookup)(hostname);
2962
+ const ip = result.address;
2963
+ if (isBlockedIpv4(ip) || isBlockedIpv6(ip)) {
2964
+ throw new Error(`PM proxy target resolved to a blocked address: ${ip}`);
2965
+ }
2966
+ return ip;
2967
+ } catch (error) {
2968
+ if (error instanceof Error && error.message.includes("blocked address")) {
2969
+ throw error;
2970
+ }
2971
+ throw new Error(`PM proxy failed to resolve target hostname "${hostname}": ${error instanceof Error ? error.message : String(error)}`);
2972
+ }
2973
+ }
2974
+ async function validateProxyTargetUrl(target) {
2975
+ if (!ALLOWED_PROXY_PROTOCOLS.has(target.protocol)) {
2976
+ throw new Error(`PM proxy target protocol "${target.protocol}" is not allowed. Only http: and https: are permitted.`);
2977
+ }
2978
+ const hostname = target.hostname;
2979
+ if (!isSafeHostname(hostname)) {
2980
+ throw new Error(`PM proxy target "${hostname}" resolves to a blocked address and is not allowed.`);
2981
+ }
2982
+ if (!/^\d{1,3}(\.\d{1,3}){3}$/.test(hostname) && !/^\[.*\]$/.test(hostname)) {
2983
+ await safeResolveHostname(hostname);
2984
+ }
2985
+ }
2986
+ function sanitizeProxyRequestPath(requestUrl) {
2987
+ if (!requestUrl || requestUrl === "/") return "/";
2988
+ try {
2989
+ const normalizedInput = requestUrl.replace(/\\/g, "/");
2990
+ const parsed = new URL(normalizedInput, "http://placeholder");
2991
+ if (parsed.username || parsed.password || parsed.hostname !== "placeholder" || parsed.port) {
2992
+ return "/";
2993
+ }
2994
+ const pathname = parsed.pathname || "/";
2995
+ let decodedPathname = pathname;
2996
+ try {
2997
+ decodedPathname = decodeURIComponent(pathname);
2998
+ } catch {
2999
+ return "/";
3000
+ }
3001
+ const lowerPath = pathname.toLowerCase();
3002
+ if (lowerPath.includes("%2f") || lowerPath.includes("%5c") || lowerPath.includes("%40") || lowerPath.includes("%00")) {
3003
+ return "/";
3004
+ }
3005
+ const segments = decodedPathname.split("/");
3006
+ if (segments.some((segment) => segment === "." || segment === "..")) {
3007
+ return "/";
3008
+ }
3009
+ const sanitized = pathname + parsed.search;
3010
+ return sanitized.startsWith("/") ? sanitized || "/" : `/${sanitized}`;
3011
+ } catch {
3012
+ return "/";
3013
+ }
3014
+ }
2799
3015
  function resolvePmProxyHost(proxy) {
2800
3016
  return proxy.host?.trim() || "0.0.0.0";
2801
3017
  }
@@ -2885,6 +3101,9 @@ async function createPmProxyController(proxy) {
2885
3101
  nextTargetIndex = (nextTargetIndex + 1) % targets.length;
2886
3102
  return target;
2887
3103
  };
3104
+ const validateTarget = async (target) => {
3105
+ await validateProxyTargetUrl(target);
3106
+ };
2888
3107
  const server = (0, import_node_http.createServer)((req, res) => {
2889
3108
  const target = pickTarget();
2890
3109
  if (!target) {
@@ -2892,29 +3111,45 @@ async function createPmProxyController(proxy) {
2892
3111
  res.end("PM proxy target is not ready.");
2893
3112
  return;
2894
3113
  }
3114
+ const sanitizedPath = sanitizeProxyRequestPath(req.url || "/");
2895
3115
  const requestLib = target.protocol === "https:" ? import_node_https.request : import_node_http.request;
2896
- const targetUrl = new URL(req.url || "/", target);
2897
3116
  const headers = buildPmProxyHeaders(req.headers, target.host);
2898
- const proxyReq = requestLib(targetUrl, {
2899
- method: req.method,
2900
- headers
2901
- }, (proxyRes) => {
2902
- const outgoingHeaders = {};
2903
- for (const [key, value] of Object.entries(proxyRes.headers)) {
2904
- if (value !== void 0) {
2905
- outgoingHeaders[key] = value;
3117
+ if (!ALLOWED_PROXY_PROTOCOLS.has(target.protocol)) {
3118
+ res.statusCode = 400;
3119
+ res.end("PM proxy rejected unsafe target protocol.");
3120
+ return;
3121
+ }
3122
+ validateTarget(target).then(() => {
3123
+ const proxyReq = requestLib({
3124
+ protocol: target.protocol,
3125
+ hostname: target.hostname,
3126
+ port: target.port || void 0,
3127
+ path: sanitizedPath,
3128
+ method: req.method,
3129
+ headers
3130
+ }, (proxyRes) => {
3131
+ const outgoingHeaders = {};
3132
+ for (const [key, value] of Object.entries(proxyRes.headers)) {
3133
+ if (value !== void 0) {
3134
+ outgoingHeaders[key] = value;
3135
+ }
2906
3136
  }
2907
- }
2908
- res.writeHead(proxyRes.statusCode || 200, outgoingHeaders);
2909
- proxyRes.pipe(res);
2910
- });
2911
- proxyReq.on("error", (error) => {
3137
+ res.writeHead(proxyRes.statusCode || 200, outgoingHeaders);
3138
+ proxyRes.pipe(res);
3139
+ });
3140
+ proxyReq.on("error", (error) => {
3141
+ if (!res.headersSent) {
3142
+ res.statusCode = 502;
3143
+ }
3144
+ res.end(`PM proxy error: ${error.message}`);
3145
+ });
3146
+ req.pipe(proxyReq);
3147
+ }).catch((error) => {
2912
3148
  if (!res.headersSent) {
2913
- res.statusCode = 502;
3149
+ res.statusCode = 403;
2914
3150
  }
2915
- res.end(`PM proxy error: ${error.message}`);
3151
+ res.end(`PM proxy blocked target: ${error instanceof Error ? error.message : String(error)}`);
2916
3152
  });
2917
- req.pipe(proxyReq);
2918
3153
  });
2919
3154
  server.on("upgrade", (req, socket, head) => {
2920
3155
  const target = pickTarget();
@@ -2926,38 +3161,56 @@ async function createPmProxyController(proxy) {
2926
3161
  socket.destroy();
2927
3162
  return;
2928
3163
  }
3164
+ const sanitizedPath = sanitizeProxyRequestPath(req.url || "/");
2929
3165
  const requestLib = target.protocol === "https:" ? import_node_https.request : import_node_http.request;
2930
- const targetUrl = new URL(req.url || "/", target);
2931
- const proxyReq = requestLib(targetUrl, {
2932
- method: req.method,
2933
- headers: buildPmProxyHeaders(req.headers, target.host)
2934
- });
2935
- proxyReq.on("upgrade", (proxyRes, proxySocket, proxyHead) => {
2936
- writeRawHttpResponse(socket, proxyRes.statusCode || 101, proxyRes.statusMessage || "Switching Protocols", proxyRes.headers);
2937
- if (head.length > 0) {
2938
- proxySocket.write(head);
2939
- }
2940
- if (proxyHead.length > 0) {
2941
- socket.write(proxyHead);
2942
- }
2943
- socket.on("error", () => proxySocket.destroy());
2944
- proxySocket.on("error", () => socket.destroy());
2945
- proxySocket.pipe(socket);
2946
- socket.pipe(proxySocket);
2947
- });
2948
- proxyReq.on("response", (proxyRes) => {
2949
- writeRawHttpResponse(socket, proxyRes.statusCode || 502, proxyRes.statusMessage || "Bad Gateway", proxyRes.headers);
2950
- proxyRes.pipe(socket);
2951
- });
2952
- proxyReq.on("error", (error) => {
2953
- writeRawHttpResponse(socket, 502, "Bad Gateway", {
3166
+ const targetUrl = new URL(sanitizedPath, target);
3167
+ if (targetUrl.hostname !== target.hostname || targetUrl.port !== target.port || !ALLOWED_PROXY_PROTOCOLS.has(targetUrl.protocol)) {
3168
+ writeRawHttpResponse(socket, 400, "Bad Request", {
3169
+ connection: "close",
3170
+ "content-length": 0
3171
+ });
3172
+ socket.destroy();
3173
+ return;
3174
+ }
3175
+ validateTarget(target).then(() => {
3176
+ const proxyReq = requestLib(targetUrl, {
3177
+ method: req.method,
3178
+ headers: buildPmProxyHeaders(req.headers, target.host)
3179
+ });
3180
+ proxyReq.on("upgrade", (proxyRes, proxySocket, proxyHead) => {
3181
+ writeRawHttpResponse(socket, proxyRes.statusCode || 101, proxyRes.statusMessage || "Switching Protocols", proxyRes.headers);
3182
+ if (head.length > 0) {
3183
+ proxySocket.write(head);
3184
+ }
3185
+ if (proxyHead.length > 0) {
3186
+ socket.write(proxyHead);
3187
+ }
3188
+ socket.on("error", () => proxySocket.destroy());
3189
+ proxySocket.on("error", () => socket.destroy());
3190
+ proxySocket.pipe(socket);
3191
+ socket.pipe(proxySocket);
3192
+ });
3193
+ proxyReq.on("response", (proxyRes) => {
3194
+ writeRawHttpResponse(socket, proxyRes.statusCode || 502, proxyRes.statusMessage || "Bad Gateway", proxyRes.headers);
3195
+ proxyRes.pipe(socket);
3196
+ });
3197
+ proxyReq.on("error", (error) => {
3198
+ writeRawHttpResponse(socket, 502, "Bad Gateway", {
3199
+ connection: "close",
3200
+ "content-type": "text/plain; charset=utf-8",
3201
+ "content-length": Buffer.byteLength(`PM proxy error: ${error.message}`)
3202
+ });
3203
+ socket.end(`PM proxy error: ${error.message}`);
3204
+ });
3205
+ proxyReq.end();
3206
+ }).catch((error) => {
3207
+ writeRawHttpResponse(socket, 403, "Forbidden", {
2954
3208
  connection: "close",
2955
3209
  "content-type": "text/plain; charset=utf-8",
2956
- "content-length": Buffer.byteLength(`PM proxy error: ${error.message}`)
3210
+ "content-length": Buffer.byteLength(`PM proxy blocked target: ${error instanceof Error ? error.message : String(error)}`)
2957
3211
  });
2958
- socket.end(`PM proxy error: ${error.message}`);
3212
+ socket.end(`PM proxy blocked target: ${error instanceof Error ? error.message : String(error)}`);
2959
3213
  });
2960
- proxyReq.end();
2961
3214
  });
2962
3215
  await new Promise((resolve7, reject) => {
2963
3216
  server.once("error", reject);
@@ -2965,10 +3218,25 @@ async function createPmProxyController(proxy) {
2965
3218
  });
2966
3219
  return {
2967
3220
  setTarget(targetUrl) {
2968
- setResolvedTargets(targetUrl ? [new URL(targetUrl)] : []);
3221
+ if (targetUrl) {
3222
+ const parsed = new URL(targetUrl);
3223
+ validateProxyTargetUrl(parsed).then(() => {
3224
+ setResolvedTargets([parsed]);
3225
+ }).catch((error) => {
3226
+ console.error(`[PM proxy] Blocked setTarget: ${error instanceof Error ? error.message : String(error)}`);
3227
+ setResolvedTargets([]);
3228
+ });
3229
+ } else {
3230
+ setResolvedTargets([]);
3231
+ }
2969
3232
  },
2970
3233
  setTargets(targetUrls) {
2971
- setResolvedTargets(targetUrls.map((targetUrl) => new URL(targetUrl)));
3234
+ Promise.all(targetUrls.map((url) => validateProxyTargetUrl(new URL(url)))).then(() => {
3235
+ setResolvedTargets(targetUrls.map((targetUrl) => new URL(targetUrl)));
3236
+ }).catch((error) => {
3237
+ console.error(`[PM proxy] Blocked setTargets: ${error instanceof Error ? error.message : String(error)}`);
3238
+ setResolvedTargets([]);
3239
+ });
2972
3240
  },
2973
3241
  close() {
2974
3242
  return new Promise((resolve7, reject) => {
package/dist/pm.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { P as PmRuntimeName, a as PmProxyStrategy, W as WapkRunConfig, b as PmProxyConfig, c as PmRestartPolicy, d as PmMemoryAction, e as WapkGoogleDriveConfig, f as PmConfig, g as PmAppConfig, E as ElitConfig } from './types-BayMVo_k.js';
2
- import './types-fiLday0L.js';
1
+ import { P as PmRuntimeName, a as PmProxyStrategy, W as WapkRunConfig, b as PmProxyConfig, c as PmRestartPolicy, d as PmMemoryAction, e as WapkGoogleDriveConfig, f as PmConfig, g as PmAppConfig, E as ElitConfig } from './types-CLGrLRTl.js';
2
+ import './types-CYEpzeEi.js';
3
3
  import './types-DPOgoGs-.js';
4
4
  import 'node:events';
5
5
  import './websocket-BLBEAnhp.js';
@@ -7,10 +7,10 @@ import 'events';
7
7
  import 'http';
8
8
  import 'ws';
9
9
  import './types-BR4wMiVx.js';
10
+ import './contracts-Av9yuqDM.js';
10
11
  import './types-C4gKykuG.js';
11
12
  import 'net';
12
13
  import 'smtp-server';
13
- import './contracts-D7KIS-TK.js';
14
14
  import './contracts-_0p1-15U.js';
15
15
 
16
16
  declare const DEFAULT_PM_DATA_DIR: string;