xypriss 2.3.4 → 2.3.6
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/cjs/src/index.js +2 -0
- package/dist/cjs/src/index.js.map +1 -1
- package/dist/cjs/src/server/FastServer.js +17 -0
- package/dist/cjs/src/server/FastServer.js.map +1 -1
- package/dist/cjs/src/server/core/HttpServer.js +70 -13
- package/dist/cjs/src/server/core/HttpServer.js.map +1 -1
- package/dist/cjs/src/server/core/XyprissApp.js +8 -0
- package/dist/cjs/src/server/core/XyprissApp.js.map +1 -1
- package/dist/cjs/src/server/utils/trustProxy.js +446 -0
- package/dist/cjs/src/server/utils/trustProxy.js.map +1 -0
- package/dist/esm/src/index.js +1 -0
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/server/FastServer.js +17 -0
- package/dist/esm/src/server/FastServer.js.map +1 -1
- package/dist/esm/src/server/core/HttpServer.js +70 -13
- package/dist/esm/src/server/core/HttpServer.js.map +1 -1
- package/dist/esm/src/server/core/XyprissApp.js +8 -0
- package/dist/esm/src/server/core/XyprissApp.js.map +1 -1
- package/dist/esm/src/server/utils/trustProxy.js +444 -0
- package/dist/esm/src/server/utils/trustProxy.js.map +1 -0
- package/dist/index.d.ts +144 -4
- package/package.json +1 -1
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
import { isIP } from 'net';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Advanced Trust Proxy Implementation for XyPriss
|
|
5
|
+
*
|
|
6
|
+
* Supports Express-like trust proxy configurations including:
|
|
7
|
+
* - Boolean values (true/false)
|
|
8
|
+
* - String values ('loopback', 'linklocal', 'uniquelocal')
|
|
9
|
+
* - CIDR notation ('192.168.0.0/16')
|
|
10
|
+
* - IP addresses ('127.0.0.1')
|
|
11
|
+
* - Arrays of the above
|
|
12
|
+
* - Custom functions
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Predefined network ranges
|
|
16
|
+
*/
|
|
17
|
+
const PREDEFINED_RANGES = {
|
|
18
|
+
loopback: ["127.0.0.0/8", "::1/128"],
|
|
19
|
+
linklocal: ["169.254.0.0/16", "fe80::/10"],
|
|
20
|
+
uniquelocal: ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "fc00::/7"],
|
|
21
|
+
};
|
|
22
|
+
class TrustProxy {
|
|
23
|
+
constructor(config) {
|
|
24
|
+
this.trustProxyFn = this.createTrustProxyFunction(config);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Validate and normalize IP address string
|
|
28
|
+
*/
|
|
29
|
+
normalizeIP(ip) {
|
|
30
|
+
if (!ip || typeof ip !== "string")
|
|
31
|
+
return null;
|
|
32
|
+
const trimmed = ip.trim();
|
|
33
|
+
if (!trimmed)
|
|
34
|
+
return null;
|
|
35
|
+
// Handle IPv4-mapped IPv6 addresses (::ffff:192.168.1.1)
|
|
36
|
+
if (trimmed.startsWith("::ffff:") && trimmed.includes(".")) {
|
|
37
|
+
const ipv4Part = trimmed.substring(7);
|
|
38
|
+
if (isIP(ipv4Part) === 4) {
|
|
39
|
+
return ipv4Part;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Validate it's a proper IP
|
|
43
|
+
const ipVersion = isIP(trimmed);
|
|
44
|
+
if (ipVersion === 0)
|
|
45
|
+
return null;
|
|
46
|
+
return trimmed;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Convert IPv4 address to number for comparison
|
|
50
|
+
*/
|
|
51
|
+
ipv4ToNumber(ip) {
|
|
52
|
+
try {
|
|
53
|
+
const parts = ip.split(".");
|
|
54
|
+
if (parts.length !== 4)
|
|
55
|
+
return null;
|
|
56
|
+
const nums = parts.map((p) => {
|
|
57
|
+
const num = parseInt(p, 10);
|
|
58
|
+
if (isNaN(num) || num < 0 || num > 255)
|
|
59
|
+
throw new Error("Invalid octet");
|
|
60
|
+
return num;
|
|
61
|
+
});
|
|
62
|
+
return (nums[0] << 24) + (nums[1] << 16) + (nums[2] << 8) + nums[3];
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Check if IPv4 address is in CIDR range
|
|
70
|
+
*/
|
|
71
|
+
isIPv4InCIDR(ip, cidr) {
|
|
72
|
+
try {
|
|
73
|
+
const parts = cidr.split("/");
|
|
74
|
+
if (parts.length !== 2)
|
|
75
|
+
return false;
|
|
76
|
+
const [network, prefixLength] = parts;
|
|
77
|
+
const prefixLen = parseInt(prefixLength, 10);
|
|
78
|
+
if (isNaN(prefixLen) || prefixLen < 0 || prefixLen > 32)
|
|
79
|
+
return false;
|
|
80
|
+
const ipNum = this.ipv4ToNumber(ip);
|
|
81
|
+
const networkNum = this.ipv4ToNumber(network);
|
|
82
|
+
if (ipNum === null || networkNum === null)
|
|
83
|
+
return false;
|
|
84
|
+
// Handle edge cases
|
|
85
|
+
if (prefixLen === 0)
|
|
86
|
+
return true; // 0.0.0.0/0 matches everything
|
|
87
|
+
if (prefixLen === 32)
|
|
88
|
+
return ipNum === networkNum; // Exact match
|
|
89
|
+
const mask = (0xffffffff << (32 - prefixLen)) >>> 0;
|
|
90
|
+
return (ipNum & mask) === (networkNum & mask);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Expand IPv6 address to full form
|
|
98
|
+
*/
|
|
99
|
+
expandIPv6(ip) {
|
|
100
|
+
try {
|
|
101
|
+
if (!ip.includes(":"))
|
|
102
|
+
return null;
|
|
103
|
+
// Handle :: compression
|
|
104
|
+
if (ip.includes("::")) {
|
|
105
|
+
const parts = ip.split("::");
|
|
106
|
+
if (parts.length > 2)
|
|
107
|
+
return null; // Invalid: multiple ::
|
|
108
|
+
const left = parts[0] ? parts[0].split(":") : [];
|
|
109
|
+
const right = parts[1] ? parts[1].split(":") : [];
|
|
110
|
+
const missing = 8 - left.length - right.length;
|
|
111
|
+
if (missing < 0)
|
|
112
|
+
return null; // Too many parts
|
|
113
|
+
const middle = Array(missing).fill("0000");
|
|
114
|
+
const allParts = [...left, ...middle, ...right];
|
|
115
|
+
// Pad each part to 4 hex digits
|
|
116
|
+
return allParts.map((p) => p.padStart(4, "0")).join(":");
|
|
117
|
+
}
|
|
118
|
+
// No compression
|
|
119
|
+
const parts = ip.split(":");
|
|
120
|
+
if (parts.length !== 8)
|
|
121
|
+
return null;
|
|
122
|
+
return parts.map((p) => p.padStart(4, "0")).join(":");
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Convert IPv6 address to BigInt for comparison
|
|
130
|
+
*/
|
|
131
|
+
ipv6ToBigInt(ip) {
|
|
132
|
+
try {
|
|
133
|
+
const expanded = this.expandIPv6(ip);
|
|
134
|
+
if (!expanded)
|
|
135
|
+
return null;
|
|
136
|
+
const parts = expanded.split(":");
|
|
137
|
+
if (parts.length !== 8)
|
|
138
|
+
return null;
|
|
139
|
+
let result = 0n;
|
|
140
|
+
for (let i = 0; i < 8; i++) {
|
|
141
|
+
const val = parseInt(parts[i], 16);
|
|
142
|
+
if (isNaN(val) || val < 0 || val > 0xffff)
|
|
143
|
+
return null;
|
|
144
|
+
result = (result << 16n) + BigInt(val);
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Check if IPv6 address is in CIDR range
|
|
154
|
+
*/
|
|
155
|
+
isIPv6InCIDR(ip, cidr) {
|
|
156
|
+
try {
|
|
157
|
+
const parts = cidr.split("/");
|
|
158
|
+
if (parts.length !== 2)
|
|
159
|
+
return false;
|
|
160
|
+
const [network, prefixLength] = parts;
|
|
161
|
+
const prefixLen = parseInt(prefixLength, 10);
|
|
162
|
+
if (isNaN(prefixLen) || prefixLen < 0 || prefixLen > 128)
|
|
163
|
+
return false;
|
|
164
|
+
const ipNum = this.ipv6ToBigInt(ip);
|
|
165
|
+
const networkNum = this.ipv6ToBigInt(network);
|
|
166
|
+
if (ipNum === null || networkNum === null)
|
|
167
|
+
return false;
|
|
168
|
+
// Handle edge cases
|
|
169
|
+
if (prefixLen === 0)
|
|
170
|
+
return true; // ::/0 matches everything
|
|
171
|
+
if (prefixLen === 128)
|
|
172
|
+
return ipNum === networkNum; // Exact match
|
|
173
|
+
const mask = (BigInt(2) ** BigInt(128) - BigInt(1)) <<
|
|
174
|
+
BigInt(128 - prefixLen);
|
|
175
|
+
return (ipNum & mask) === (networkNum & mask);
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Check if IP address is in CIDR range
|
|
183
|
+
*/
|
|
184
|
+
isIPInCIDR(ip, cidr) {
|
|
185
|
+
if (!ip || !cidr)
|
|
186
|
+
return false;
|
|
187
|
+
const ipVersion = isIP(ip);
|
|
188
|
+
if (ipVersion === 0)
|
|
189
|
+
return false;
|
|
190
|
+
// Determine CIDR type
|
|
191
|
+
const isCIDRv4 = cidr.includes(".") && cidr.includes("/");
|
|
192
|
+
const isCIDRv6 = cidr.includes(":") && cidr.includes("/");
|
|
193
|
+
if (ipVersion === 4 && isCIDRv4) {
|
|
194
|
+
return this.isIPv4InCIDR(ip, cidr);
|
|
195
|
+
}
|
|
196
|
+
else if (ipVersion === 6 && isCIDRv6) {
|
|
197
|
+
return this.isIPv6InCIDR(ip, cidr);
|
|
198
|
+
}
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Check if IP matches a single trust proxy rule
|
|
203
|
+
*/
|
|
204
|
+
matchesTrustRule(ip, rule) {
|
|
205
|
+
if (!ip || !rule)
|
|
206
|
+
return false;
|
|
207
|
+
try {
|
|
208
|
+
// Handle predefined ranges
|
|
209
|
+
if (rule in PREDEFINED_RANGES) {
|
|
210
|
+
const ranges = PREDEFINED_RANGES[rule];
|
|
211
|
+
return ranges.some((range) => this.isIPInCIDR(ip, range));
|
|
212
|
+
}
|
|
213
|
+
// Handle CIDR notation
|
|
214
|
+
if (rule.includes("/")) {
|
|
215
|
+
return this.isIPInCIDR(ip, rule);
|
|
216
|
+
}
|
|
217
|
+
// Handle exact IP match (normalize both for comparison)
|
|
218
|
+
const normalizedIP = this.normalizeIP(ip);
|
|
219
|
+
const normalizedRule = this.normalizeIP(rule);
|
|
220
|
+
if (!normalizedIP || !normalizedRule)
|
|
221
|
+
return false;
|
|
222
|
+
return normalizedIP === normalizedRule;
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Create a trust proxy function from configuration
|
|
230
|
+
*/
|
|
231
|
+
createTrustProxyFunction(config) {
|
|
232
|
+
// Handle boolean values
|
|
233
|
+
if (typeof config === "boolean") {
|
|
234
|
+
return () => config;
|
|
235
|
+
}
|
|
236
|
+
// Handle number values (trust first N hops)
|
|
237
|
+
if (typeof config === "number") {
|
|
238
|
+
if (!Number.isInteger(config) || config < 0) {
|
|
239
|
+
throw new Error("Trust proxy number must be a non-negative integer");
|
|
240
|
+
}
|
|
241
|
+
return (_ip, hopIndex) => hopIndex < config;
|
|
242
|
+
}
|
|
243
|
+
// Handle function values
|
|
244
|
+
if (typeof config === "function") {
|
|
245
|
+
return (ip, hopIndex) => {
|
|
246
|
+
try {
|
|
247
|
+
return Boolean(config(ip, hopIndex));
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
return false; // Safe default on function error
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
// Handle string values
|
|
255
|
+
if (typeof config === "string") {
|
|
256
|
+
const trimmed = config.trim();
|
|
257
|
+
if (!trimmed)
|
|
258
|
+
return () => false;
|
|
259
|
+
return (ip) => this.matchesTrustRule(ip, trimmed);
|
|
260
|
+
}
|
|
261
|
+
// Handle array values
|
|
262
|
+
if (Array.isArray(config)) {
|
|
263
|
+
const validRules = config.filter((rule) => typeof rule === "string" && rule.trim());
|
|
264
|
+
if (validRules.length === 0)
|
|
265
|
+
return () => false;
|
|
266
|
+
return (ip) => validRules.some((rule) => this.matchesTrustRule(ip, rule));
|
|
267
|
+
}
|
|
268
|
+
// Default: don't trust
|
|
269
|
+
return () => false;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Safely parse X-Forwarded-For header
|
|
273
|
+
*/
|
|
274
|
+
parseForwardedFor(header) {
|
|
275
|
+
if (!header)
|
|
276
|
+
return [];
|
|
277
|
+
// Handle array form (shouldn't happen but be defensive)
|
|
278
|
+
const headerStr = Array.isArray(header) ? header.join(",") : header;
|
|
279
|
+
if (typeof headerStr !== "string")
|
|
280
|
+
return [];
|
|
281
|
+
return headerStr
|
|
282
|
+
.split(",")
|
|
283
|
+
.map((ip) => this.normalizeIP(ip))
|
|
284
|
+
.filter((ip) => ip !== null);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Get remote address with fallback
|
|
288
|
+
*/
|
|
289
|
+
getRemoteAddress(req) {
|
|
290
|
+
const remoteAddr = req.socket?.remoteAddress;
|
|
291
|
+
if (!remoteAddr)
|
|
292
|
+
return "127.0.0.1";
|
|
293
|
+
const normalized = this.normalizeIP(remoteAddr);
|
|
294
|
+
return normalized || "127.0.0.1";
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Extract client IP considering trust proxy configuration
|
|
298
|
+
*/
|
|
299
|
+
extractClientIP(req) {
|
|
300
|
+
try {
|
|
301
|
+
const forwardedFor = req.headers["x-forwarded-for"];
|
|
302
|
+
const ips = this.parseForwardedFor(forwardedFor);
|
|
303
|
+
if (ips.length === 0) {
|
|
304
|
+
// No forwarded headers, return direct connection IP
|
|
305
|
+
return this.getRemoteAddress(req);
|
|
306
|
+
}
|
|
307
|
+
// Start from the rightmost IP (closest to server) and work backwards
|
|
308
|
+
const directIP = this.getRemoteAddress(req);
|
|
309
|
+
let trustedIP = directIP;
|
|
310
|
+
// Process IPs from right to left (closest to server first)
|
|
311
|
+
for (let i = ips.length - 1; i >= 0; i--) {
|
|
312
|
+
const hopIndex = ips.length - 1 - i;
|
|
313
|
+
const currentIP = ips[i];
|
|
314
|
+
// Check if we trust this hop
|
|
315
|
+
if (this.trustProxyFn(trustedIP, hopIndex)) {
|
|
316
|
+
trustedIP = currentIP;
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
// Stop at first untrusted hop
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return trustedIP;
|
|
324
|
+
}
|
|
325
|
+
catch {
|
|
326
|
+
// On any error, return the direct connection IP as safe default
|
|
327
|
+
return this.getRemoteAddress(req);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Extract all IPs in the proxy chain
|
|
332
|
+
*/
|
|
333
|
+
extractProxyChain(req) {
|
|
334
|
+
try {
|
|
335
|
+
const forwardedFor = req.headers["x-forwarded-for"];
|
|
336
|
+
const ips = this.parseForwardedFor(forwardedFor);
|
|
337
|
+
const directIP = this.getRemoteAddress(req);
|
|
338
|
+
if (ips.length === 0) {
|
|
339
|
+
return [directIP];
|
|
340
|
+
}
|
|
341
|
+
const trustedIPs = [directIP];
|
|
342
|
+
// Process IPs from right to left
|
|
343
|
+
for (let i = ips.length - 1; i >= 0; i--) {
|
|
344
|
+
const hopIndex = ips.length - 1 - i;
|
|
345
|
+
const currentIP = ips[i];
|
|
346
|
+
const previousIP = trustedIPs[trustedIPs.length - 1];
|
|
347
|
+
if (this.trustProxyFn(previousIP, hopIndex)) {
|
|
348
|
+
trustedIPs.push(currentIP);
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return trustedIPs.reverse(); // Return in client -> server order
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
return [this.getRemoteAddress(req)];
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Determine if connection is secure based on trust proxy
|
|
362
|
+
*/
|
|
363
|
+
isSecureConnection(req) {
|
|
364
|
+
try {
|
|
365
|
+
// Check if we have a direct TLS connection
|
|
366
|
+
const socket = req.socket;
|
|
367
|
+
if (socket?.encrypted === true) {
|
|
368
|
+
return true;
|
|
369
|
+
}
|
|
370
|
+
// Check X-Forwarded-Proto header if we trust the proxy
|
|
371
|
+
const forwardedProto = req.headers["x-forwarded-proto"];
|
|
372
|
+
if (!forwardedProto)
|
|
373
|
+
return false;
|
|
374
|
+
const directIP = this.getRemoteAddress(req);
|
|
375
|
+
if (!this.trustProxyFn(directIP, 0))
|
|
376
|
+
return false;
|
|
377
|
+
// Handle both string and array forms
|
|
378
|
+
const protoStr = Array.isArray(forwardedProto)
|
|
379
|
+
? forwardedProto[0]
|
|
380
|
+
: forwardedProto;
|
|
381
|
+
if (typeof protoStr !== "string")
|
|
382
|
+
return false;
|
|
383
|
+
// Take first value if comma-separated
|
|
384
|
+
const proto = protoStr.split(",")[0].trim().toLowerCase();
|
|
385
|
+
return proto === "https";
|
|
386
|
+
}
|
|
387
|
+
catch {
|
|
388
|
+
return false;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Get protocol considering trust proxy
|
|
393
|
+
*/
|
|
394
|
+
getProtocol(req) {
|
|
395
|
+
return this.isSecureConnection(req) ? "https" : "http";
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Get hostname considering trust proxy
|
|
399
|
+
*/
|
|
400
|
+
getHostname(req) {
|
|
401
|
+
try {
|
|
402
|
+
const directIP = this.getRemoteAddress(req);
|
|
403
|
+
// Check X-Forwarded-Host if we trust the proxy
|
|
404
|
+
const forwardedHost = req.headers["x-forwarded-host"];
|
|
405
|
+
if (forwardedHost && this.trustProxyFn(directIP, 0)) {
|
|
406
|
+
const hostStr = Array.isArray(forwardedHost)
|
|
407
|
+
? forwardedHost[0]
|
|
408
|
+
: forwardedHost;
|
|
409
|
+
if (typeof hostStr === "string" && hostStr.trim()) {
|
|
410
|
+
// Take first host if comma-separated, remove port
|
|
411
|
+
const hostname = hostStr.split(",")[0].trim().split(":")[0];
|
|
412
|
+
if (hostname)
|
|
413
|
+
return hostname;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
// Fallback to Host header
|
|
417
|
+
const host = req.headers.host;
|
|
418
|
+
if (host && typeof host === "string") {
|
|
419
|
+
const hostname = host.split(":")[0];
|
|
420
|
+
if (hostname)
|
|
421
|
+
return hostname;
|
|
422
|
+
}
|
|
423
|
+
return "localhost";
|
|
424
|
+
}
|
|
425
|
+
catch {
|
|
426
|
+
return "localhost";
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Validate trust proxy configuration
|
|
431
|
+
*/
|
|
432
|
+
static validate(config) {
|
|
433
|
+
try {
|
|
434
|
+
new TrustProxy(config);
|
|
435
|
+
return true;
|
|
436
|
+
}
|
|
437
|
+
catch {
|
|
438
|
+
return false;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
export { TrustProxy };
|
|
444
|
+
//# sourceMappingURL=trustProxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trustProxy.js","sources":["../../../../../src/server/utils/trustProxy.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -94,6 +94,56 @@ type NextFunction = (error?: any) => void;
|
|
|
94
94
|
*/
|
|
95
95
|
type RouteHandler$1 = (req: XyPrisRequest, res: XyPrisResponse, next?: NextFunction) => void | Promise<void>;
|
|
96
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Trust Proxy Type Definitions for XyPriss
|
|
99
|
+
*
|
|
100
|
+
* Comprehensive type definitions for the advanced trust proxy functionality
|
|
101
|
+
*/
|
|
102
|
+
/**
|
|
103
|
+
* Predefined network range identifiers
|
|
104
|
+
*/
|
|
105
|
+
type PredefinedRange = 'loopback' | 'linklocal' | 'uniquelocal';
|
|
106
|
+
/**
|
|
107
|
+
* Trust proxy configuration value
|
|
108
|
+
*
|
|
109
|
+
* Supports all Express.js trust proxy configurations plus XyPriss enhancements:
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* // Boolean - trust all proxies or none
|
|
114
|
+
* trustProxy: true
|
|
115
|
+
* trustProxy: false
|
|
116
|
+
*
|
|
117
|
+
* // Predefined ranges
|
|
118
|
+
* trustProxy: 'loopback' // Trust localhost/127.0.0.1 and ::1
|
|
119
|
+
* trustProxy: 'linklocal' // Trust link-local addresses (169.254.0.0/16, fe80::/10)
|
|
120
|
+
* trustProxy: 'uniquelocal' // Trust private networks (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7)
|
|
121
|
+
*
|
|
122
|
+
* // CIDR notation
|
|
123
|
+
* trustProxy: '192.168.0.0/16'
|
|
124
|
+
* trustProxy: '10.0.0.0/8'
|
|
125
|
+
* trustProxy: 'fc00::/7' // IPv6 CIDR
|
|
126
|
+
*
|
|
127
|
+
* // Exact IP addresses
|
|
128
|
+
* trustProxy: '127.0.0.1'
|
|
129
|
+
* trustProxy: '::1'
|
|
130
|
+
*
|
|
131
|
+
* // Array of rules (mixed types supported)
|
|
132
|
+
* trustProxy: ['loopback', 'linklocal', '10.0.0.0/8']
|
|
133
|
+
* trustProxy: ['127.0.0.1', '192.168.1.100', 'uniquelocal']
|
|
134
|
+
*
|
|
135
|
+
* // Number - trust first N hops
|
|
136
|
+
* trustProxy: 1 // Trust first proxy
|
|
137
|
+
* trustProxy: 2 // Trust first 2 proxies in chain
|
|
138
|
+
*
|
|
139
|
+
* // Custom function
|
|
140
|
+
* trustProxy: (ip, hopIndex) => {
|
|
141
|
+
* return ip.startsWith('192.168.') || ip === '127.0.0.1';
|
|
142
|
+
* }
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
type TrustProxyValue$1 = boolean | PredefinedRange | string | (PredefinedRange | string)[] | number | ((ip: string, hopIndex: number) => boolean);
|
|
146
|
+
|
|
97
147
|
interface CacheStats {
|
|
98
148
|
hits: number;
|
|
99
149
|
misses: number;
|
|
@@ -4489,6 +4539,10 @@ declare class XyPrissServer {
|
|
|
4489
4539
|
* Add safe JSON middleware to handle circular references
|
|
4490
4540
|
*/
|
|
4491
4541
|
private addSafeJsonMiddleware;
|
|
4542
|
+
/**
|
|
4543
|
+
* Configure trust proxy settings based on server options
|
|
4544
|
+
*/
|
|
4545
|
+
private configureTrustProxy;
|
|
4492
4546
|
/**
|
|
4493
4547
|
* Initialize request management middleware for timeouts, network quality, and concurrency control
|
|
4494
4548
|
*/
|
|
@@ -5218,7 +5272,7 @@ interface MultiServerConfig {
|
|
|
5218
5272
|
/** Server-specific overrides */
|
|
5219
5273
|
server?: {
|
|
5220
5274
|
host?: string;
|
|
5221
|
-
trustProxy?:
|
|
5275
|
+
trustProxy?: TrustProxyValue$1;
|
|
5222
5276
|
jsonLimit?: string;
|
|
5223
5277
|
urlEncodedLimit?: string;
|
|
5224
5278
|
enableMiddleware?: boolean;
|
|
@@ -5458,7 +5512,7 @@ interface ServerOptions {
|
|
|
5458
5512
|
server?: {
|
|
5459
5513
|
port?: number;
|
|
5460
5514
|
host?: string;
|
|
5461
|
-
trustProxy?:
|
|
5515
|
+
trustProxy?: TrustProxyValue$1;
|
|
5462
5516
|
jsonLimit?: string;
|
|
5463
5517
|
urlEncodedLimit?: string;
|
|
5464
5518
|
enableMiddleware?: boolean;
|
|
@@ -11831,6 +11885,92 @@ declare class PluginDevelopmentHelpers {
|
|
|
11831
11885
|
*/
|
|
11832
11886
|
declare function quickServer(port?: number): UltraFastApp;
|
|
11833
11887
|
|
|
11888
|
+
/**
|
|
11889
|
+
* Advanced Trust Proxy Implementation for XyPriss
|
|
11890
|
+
*
|
|
11891
|
+
* Supports Express-like trust proxy configurations including:
|
|
11892
|
+
* - Boolean values (true/false)
|
|
11893
|
+
* - String values ('loopback', 'linklocal', 'uniquelocal')
|
|
11894
|
+
* - CIDR notation ('192.168.0.0/16')
|
|
11895
|
+
* - IP addresses ('127.0.0.1')
|
|
11896
|
+
* - Arrays of the above
|
|
11897
|
+
* - Custom functions
|
|
11898
|
+
*/
|
|
11899
|
+
|
|
11900
|
+
type TrustProxyValue = boolean | string | string[] | number | ((ip: string, hopIndex: number) => boolean);
|
|
11901
|
+
declare class TrustProxy {
|
|
11902
|
+
private trustProxyFn;
|
|
11903
|
+
constructor(config: TrustProxyValue);
|
|
11904
|
+
/**
|
|
11905
|
+
* Validate and normalize IP address string
|
|
11906
|
+
*/
|
|
11907
|
+
private normalizeIP;
|
|
11908
|
+
/**
|
|
11909
|
+
* Convert IPv4 address to number for comparison
|
|
11910
|
+
*/
|
|
11911
|
+
private ipv4ToNumber;
|
|
11912
|
+
/**
|
|
11913
|
+
* Check if IPv4 address is in CIDR range
|
|
11914
|
+
*/
|
|
11915
|
+
private isIPv4InCIDR;
|
|
11916
|
+
/**
|
|
11917
|
+
* Expand IPv6 address to full form
|
|
11918
|
+
*/
|
|
11919
|
+
private expandIPv6;
|
|
11920
|
+
/**
|
|
11921
|
+
* Convert IPv6 address to BigInt for comparison
|
|
11922
|
+
*/
|
|
11923
|
+
private ipv6ToBigInt;
|
|
11924
|
+
/**
|
|
11925
|
+
* Check if IPv6 address is in CIDR range
|
|
11926
|
+
*/
|
|
11927
|
+
private isIPv6InCIDR;
|
|
11928
|
+
/**
|
|
11929
|
+
* Check if IP address is in CIDR range
|
|
11930
|
+
*/
|
|
11931
|
+
private isIPInCIDR;
|
|
11932
|
+
/**
|
|
11933
|
+
* Check if IP matches a single trust proxy rule
|
|
11934
|
+
*/
|
|
11935
|
+
private matchesTrustRule;
|
|
11936
|
+
/**
|
|
11937
|
+
* Create a trust proxy function from configuration
|
|
11938
|
+
*/
|
|
11939
|
+
private createTrustProxyFunction;
|
|
11940
|
+
/**
|
|
11941
|
+
* Safely parse X-Forwarded-For header
|
|
11942
|
+
*/
|
|
11943
|
+
private parseForwardedFor;
|
|
11944
|
+
/**
|
|
11945
|
+
* Get remote address with fallback
|
|
11946
|
+
*/
|
|
11947
|
+
private getRemoteAddress;
|
|
11948
|
+
/**
|
|
11949
|
+
* Extract client IP considering trust proxy configuration
|
|
11950
|
+
*/
|
|
11951
|
+
extractClientIP(req: IncomingMessage): string;
|
|
11952
|
+
/**
|
|
11953
|
+
* Extract all IPs in the proxy chain
|
|
11954
|
+
*/
|
|
11955
|
+
extractProxyChain(req: IncomingMessage): string[];
|
|
11956
|
+
/**
|
|
11957
|
+
* Determine if connection is secure based on trust proxy
|
|
11958
|
+
*/
|
|
11959
|
+
isSecureConnection(req: IncomingMessage): boolean;
|
|
11960
|
+
/**
|
|
11961
|
+
* Get protocol considering trust proxy
|
|
11962
|
+
*/
|
|
11963
|
+
getProtocol(req: IncomingMessage): string;
|
|
11964
|
+
/**
|
|
11965
|
+
* Get hostname considering trust proxy
|
|
11966
|
+
*/
|
|
11967
|
+
getHostname(req: IncomingMessage): string;
|
|
11968
|
+
/**
|
|
11969
|
+
* Validate trust proxy configuration
|
|
11970
|
+
*/
|
|
11971
|
+
static validate(config: TrustProxyValue): boolean;
|
|
11972
|
+
}
|
|
11973
|
+
|
|
11834
11974
|
/***************************************************************************
|
|
11835
11975
|
* XyPrissJS - Advanced JavaScript Security Library
|
|
11836
11976
|
*
|
|
@@ -11863,5 +12003,5 @@ declare function quickServer(port?: number): UltraFastApp;
|
|
|
11863
12003
|
*/
|
|
11864
12004
|
declare function Router(): XyPrissRouter;
|
|
11865
12005
|
|
|
11866
|
-
export { CachePlugin as CachePluginBase, CompressionPlugin, ConnectionPlugin, DEFAULT_PLUGIN_CONFIG, FileUploadAPI as FLA, FileUploadAPI, JWTAuthPlugin, NetworkCategory, NetworkPlugin, NetworkPluginFactory, NetworkPluginUtils, PERFORMANCE_TARGETS, PLUGIN_SYSTEM_NAME, PLUGIN_SYSTEM_VERSION, PerformanceMonitor, PerformancePlugin as PerformancePluginBase, PluginDevelopmentHelpers, PluginEngine, PluginEventType, PluginPriority, PluginRegistry, PluginSystemFactory, PluginSystemUtils, PluginType, ProxyPlugin, RateLimitPlugin, ResponseTimePlugin, Route, Router, SecurityMiddleware, SecurityPlugin as SecurityPluginBase, SmartCachePlugin, XyPrissRouter, createCacheMiddleware, createCircularRefDebugger, createOptimalCache, createSafeJsonMiddleware, createServer, createServerInstance, expressStringify, fastStringify, initializeFileUpload, quickServer, safeJsonStringify, safeStringify, sendSafeJson, setupSafeJson, uploadAny, uploadArray, uploadFields, uploadSingle };
|
|
11867
|
-
export type { BasePlugin, CacheConfig, CachePlugin$1 as CachePlugin, CompressionAlgorithm, CompressionConfig, ConnectionConfig, FailoverConfig, HTTPCacheConfig, HealthCheckConfig, CachePlugin$1 as ICachePlugin, PerformancePlugin$1 as IPerformancePlugin, SecurityPlugin$1 as ISecurityPlugin, LoadBalancingStrategy, MultiServerApp, MultiServerConfig, NativePlugin, NetworkExecutionContext, NetworkExecutionResult, NetworkHealthStatus, NetworkPluginConfig, NetworkSecurityConfig, NextFunction, PerformanceConfig, PerformanceMetrics, PerformancePlugin$1 as PerformancePlugin, PluginConfiguration, PluginEvent, PluginExecutionContext, PluginExecutionResult, PluginExecutionStats, PluginInitializationContext, PluginRegistryConfig, ProxyConfig, RateLimitConfig, RateLimitRule, RateLimitStrategy, RedisConfig, XyPrisRequest as Request, RequestHandler, XyPrisResponse as Response, RouteConfig, RouteOptions, SecurityConfig, SecurityPlugin$1 as SecurityPlugin, ServerOptions, SmartRouteConfig, UltraFastApp, UpstreamServer, WebSocketConfig, MultiServerApp as XyPMS, XyPrisRequest as XyPrissRequest, XyPrisResponse as XyPrissResponse };
|
|
12006
|
+
export { CachePlugin as CachePluginBase, CompressionPlugin, ConnectionPlugin, DEFAULT_PLUGIN_CONFIG, FileUploadAPI as FLA, FileUploadAPI, JWTAuthPlugin, NetworkCategory, NetworkPlugin, NetworkPluginFactory, NetworkPluginUtils, PERFORMANCE_TARGETS, PLUGIN_SYSTEM_NAME, PLUGIN_SYSTEM_VERSION, PerformanceMonitor, PerformancePlugin as PerformancePluginBase, PluginDevelopmentHelpers, PluginEngine, PluginEventType, PluginPriority, PluginRegistry, PluginSystemFactory, PluginSystemUtils, PluginType, ProxyPlugin, RateLimitPlugin, ResponseTimePlugin, Route, Router, SecurityMiddleware, SecurityPlugin as SecurityPluginBase, SmartCachePlugin, TrustProxy, XyPrissRouter, createCacheMiddleware, createCircularRefDebugger, createOptimalCache, createSafeJsonMiddleware, createServer, createServerInstance, expressStringify, fastStringify, initializeFileUpload, quickServer, safeJsonStringify, safeStringify, sendSafeJson, setupSafeJson, uploadAny, uploadArray, uploadFields, uploadSingle };
|
|
12007
|
+
export type { BasePlugin, CacheConfig, CachePlugin$1 as CachePlugin, CompressionAlgorithm, CompressionConfig, ConnectionConfig, FailoverConfig, HTTPCacheConfig, HealthCheckConfig, CachePlugin$1 as ICachePlugin, PerformancePlugin$1 as IPerformancePlugin, SecurityPlugin$1 as ISecurityPlugin, LoadBalancingStrategy, MultiServerApp, MultiServerConfig, NativePlugin, NetworkExecutionContext, NetworkExecutionResult, NetworkHealthStatus, NetworkPluginConfig, NetworkSecurityConfig, NextFunction, PerformanceConfig, PerformanceMetrics, PerformancePlugin$1 as PerformancePlugin, PluginConfiguration, PluginEvent, PluginExecutionContext, PluginExecutionResult, PluginExecutionStats, PluginInitializationContext, PluginRegistryConfig, ProxyConfig, RateLimitConfig, RateLimitRule, RateLimitStrategy, RedisConfig, XyPrisRequest as Request, RequestHandler, XyPrisResponse as Response, RouteConfig, RouteOptions, SecurityConfig, SecurityPlugin$1 as SecurityPlugin, ServerOptions, SmartRouteConfig, TrustProxyValue$1 as TrustProxyValue, UltraFastApp, UpstreamServer, WebSocketConfig, MultiServerApp as XyPMS, XyPrisRequest as XyPrissRequest, XyPrisResponse as XyPrissResponse };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xypriss",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.6",
|
|
4
4
|
"description": "XyPriss is a lightweight, TypeScript-first, open-source Node.js web framework crafted for developers seeking a familiar Express-like API without Express dependencies. It features built-in security middleware, a robust routing system, and performance optimizations to build scalable, secure web applications effortlessly. Join our community and contribute on GitHub!",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|