elit 3.6.8 → 3.6.9
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/Cargo.lock +1 -1
- package/Cargo.toml +1 -1
- package/dist/cli.cjs +328 -65
- package/dist/cli.mjs +310 -47
- package/dist/pm.cjs +309 -46
- package/dist/pm.js +309 -46
- package/dist/pm.mjs +309 -46
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -81569,6 +81569,217 @@ function watch2(paths, options) {
|
|
|
81569
81569
|
import { createServer, request as httpRequest } from "http";
|
|
81570
81570
|
import { request as httpsRequest } from "https";
|
|
81571
81571
|
import { createServer as createNetServer } from "net";
|
|
81572
|
+
import { lookup as dnsLookup } from "dns/promises";
|
|
81573
|
+
var BLOCKED_IPV4_PREFIXES = [
|
|
81574
|
+
"0.",
|
|
81575
|
+
"10.",
|
|
81576
|
+
"100.64.",
|
|
81577
|
+
"100.65.",
|
|
81578
|
+
"100.66.",
|
|
81579
|
+
"100.67.",
|
|
81580
|
+
"100.68.",
|
|
81581
|
+
"100.69.",
|
|
81582
|
+
"100.70.",
|
|
81583
|
+
"100.71.",
|
|
81584
|
+
"100.72.",
|
|
81585
|
+
"100.73.",
|
|
81586
|
+
"100.74.",
|
|
81587
|
+
"100.75.",
|
|
81588
|
+
"100.76.",
|
|
81589
|
+
"100.77.",
|
|
81590
|
+
"100.78.",
|
|
81591
|
+
"100.79.",
|
|
81592
|
+
"100.80.",
|
|
81593
|
+
"100.81.",
|
|
81594
|
+
"100.82.",
|
|
81595
|
+
"100.83.",
|
|
81596
|
+
"100.84.",
|
|
81597
|
+
"100.85.",
|
|
81598
|
+
"100.86.",
|
|
81599
|
+
"100.87.",
|
|
81600
|
+
"100.88.",
|
|
81601
|
+
"100.89.",
|
|
81602
|
+
"100.90.",
|
|
81603
|
+
"100.91.",
|
|
81604
|
+
"100.92.",
|
|
81605
|
+
"100.93.",
|
|
81606
|
+
"100.94.",
|
|
81607
|
+
"100.95.",
|
|
81608
|
+
"100.96.",
|
|
81609
|
+
"100.97.",
|
|
81610
|
+
"100.98.",
|
|
81611
|
+
"100.99.",
|
|
81612
|
+
"100.100.",
|
|
81613
|
+
"100.101.",
|
|
81614
|
+
"100.102.",
|
|
81615
|
+
"100.103.",
|
|
81616
|
+
"100.104.",
|
|
81617
|
+
"100.105.",
|
|
81618
|
+
"100.106.",
|
|
81619
|
+
"100.107.",
|
|
81620
|
+
"100.108.",
|
|
81621
|
+
"100.109.",
|
|
81622
|
+
"100.110.",
|
|
81623
|
+
"100.111.",
|
|
81624
|
+
"100.112.",
|
|
81625
|
+
"100.113.",
|
|
81626
|
+
"100.114.",
|
|
81627
|
+
"100.115.",
|
|
81628
|
+
"100.116.",
|
|
81629
|
+
"100.117.",
|
|
81630
|
+
"100.118.",
|
|
81631
|
+
"100.119.",
|
|
81632
|
+
"100.120.",
|
|
81633
|
+
"100.121.",
|
|
81634
|
+
"100.122.",
|
|
81635
|
+
"100.123.",
|
|
81636
|
+
"100.124.",
|
|
81637
|
+
"100.125.",
|
|
81638
|
+
"100.126.",
|
|
81639
|
+
"100.127.",
|
|
81640
|
+
"127.",
|
|
81641
|
+
"169.254.",
|
|
81642
|
+
"172.16.",
|
|
81643
|
+
"172.17.",
|
|
81644
|
+
"172.18.",
|
|
81645
|
+
"172.19.",
|
|
81646
|
+
"172.20.",
|
|
81647
|
+
"172.21.",
|
|
81648
|
+
"172.22.",
|
|
81649
|
+
"172.23.",
|
|
81650
|
+
"172.24.",
|
|
81651
|
+
"172.25.",
|
|
81652
|
+
"172.26.",
|
|
81653
|
+
"172.27.",
|
|
81654
|
+
"172.28.",
|
|
81655
|
+
"172.29.",
|
|
81656
|
+
"172.30.",
|
|
81657
|
+
"172.31.",
|
|
81658
|
+
"192.0.2.",
|
|
81659
|
+
"192.88.99.",
|
|
81660
|
+
"192.168.",
|
|
81661
|
+
"198.18.",
|
|
81662
|
+
"198.19.",
|
|
81663
|
+
"198.51.100.",
|
|
81664
|
+
"203.0.113.",
|
|
81665
|
+
"224.",
|
|
81666
|
+
"225.",
|
|
81667
|
+
"226.",
|
|
81668
|
+
"227.",
|
|
81669
|
+
"228.",
|
|
81670
|
+
"229.",
|
|
81671
|
+
"230.",
|
|
81672
|
+
"231.",
|
|
81673
|
+
"232.",
|
|
81674
|
+
"233.",
|
|
81675
|
+
"234.",
|
|
81676
|
+
"235.",
|
|
81677
|
+
"236.",
|
|
81678
|
+
"237.",
|
|
81679
|
+
"238.",
|
|
81680
|
+
"239.",
|
|
81681
|
+
"240.",
|
|
81682
|
+
"241.",
|
|
81683
|
+
"242.",
|
|
81684
|
+
"243.",
|
|
81685
|
+
"244.",
|
|
81686
|
+
"245.",
|
|
81687
|
+
"246.",
|
|
81688
|
+
"247.",
|
|
81689
|
+
"248.",
|
|
81690
|
+
"249.",
|
|
81691
|
+
"250.",
|
|
81692
|
+
"251.",
|
|
81693
|
+
"252.",
|
|
81694
|
+
"253.",
|
|
81695
|
+
"254.",
|
|
81696
|
+
"255."
|
|
81697
|
+
];
|
|
81698
|
+
var ALLOWED_PROXY_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
81699
|
+
function isBlockedIpv4(hostname) {
|
|
81700
|
+
const octets = hostname.split(".");
|
|
81701
|
+
if (octets.length !== 4) return false;
|
|
81702
|
+
const joined = hostname;
|
|
81703
|
+
return BLOCKED_IPV4_PREFIXES.some((prefix) => joined.startsWith(prefix));
|
|
81704
|
+
}
|
|
81705
|
+
function isBlockedIpv6(hostname) {
|
|
81706
|
+
const lower = hostname.toLowerCase();
|
|
81707
|
+
if (lower === "::1" || lower === "::" || lower === "0:0:0:0:0:0:0:1" || lower === "0:0:0:0:0:0:0:0") {
|
|
81708
|
+
return true;
|
|
81709
|
+
}
|
|
81710
|
+
const ffffMatch = lower.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/);
|
|
81711
|
+
if (ffffMatch) {
|
|
81712
|
+
return isBlockedIpv4(ffffMatch[1]);
|
|
81713
|
+
}
|
|
81714
|
+
const compatMatch = lower.match(/^::(\d+\.\d+\.\d+\.\d+)$/);
|
|
81715
|
+
if (compatMatch) {
|
|
81716
|
+
return isBlockedIpv4(compatMatch[1]);
|
|
81717
|
+
}
|
|
81718
|
+
return false;
|
|
81719
|
+
}
|
|
81720
|
+
function isSafeHostname(hostname) {
|
|
81721
|
+
if (!hostname) return false;
|
|
81722
|
+
if (/^\d{1,3}(\.\d{1,3}){3}$/.test(hostname)) return !isBlockedIpv4(hostname);
|
|
81723
|
+
if (/^\[.*\]$/.test(hostname)) return !isBlockedIpv6(hostname.slice(1, -1));
|
|
81724
|
+
if (hostname.includes(":")) return !isBlockedIpv6(hostname);
|
|
81725
|
+
return true;
|
|
81726
|
+
}
|
|
81727
|
+
async function safeResolveHostname(hostname) {
|
|
81728
|
+
try {
|
|
81729
|
+
const result2 = await dnsLookup(hostname);
|
|
81730
|
+
const ip = result2.address;
|
|
81731
|
+
if (isBlockedIpv4(ip) || isBlockedIpv6(ip)) {
|
|
81732
|
+
throw new Error(`PM proxy target resolved to a blocked address: ${ip}`);
|
|
81733
|
+
}
|
|
81734
|
+
return ip;
|
|
81735
|
+
} catch (error) {
|
|
81736
|
+
if (error instanceof Error && error.message.includes("blocked address")) {
|
|
81737
|
+
throw error;
|
|
81738
|
+
}
|
|
81739
|
+
throw new Error(`PM proxy failed to resolve target hostname "${hostname}": ${error instanceof Error ? error.message : String(error)}`);
|
|
81740
|
+
}
|
|
81741
|
+
}
|
|
81742
|
+
async function validateProxyTargetUrl(target) {
|
|
81743
|
+
if (!ALLOWED_PROXY_PROTOCOLS.has(target.protocol)) {
|
|
81744
|
+
throw new Error(`PM proxy target protocol "${target.protocol}" is not allowed. Only http: and https: are permitted.`);
|
|
81745
|
+
}
|
|
81746
|
+
const hostname = target.hostname;
|
|
81747
|
+
if (!isSafeHostname(hostname)) {
|
|
81748
|
+
throw new Error(`PM proxy target "${hostname}" resolves to a blocked address and is not allowed.`);
|
|
81749
|
+
}
|
|
81750
|
+
if (!/^\d{1,3}(\.\d{1,3}){3}$/.test(hostname) && !/^\[.*\]$/.test(hostname)) {
|
|
81751
|
+
await safeResolveHostname(hostname);
|
|
81752
|
+
}
|
|
81753
|
+
}
|
|
81754
|
+
function sanitizeProxyRequestPath(requestUrl) {
|
|
81755
|
+
if (!requestUrl || requestUrl === "/") return "/";
|
|
81756
|
+
try {
|
|
81757
|
+
const normalizedInput = requestUrl.replace(/\\/g, "/");
|
|
81758
|
+
const parsed = new URL(normalizedInput, "http://placeholder");
|
|
81759
|
+
if (parsed.username || parsed.password || parsed.hostname !== "placeholder" || parsed.port) {
|
|
81760
|
+
return "/";
|
|
81761
|
+
}
|
|
81762
|
+
const pathname = parsed.pathname || "/";
|
|
81763
|
+
let decodedPathname = pathname;
|
|
81764
|
+
try {
|
|
81765
|
+
decodedPathname = decodeURIComponent(pathname);
|
|
81766
|
+
} catch {
|
|
81767
|
+
return "/";
|
|
81768
|
+
}
|
|
81769
|
+
const lowerPath = pathname.toLowerCase();
|
|
81770
|
+
if (lowerPath.includes("%2f") || lowerPath.includes("%5c") || lowerPath.includes("%40") || lowerPath.includes("%00")) {
|
|
81771
|
+
return "/";
|
|
81772
|
+
}
|
|
81773
|
+
const segments = decodedPathname.split("/");
|
|
81774
|
+
if (segments.some((segment) => segment === "." || segment === "..")) {
|
|
81775
|
+
return "/";
|
|
81776
|
+
}
|
|
81777
|
+
const sanitized = pathname + parsed.search;
|
|
81778
|
+
return sanitized.startsWith("/") ? sanitized || "/" : `/${sanitized}`;
|
|
81779
|
+
} catch {
|
|
81780
|
+
return "/";
|
|
81781
|
+
}
|
|
81782
|
+
}
|
|
81572
81783
|
function resolvePmProxyHost(proxy) {
|
|
81573
81784
|
return proxy.host?.trim() || "0.0.0.0";
|
|
81574
81785
|
}
|
|
@@ -81658,6 +81869,9 @@ async function createPmProxyController(proxy) {
|
|
|
81658
81869
|
nextTargetIndex = (nextTargetIndex + 1) % targets.length;
|
|
81659
81870
|
return target;
|
|
81660
81871
|
};
|
|
81872
|
+
const validateTarget = async (target) => {
|
|
81873
|
+
await validateProxyTargetUrl(target);
|
|
81874
|
+
};
|
|
81661
81875
|
const server = createServer((req, res) => {
|
|
81662
81876
|
const target = pickTarget();
|
|
81663
81877
|
if (!target) {
|
|
@@ -81665,29 +81879,45 @@ async function createPmProxyController(proxy) {
|
|
|
81665
81879
|
res.end("PM proxy target is not ready.");
|
|
81666
81880
|
return;
|
|
81667
81881
|
}
|
|
81882
|
+
const sanitizedPath = sanitizeProxyRequestPath(req.url || "/");
|
|
81668
81883
|
const requestLib = target.protocol === "https:" ? httpsRequest : httpRequest;
|
|
81669
|
-
const targetUrl = new URL(req.url || "/", target);
|
|
81670
81884
|
const headers = buildPmProxyHeaders(req.headers, target.host);
|
|
81671
|
-
|
|
81672
|
-
|
|
81673
|
-
|
|
81674
|
-
|
|
81675
|
-
|
|
81676
|
-
|
|
81677
|
-
|
|
81678
|
-
|
|
81885
|
+
if (!ALLOWED_PROXY_PROTOCOLS.has(target.protocol)) {
|
|
81886
|
+
res.statusCode = 400;
|
|
81887
|
+
res.end("PM proxy rejected unsafe target protocol.");
|
|
81888
|
+
return;
|
|
81889
|
+
}
|
|
81890
|
+
validateTarget(target).then(() => {
|
|
81891
|
+
const proxyReq = requestLib({
|
|
81892
|
+
protocol: target.protocol,
|
|
81893
|
+
hostname: target.hostname,
|
|
81894
|
+
port: target.port || void 0,
|
|
81895
|
+
path: sanitizedPath,
|
|
81896
|
+
method: req.method,
|
|
81897
|
+
headers
|
|
81898
|
+
}, (proxyRes) => {
|
|
81899
|
+
const outgoingHeaders = {};
|
|
81900
|
+
for (const [key, value] of Object.entries(proxyRes.headers)) {
|
|
81901
|
+
if (value !== void 0) {
|
|
81902
|
+
outgoingHeaders[key] = value;
|
|
81903
|
+
}
|
|
81679
81904
|
}
|
|
81680
|
-
|
|
81681
|
-
|
|
81682
|
-
|
|
81683
|
-
|
|
81684
|
-
|
|
81905
|
+
res.writeHead(proxyRes.statusCode || 200, outgoingHeaders);
|
|
81906
|
+
proxyRes.pipe(res);
|
|
81907
|
+
});
|
|
81908
|
+
proxyReq.on("error", (error) => {
|
|
81909
|
+
if (!res.headersSent) {
|
|
81910
|
+
res.statusCode = 502;
|
|
81911
|
+
}
|
|
81912
|
+
res.end(`PM proxy error: ${error.message}`);
|
|
81913
|
+
});
|
|
81914
|
+
req.pipe(proxyReq);
|
|
81915
|
+
}).catch((error) => {
|
|
81685
81916
|
if (!res.headersSent) {
|
|
81686
|
-
res.statusCode =
|
|
81917
|
+
res.statusCode = 403;
|
|
81687
81918
|
}
|
|
81688
|
-
res.end(`PM proxy
|
|
81919
|
+
res.end(`PM proxy blocked target: ${error instanceof Error ? error.message : String(error)}`);
|
|
81689
81920
|
});
|
|
81690
|
-
req.pipe(proxyReq);
|
|
81691
81921
|
});
|
|
81692
81922
|
server.on("upgrade", (req, socket, head) => {
|
|
81693
81923
|
const target = pickTarget();
|
|
@@ -81699,38 +81929,56 @@ async function createPmProxyController(proxy) {
|
|
|
81699
81929
|
socket.destroy();
|
|
81700
81930
|
return;
|
|
81701
81931
|
}
|
|
81932
|
+
const sanitizedPath = sanitizeProxyRequestPath(req.url || "/");
|
|
81702
81933
|
const requestLib = target.protocol === "https:" ? httpsRequest : httpRequest;
|
|
81703
|
-
const targetUrl = new URL(
|
|
81704
|
-
|
|
81705
|
-
|
|
81706
|
-
|
|
81707
|
-
|
|
81708
|
-
|
|
81709
|
-
|
|
81710
|
-
|
|
81711
|
-
|
|
81712
|
-
|
|
81713
|
-
|
|
81714
|
-
|
|
81715
|
-
|
|
81716
|
-
|
|
81717
|
-
|
|
81718
|
-
|
|
81719
|
-
|
|
81720
|
-
|
|
81721
|
-
|
|
81722
|
-
|
|
81723
|
-
|
|
81724
|
-
|
|
81725
|
-
|
|
81726
|
-
|
|
81934
|
+
const targetUrl = new URL(sanitizedPath, target);
|
|
81935
|
+
if (targetUrl.hostname !== target.hostname || targetUrl.port !== target.port || !ALLOWED_PROXY_PROTOCOLS.has(targetUrl.protocol)) {
|
|
81936
|
+
writeRawHttpResponse(socket, 400, "Bad Request", {
|
|
81937
|
+
connection: "close",
|
|
81938
|
+
"content-length": 0
|
|
81939
|
+
});
|
|
81940
|
+
socket.destroy();
|
|
81941
|
+
return;
|
|
81942
|
+
}
|
|
81943
|
+
validateTarget(target).then(() => {
|
|
81944
|
+
const proxyReq = requestLib(targetUrl, {
|
|
81945
|
+
method: req.method,
|
|
81946
|
+
headers: buildPmProxyHeaders(req.headers, target.host)
|
|
81947
|
+
});
|
|
81948
|
+
proxyReq.on("upgrade", (proxyRes, proxySocket, proxyHead) => {
|
|
81949
|
+
writeRawHttpResponse(socket, proxyRes.statusCode || 101, proxyRes.statusMessage || "Switching Protocols", proxyRes.headers);
|
|
81950
|
+
if (head.length > 0) {
|
|
81951
|
+
proxySocket.write(head);
|
|
81952
|
+
}
|
|
81953
|
+
if (proxyHead.length > 0) {
|
|
81954
|
+
socket.write(proxyHead);
|
|
81955
|
+
}
|
|
81956
|
+
socket.on("error", () => proxySocket.destroy());
|
|
81957
|
+
proxySocket.on("error", () => socket.destroy());
|
|
81958
|
+
proxySocket.pipe(socket);
|
|
81959
|
+
socket.pipe(proxySocket);
|
|
81960
|
+
});
|
|
81961
|
+
proxyReq.on("response", (proxyRes) => {
|
|
81962
|
+
writeRawHttpResponse(socket, proxyRes.statusCode || 502, proxyRes.statusMessage || "Bad Gateway", proxyRes.headers);
|
|
81963
|
+
proxyRes.pipe(socket);
|
|
81964
|
+
});
|
|
81965
|
+
proxyReq.on("error", (error) => {
|
|
81966
|
+
writeRawHttpResponse(socket, 502, "Bad Gateway", {
|
|
81967
|
+
connection: "close",
|
|
81968
|
+
"content-type": "text/plain; charset=utf-8",
|
|
81969
|
+
"content-length": Buffer.byteLength(`PM proxy error: ${error.message}`)
|
|
81970
|
+
});
|
|
81971
|
+
socket.end(`PM proxy error: ${error.message}`);
|
|
81972
|
+
});
|
|
81973
|
+
proxyReq.end();
|
|
81974
|
+
}).catch((error) => {
|
|
81975
|
+
writeRawHttpResponse(socket, 403, "Forbidden", {
|
|
81727
81976
|
connection: "close",
|
|
81728
81977
|
"content-type": "text/plain; charset=utf-8",
|
|
81729
|
-
"content-length": Buffer.byteLength(`PM proxy
|
|
81978
|
+
"content-length": Buffer.byteLength(`PM proxy blocked target: ${error instanceof Error ? error.message : String(error)}`)
|
|
81730
81979
|
});
|
|
81731
|
-
socket.end(`PM proxy
|
|
81980
|
+
socket.end(`PM proxy blocked target: ${error instanceof Error ? error.message : String(error)}`);
|
|
81732
81981
|
});
|
|
81733
|
-
proxyReq.end();
|
|
81734
81982
|
});
|
|
81735
81983
|
await new Promise((resolve26, reject) => {
|
|
81736
81984
|
server.once("error", reject);
|
|
@@ -81738,10 +81986,25 @@ async function createPmProxyController(proxy) {
|
|
|
81738
81986
|
});
|
|
81739
81987
|
return {
|
|
81740
81988
|
setTarget(targetUrl) {
|
|
81741
|
-
|
|
81989
|
+
if (targetUrl) {
|
|
81990
|
+
const parsed = new URL(targetUrl);
|
|
81991
|
+
validateProxyTargetUrl(parsed).then(() => {
|
|
81992
|
+
setResolvedTargets([parsed]);
|
|
81993
|
+
}).catch((error) => {
|
|
81994
|
+
console.error(`[PM proxy] Blocked setTarget: ${error instanceof Error ? error.message : String(error)}`);
|
|
81995
|
+
setResolvedTargets([]);
|
|
81996
|
+
});
|
|
81997
|
+
} else {
|
|
81998
|
+
setResolvedTargets([]);
|
|
81999
|
+
}
|
|
81742
82000
|
},
|
|
81743
82001
|
setTargets(targetUrls) {
|
|
81744
|
-
|
|
82002
|
+
Promise.all(targetUrls.map((url) => validateProxyTargetUrl(new URL(url)))).then(() => {
|
|
82003
|
+
setResolvedTargets(targetUrls.map((targetUrl) => new URL(targetUrl)));
|
|
82004
|
+
}).catch((error) => {
|
|
82005
|
+
console.error(`[PM proxy] Blocked setTargets: ${error instanceof Error ? error.message : String(error)}`);
|
|
82006
|
+
setResolvedTargets([]);
|
|
82007
|
+
});
|
|
81745
82008
|
},
|
|
81746
82009
|
close() {
|
|
81747
82010
|
return new Promise((resolve26, reject) => {
|
|
@@ -86160,7 +86423,7 @@ function parsePreviewArgs(args) {
|
|
|
86160
86423
|
// package.json
|
|
86161
86424
|
var package_default = {
|
|
86162
86425
|
name: "elit",
|
|
86163
|
-
version: "3.6.
|
|
86426
|
+
version: "3.6.9",
|
|
86164
86427
|
description: "Optimized lightweight library for creating DOM elements with reactive state",
|
|
86165
86428
|
main: "dist/index.js",
|
|
86166
86429
|
module: "dist/index.mjs",
|