@arcis/node 1.2.0 → 1.4.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 (122) hide show
  1. package/dist/core/{index.d.mts → constants.d.ts} +21 -70
  2. package/dist/core/constants.d.ts.map +1 -0
  3. package/dist/core/errors.d.ts +53 -0
  4. package/dist/core/errors.d.ts.map +1 -0
  5. package/dist/core/index.d.ts +6 -168
  6. package/dist/core/index.d.ts.map +1 -0
  7. package/dist/{types-CsOFHoD9.d.mts → core/types.d.ts} +38 -31
  8. package/dist/core/types.d.ts.map +1 -0
  9. package/dist/index.d.ts +71 -166
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +151 -4
  12. package/dist/index.js.map +1 -1
  13. package/dist/index.mjs +145 -5
  14. package/dist/index.mjs.map +1 -1
  15. package/dist/logging/index.d.ts +4 -36
  16. package/dist/logging/index.d.ts.map +1 -0
  17. package/dist/logging/{index.d.mts → redactor.d.ts} +5 -9
  18. package/dist/logging/redactor.d.ts.map +1 -0
  19. package/dist/middleware/bot-detection.d.ts +86 -0
  20. package/dist/middleware/bot-detection.d.ts.map +1 -0
  21. package/dist/middleware/cookies.d.ts +48 -0
  22. package/dist/middleware/cookies.d.ts.map +1 -0
  23. package/dist/middleware/cors.d.ts +65 -0
  24. package/dist/middleware/cors.d.ts.map +1 -0
  25. package/dist/middleware/csrf.d.ts +109 -0
  26. package/dist/middleware/csrf.d.ts.map +1 -0
  27. package/dist/middleware/error-handler.d.ts +43 -0
  28. package/dist/middleware/error-handler.d.ts.map +1 -0
  29. package/dist/middleware/headers.d.ts +29 -0
  30. package/dist/middleware/headers.d.ts.map +1 -0
  31. package/dist/middleware/hpp.d.ts +56 -0
  32. package/dist/middleware/hpp.d.ts.map +1 -0
  33. package/dist/middleware/index.d.ts +16 -3
  34. package/dist/middleware/index.d.ts.map +1 -0
  35. package/dist/middleware/index.js +28 -3
  36. package/dist/middleware/index.js.map +1 -1
  37. package/dist/middleware/index.mjs +28 -3
  38. package/dist/middleware/index.mjs.map +1 -1
  39. package/dist/middleware/main.d.ts +40 -0
  40. package/dist/middleware/main.d.ts.map +1 -0
  41. package/dist/middleware/rate-limit-sliding.d.ts +46 -0
  42. package/dist/middleware/rate-limit-sliding.d.ts.map +1 -0
  43. package/dist/middleware/rate-limit-token.d.ts +51 -0
  44. package/dist/middleware/rate-limit-token.d.ts.map +1 -0
  45. package/dist/middleware/rate-limit.d.ts +34 -0
  46. package/dist/middleware/rate-limit.d.ts.map +1 -0
  47. package/dist/sanitizers/command.d.ts +28 -0
  48. package/dist/sanitizers/command.d.ts.map +1 -0
  49. package/dist/sanitizers/encode.d.ts +46 -0
  50. package/dist/sanitizers/encode.d.ts.map +1 -0
  51. package/dist/sanitizers/headers.d.ts +46 -0
  52. package/dist/sanitizers/headers.d.ts.map +1 -0
  53. package/dist/sanitizers/index.d.ts +17 -22
  54. package/dist/sanitizers/index.d.ts.map +1 -0
  55. package/dist/sanitizers/index.js +72 -0
  56. package/dist/sanitizers/index.js.map +1 -1
  57. package/dist/sanitizers/index.mjs +68 -1
  58. package/dist/sanitizers/index.mjs.map +1 -1
  59. package/dist/sanitizers/jsonp.d.ts +34 -0
  60. package/dist/sanitizers/jsonp.d.ts.map +1 -0
  61. package/dist/sanitizers/nosql.d.ts +31 -0
  62. package/dist/sanitizers/nosql.d.ts.map +1 -0
  63. package/dist/sanitizers/path.d.ts +28 -0
  64. package/dist/sanitizers/path.d.ts.map +1 -0
  65. package/dist/sanitizers/pii.d.ts +80 -0
  66. package/dist/sanitizers/pii.d.ts.map +1 -0
  67. package/dist/sanitizers/prototype.d.ts +34 -0
  68. package/dist/sanitizers/prototype.d.ts.map +1 -0
  69. package/dist/sanitizers/sanitize.d.ts +51 -0
  70. package/dist/sanitizers/sanitize.d.ts.map +1 -0
  71. package/dist/sanitizers/sql.d.ts +28 -0
  72. package/dist/sanitizers/sql.d.ts.map +1 -0
  73. package/dist/sanitizers/ssti.d.ts +20 -0
  74. package/dist/sanitizers/ssti.d.ts.map +1 -0
  75. package/dist/sanitizers/utils.d.ts +19 -0
  76. package/dist/sanitizers/utils.d.ts.map +1 -0
  77. package/dist/sanitizers/xss.d.ts +35 -0
  78. package/dist/sanitizers/xss.d.ts.map +1 -0
  79. package/dist/sanitizers/xxe.d.ts +20 -0
  80. package/dist/sanitizers/xxe.d.ts.map +1 -0
  81. package/dist/stores/index.d.ts +6 -104
  82. package/dist/stores/index.d.ts.map +1 -0
  83. package/dist/stores/memory.d.ts +35 -0
  84. package/dist/stores/memory.d.ts.map +1 -0
  85. package/dist/stores/{index.d.mts → redis.d.ts} +6 -45
  86. package/dist/stores/redis.d.ts.map +1 -0
  87. package/dist/utils/duration.d.ts +34 -0
  88. package/dist/utils/duration.d.ts.map +1 -0
  89. package/dist/utils/fingerprint.d.ts +64 -0
  90. package/dist/utils/fingerprint.d.ts.map +1 -0
  91. package/dist/utils/index.d.ts +10 -0
  92. package/dist/utils/index.d.ts.map +1 -0
  93. package/dist/utils/index.js +188 -0
  94. package/dist/utils/index.js.map +1 -0
  95. package/dist/utils/index.mjs +182 -0
  96. package/dist/utils/index.mjs.map +1 -0
  97. package/dist/utils/ip.d.ts +70 -0
  98. package/dist/utils/ip.d.ts.map +1 -0
  99. package/dist/validation/email.d.ts +82 -0
  100. package/dist/validation/email.d.ts.map +1 -0
  101. package/dist/validation/file.d.ts +90 -0
  102. package/dist/validation/file.d.ts.map +1 -0
  103. package/dist/validation/index.d.ts +10 -3
  104. package/dist/validation/index.d.ts.map +1 -0
  105. package/dist/validation/redirect.d.ts +64 -0
  106. package/dist/validation/redirect.d.ts.map +1 -0
  107. package/dist/validation/schema.d.ts +36 -0
  108. package/dist/validation/schema.d.ts.map +1 -0
  109. package/dist/validation/url.d.ts +65 -0
  110. package/dist/validation/url.d.ts.map +1 -0
  111. package/package.json +8 -6
  112. package/dist/index-A-m-pPeW.d.mts +0 -340
  113. package/dist/index-CgK94hY_.d.mts +0 -532
  114. package/dist/index-Co5kPRZz.d.ts +0 -340
  115. package/dist/index-D_bdJcF0.d.ts +0 -532
  116. package/dist/index.d.mts +0 -175
  117. package/dist/middleware/index.d.mts +0 -3
  118. package/dist/pii-CXcHMlnX.d.mts +0 -438
  119. package/dist/pii-DhNpl7M3.d.ts +0 -438
  120. package/dist/sanitizers/index.d.mts +0 -24
  121. package/dist/types-CsOFHoD9.d.ts +0 -269
  122. package/dist/validation/index.d.mts +0 -3
package/dist/index.mjs CHANGED
@@ -303,7 +303,12 @@ function createHeaders(options = {}) {
303
303
  hsts = true,
304
304
  referrerPolicy = HEADERS.REFERRER_POLICY,
305
305
  permissionsPolicy = HEADERS.PERMISSIONS_POLICY,
306
- cacheControl = true
306
+ cacheControl = true,
307
+ crossOriginOpenerPolicy = "same-origin",
308
+ crossOriginResourcePolicy = "same-origin",
309
+ crossOriginEmbedderPolicy = "require-corp",
310
+ originAgentCluster = true,
311
+ dnsPrefetchControl = true
307
312
  } = options;
308
313
  return (req, res, next) => {
309
314
  if (contentSecurityPolicy) {
@@ -311,7 +316,7 @@ function createHeaders(options = {}) {
311
316
  res.setHeader("Content-Security-Policy", csp);
312
317
  }
313
318
  if (xssFilter) {
314
- res.setHeader("X-XSS-Protection", "1; mode=block");
319
+ res.setHeader("X-XSS-Protection", "0");
315
320
  }
316
321
  if (noSniff) {
317
322
  res.setHeader("X-Content-Type-Options", HEADERS.CONTENT_TYPE_OPTIONS);
@@ -338,6 +343,21 @@ function createHeaders(options = {}) {
338
343
  if (permissionsPolicy) {
339
344
  res.setHeader("Permissions-Policy", permissionsPolicy);
340
345
  }
346
+ if (crossOriginOpenerPolicy) {
347
+ res.setHeader("Cross-Origin-Opener-Policy", crossOriginOpenerPolicy);
348
+ }
349
+ if (crossOriginResourcePolicy) {
350
+ res.setHeader("Cross-Origin-Resource-Policy", crossOriginResourcePolicy);
351
+ }
352
+ if (crossOriginEmbedderPolicy) {
353
+ res.setHeader("Cross-Origin-Embedder-Policy", crossOriginEmbedderPolicy);
354
+ }
355
+ if (originAgentCluster) {
356
+ res.setHeader("Origin-Agent-Cluster", "?1");
357
+ }
358
+ if (dnsPrefetchControl) {
359
+ res.setHeader("X-DNS-Prefetch-Control", "off");
360
+ }
341
361
  res.setHeader("X-Permitted-Cross-Domain-Policies", "none");
342
362
  if (cacheControl) {
343
363
  const cacheControlValue = typeof cacheControl === "string" ? cacheControl : HEADERS.CACHE_CONTROL;
@@ -1245,6 +1265,73 @@ function redactObjectPii(obj, options = {}) {
1245
1265
  return result;
1246
1266
  }
1247
1267
 
1268
+ // src/sanitizers/encode.ts
1269
+ var HTML_ENTITIES = {
1270
+ "&": "&",
1271
+ "<": "&lt;",
1272
+ ">": "&gt;",
1273
+ '"': "&quot;",
1274
+ "'": "&#x27;"
1275
+ };
1276
+ var HTML_ENCODE_RE = /[&<>"']/g;
1277
+ function encodeForHtml(value) {
1278
+ if (!value) return "";
1279
+ return value.replace(HTML_ENCODE_RE, (ch) => HTML_ENTITIES[ch]);
1280
+ }
1281
+ function encodeForAttribute(value) {
1282
+ if (!value) return "";
1283
+ let result = "";
1284
+ for (let i = 0; i < value.length; i++) {
1285
+ const ch = value.charCodeAt(i);
1286
+ if (ch >= 48 && ch <= 57 || // 0-9
1287
+ ch >= 65 && ch <= 90 || // A-Z
1288
+ ch >= 97 && ch <= 122) {
1289
+ result += value[i];
1290
+ } else {
1291
+ result += `&#x${ch.toString(16).toUpperCase()};`;
1292
+ }
1293
+ }
1294
+ return result;
1295
+ }
1296
+ function encodeForJs(value) {
1297
+ if (!value) return "";
1298
+ let result = "";
1299
+ for (let i = 0; i < value.length; i++) {
1300
+ const ch = value.charCodeAt(i);
1301
+ if (ch >= 48 && ch <= 57 || // 0-9
1302
+ ch >= 65 && ch <= 90 || // A-Z
1303
+ ch >= 97 && ch <= 122) {
1304
+ result += value[i];
1305
+ } else if (ch < 256) {
1306
+ result += `\\x${ch.toString(16).toUpperCase().padStart(2, "0")}`;
1307
+ } else {
1308
+ result += `\\u${ch.toString(16).toUpperCase().padStart(4, "0")}`;
1309
+ }
1310
+ }
1311
+ return result;
1312
+ }
1313
+ function encodeForUrl(value) {
1314
+ if (!value) return "";
1315
+ return encodeURIComponent(value).replace(/[!'()*]/g, (ch) => {
1316
+ return `%${ch.charCodeAt(0).toString(16).toUpperCase()}`;
1317
+ });
1318
+ }
1319
+ function encodeForCss(value) {
1320
+ if (!value) return "";
1321
+ let result = "";
1322
+ for (let i = 0; i < value.length; i++) {
1323
+ const ch = value.charCodeAt(i);
1324
+ if (ch >= 48 && ch <= 57 || // 0-9
1325
+ ch >= 65 && ch <= 90 || // A-Z
1326
+ ch >= 97 && ch <= 122) {
1327
+ result += value[i];
1328
+ } else {
1329
+ result += `\\${ch.toString(16).toUpperCase()} `;
1330
+ }
1331
+ }
1332
+ return result;
1333
+ }
1334
+
1248
1335
  // src/validation/schema.ts
1249
1336
  function validate(schema, source = "body") {
1250
1337
  return (req, res, next) => {
@@ -2751,12 +2838,14 @@ function getRequestToken(req, headerName, fieldName) {
2751
2838
  return void 0;
2752
2839
  }
2753
2840
  function csrfProtection(options = {}) {
2754
- const cookieName = options.cookieName ?? DEFAULTS.cookieName;
2841
+ const baseCookieName = options.cookieName ?? DEFAULTS.cookieName;
2842
+ const cookieName = options.useHostPrefix ? `__Host-${baseCookieName}` : baseCookieName;
2755
2843
  const headerName = options.headerName ?? DEFAULTS.headerName;
2756
2844
  const fieldName = options.fieldName ?? DEFAULTS.fieldName;
2757
2845
  const tokenLength = options.tokenLength ?? DEFAULTS.tokenLength;
2758
2846
  const protectedMethods = options.protectedMethods ?? [...DEFAULTS.protectedMethods];
2759
2847
  const excludePaths = options.excludePaths ?? [];
2848
+ const skipCsrf = options.skipCsrf;
2760
2849
  const isProduction = process.env.NODE_ENV === "production";
2761
2850
  const cookieOpts = {
2762
2851
  path: options.cookie?.path ?? "/",
@@ -2776,6 +2865,9 @@ function csrfProtection(options = {}) {
2776
2865
  const protectedSet = new Set(protectedMethods.map((m) => m.toUpperCase()));
2777
2866
  return (req, res, next) => {
2778
2867
  const method = req.method.toUpperCase();
2868
+ if (skipCsrf && skipCsrf(req)) {
2869
+ return next();
2870
+ }
2779
2871
  const requestPath = req.path || req.url;
2780
2872
  if (excludePaths.some((p) => requestPath === p || requestPath.startsWith(p + "/"))) {
2781
2873
  return next();
@@ -2832,6 +2924,54 @@ function escapeRegex(str) {
2832
2924
  }
2833
2925
  var createCsrf = csrfProtection;
2834
2926
 
2927
+ // src/middleware/hpp.ts
2928
+ function hpp(options = {}) {
2929
+ const whitelist = new Set(options.whitelist ?? []);
2930
+ const checkQuery = options.checkQuery ?? true;
2931
+ const checkBody = options.checkBody ?? true;
2932
+ return (req, _res, next) => {
2933
+ if (checkQuery && req.query && typeof req.query === "object") {
2934
+ const polluted = {};
2935
+ const clean = {};
2936
+ for (const [key, value] of Object.entries(req.query)) {
2937
+ if (Array.isArray(value)) {
2938
+ const strings = value.filter((v) => typeof v === "string");
2939
+ if (whitelist.has(key)) {
2940
+ clean[key] = strings;
2941
+ } else {
2942
+ polluted[key] = strings;
2943
+ clean[key] = strings[strings.length - 1] ?? "";
2944
+ }
2945
+ } else {
2946
+ clean[key] = value;
2947
+ }
2948
+ }
2949
+ req.queryPolluted = polluted;
2950
+ Object.defineProperty(req, "query", { value: clean, writable: true, configurable: true });
2951
+ }
2952
+ if (checkBody && req.body && typeof req.body === "object" && !Array.isArray(req.body)) {
2953
+ const polluted = {};
2954
+ const clean = {};
2955
+ for (const [key, value] of Object.entries(req.body)) {
2956
+ if (Array.isArray(value)) {
2957
+ if (whitelist.has(key)) {
2958
+ clean[key] = value;
2959
+ } else {
2960
+ polluted[key] = value;
2961
+ clean[key] = value[value.length - 1];
2962
+ }
2963
+ } else {
2964
+ clean[key] = value;
2965
+ }
2966
+ }
2967
+ req.bodyPolluted = polluted;
2968
+ Object.defineProperty(req, "body", { value: clean, writable: true, configurable: true });
2969
+ }
2970
+ next();
2971
+ };
2972
+ }
2973
+ var createHpp = hpp;
2974
+
2835
2975
  // src/utils/ip.ts
2836
2976
  var PLATFORM_HEADERS = {
2837
2977
  cloudflare: "cf-connecting-ip",
@@ -2952,7 +3092,7 @@ function fingerprint(req, options = {}) {
2952
3092
  components.push(`enc:${getHeader2(req, "accept-encoding")}`);
2953
3093
  }
2954
3094
  for (const c of custom) {
2955
- if (c != null) components.push(`custom:${c}`);
3095
+ if (c !== null && c !== void 0) components.push(`custom:${c}`);
2956
3096
  }
2957
3097
  components.sort();
2958
3098
  const hash = createHash("sha256");
@@ -3095,6 +3235,6 @@ function createRedisStore(options) {
3095
3235
  return new RedisStore(options);
3096
3236
  }
3097
3237
 
3098
- export { ArcisError, ValidationError as ArcisValidationError, BLOCKED, ERRORS, HEADERS, INPUT, InputTooLargeError, MemoryStore, RATE_LIMIT, REDACTION, RateLimitError, RedisStore, SanitizationError, SecurityThreatError, VALIDATION, arcis, arcisWithMethods as arcisFunction, botProtection, createCors, createCsrf, createErrorHandler, createHeaders, createRateLimiter, createRedactor, createRedisStore, createSafeLogger, createSanitizer, createSecureCookies, createSlidingWindowLimiter, createTokenBucketLimiter, createValidator, csrfProtection, main_default as default, detectBot, detectClientIp, detectCommandInjection, detectHeaderInjection, detectJsonpInjection, detectNoSqlInjection, detectPathTraversal, detectPii, detectPrototypePollution, detectSql, detectSsti, detectXss, detectXxe, enforceSecureCookie, errorHandler, fingerprint, formatDuration, generateCsrfToken, isDangerousExtension, isDangerousNoSqlKey, isDangerousProtoKey, isPrivateIp, isRedirectSafe, isUrlSafe, isValidEmailSyntax, parseDuration, rateLimit, redactObjectPii, redactPii, safeCors, safeLog, sanitizeCommand, sanitizeFilename, sanitizeHeaderValue, sanitizeHeaders, sanitizeJsonpCallback, sanitizeObject, sanitizePath, sanitizeSql, sanitizeSsti, sanitizeString, sanitizeXss, sanitizeXxe, scanObjectPii, scanPii, secureCookieDefaults, securityHeaders, validate, validateCsrfToken, validateEmail, validateFile, validateRedirect, validateUrl, verifyEmailMx };
3238
+ export { ArcisError, ValidationError as ArcisValidationError, BLOCKED, ERRORS, HEADERS, INPUT, InputTooLargeError, MemoryStore, RATE_LIMIT, REDACTION, RateLimitError, RedisStore, SanitizationError, SecurityThreatError, VALIDATION, arcis, arcisWithMethods as arcisFunction, botProtection, createCors, createCsrf, createErrorHandler, createHeaders, createHpp, createRateLimiter, createRedactor, createRedisStore, createSafeLogger, createSanitizer, createSecureCookies, createSlidingWindowLimiter, createTokenBucketLimiter, createValidator, csrfProtection, main_default as default, detectBot, detectClientIp, detectCommandInjection, detectHeaderInjection, detectJsonpInjection, detectNoSqlInjection, detectPathTraversal, detectPii, detectPrototypePollution, detectSql, detectSsti, detectXss, detectXxe, encodeForAttribute, encodeForCss, encodeForHtml, encodeForJs, encodeForUrl, enforceSecureCookie, errorHandler, fingerprint, formatDuration, generateCsrfToken, hpp, isDangerousExtension, isDangerousNoSqlKey, isDangerousProtoKey, isPrivateIp, isRedirectSafe, isUrlSafe, isValidEmailSyntax, parseDuration, rateLimit, redactObjectPii, redactPii, safeCors, safeLog, sanitizeCommand, sanitizeFilename, sanitizeHeaderValue, sanitizeHeaders, sanitizeJsonpCallback, sanitizeObject, sanitizePath, sanitizeSql, sanitizeSsti, sanitizeString, sanitizeXss, sanitizeXxe, scanObjectPii, scanPii, secureCookieDefaults, securityHeaders, validate, validateCsrfToken, validateEmail, validateFile, validateRedirect, validateUrl, verifyEmailMx };
3099
3239
  //# sourceMappingURL=index.mjs.map
3100
3240
  //# sourceMappingURL=index.mjs.map