@gzl10/ts-helpers 4.2.1
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/CHANGELOG.md +320 -0
- package/README.md +233 -0
- package/USAGE-GUIDE.md +800 -0
- package/dist/browser/async.js +15 -0
- package/dist/browser/async.js.map +1 -0
- package/dist/browser/chunk-4O7ZPIJN.js +383 -0
- package/dist/browser/chunk-4O7ZPIJN.js.map +1 -0
- package/dist/browser/chunk-75XNTC34.js +60 -0
- package/dist/browser/chunk-75XNTC34.js.map +1 -0
- package/dist/browser/chunk-C3D7YZVE.js +299 -0
- package/dist/browser/chunk-C3D7YZVE.js.map +1 -0
- package/dist/browser/chunk-CZL6C2EI.js +452 -0
- package/dist/browser/chunk-CZL6C2EI.js.map +1 -0
- package/dist/browser/chunk-D4FZFIVA.js +240 -0
- package/dist/browser/chunk-D4FZFIVA.js.map +1 -0
- package/dist/browser/chunk-IL7NG7IC.js +72 -0
- package/dist/browser/chunk-IL7NG7IC.js.map +1 -0
- package/dist/browser/chunk-NSBPE2FW.js +17 -0
- package/dist/browser/chunk-NSBPE2FW.js.map +1 -0
- package/dist/browser/chunk-SLQVNPTH.js +27 -0
- package/dist/browser/chunk-SLQVNPTH.js.map +1 -0
- package/dist/browser/chunk-WG7ILCUB.js +195 -0
- package/dist/browser/chunk-WG7ILCUB.js.map +1 -0
- package/dist/browser/chunk-WJA4JDMZ.js +278 -0
- package/dist/browser/chunk-WJA4JDMZ.js.map +1 -0
- package/dist/browser/chunk-ZFVYLUTT.js +65 -0
- package/dist/browser/chunk-ZFVYLUTT.js.map +1 -0
- package/dist/browser/chunk-ZYTSVMTI.js +263 -0
- package/dist/browser/chunk-ZYTSVMTI.js.map +1 -0
- package/dist/browser/dates.js +78 -0
- package/dist/browser/dates.js.map +1 -0
- package/dist/browser/environment-detection.js +21 -0
- package/dist/browser/environment-detection.js.map +1 -0
- package/dist/browser/environment.js +34 -0
- package/dist/browser/environment.js.map +1 -0
- package/dist/browser/errors.js +18 -0
- package/dist/browser/errors.js.map +1 -0
- package/dist/browser/index.js +412 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/math.js +51 -0
- package/dist/browser/math.js.map +1 -0
- package/dist/browser/number.js +10 -0
- package/dist/browser/number.js.map +1 -0
- package/dist/browser/objects.js +31 -0
- package/dist/browser/objects.js.map +1 -0
- package/dist/browser/strings.js +80 -0
- package/dist/browser/strings.js.map +1 -0
- package/dist/browser/validation-core.js +54 -0
- package/dist/browser/validation-core.js.map +1 -0
- package/dist/browser/validation-crypto.js +28 -0
- package/dist/browser/validation-crypto.js.map +1 -0
- package/dist/browser/validators.js +98 -0
- package/dist/browser/validators.js.map +1 -0
- package/dist/cjs/async.js +86 -0
- package/dist/cjs/async.js.map +1 -0
- package/dist/cjs/dates.js +285 -0
- package/dist/cjs/dates.js.map +1 -0
- package/dist/cjs/environment-detection.js +84 -0
- package/dist/cjs/environment-detection.js.map +1 -0
- package/dist/cjs/environment.js +261 -0
- package/dist/cjs/environment.js.map +1 -0
- package/dist/cjs/errors.js +80 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/index.js +2035 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/math.js +388 -0
- package/dist/cjs/math.js.map +1 -0
- package/dist/cjs/number.js +37 -0
- package/dist/cjs/number.js.map +1 -0
- package/dist/cjs/objects.js +249 -0
- package/dist/cjs/objects.js.map +1 -0
- package/dist/cjs/strings.js +253 -0
- package/dist/cjs/strings.js.map +1 -0
- package/dist/cjs/validation.js +450 -0
- package/dist/cjs/validation.js.map +1 -0
- package/dist/esm/async.js +15 -0
- package/dist/esm/async.js.map +1 -0
- package/dist/esm/chunk-4O7ZPIJN.js +383 -0
- package/dist/esm/chunk-4O7ZPIJN.js.map +1 -0
- package/dist/esm/chunk-75XNTC34.js +60 -0
- package/dist/esm/chunk-75XNTC34.js.map +1 -0
- package/dist/esm/chunk-BDOBKBKA.js +72 -0
- package/dist/esm/chunk-BDOBKBKA.js.map +1 -0
- package/dist/esm/chunk-C3D7YZVE.js +299 -0
- package/dist/esm/chunk-C3D7YZVE.js.map +1 -0
- package/dist/esm/chunk-CZL6C2EI.js +452 -0
- package/dist/esm/chunk-CZL6C2EI.js.map +1 -0
- package/dist/esm/chunk-EBLSTOEC.js +263 -0
- package/dist/esm/chunk-EBLSTOEC.js.map +1 -0
- package/dist/esm/chunk-NSBPE2FW.js +17 -0
- package/dist/esm/chunk-NSBPE2FW.js.map +1 -0
- package/dist/esm/chunk-SLQVNPTH.js +27 -0
- package/dist/esm/chunk-SLQVNPTH.js.map +1 -0
- package/dist/esm/chunk-WG7ILCUB.js +195 -0
- package/dist/esm/chunk-WG7ILCUB.js.map +1 -0
- package/dist/esm/chunk-WJA4JDMZ.js +278 -0
- package/dist/esm/chunk-WJA4JDMZ.js.map +1 -0
- package/dist/esm/chunk-ZFVYLUTT.js +65 -0
- package/dist/esm/chunk-ZFVYLUTT.js.map +1 -0
- package/dist/esm/dates.js +78 -0
- package/dist/esm/dates.js.map +1 -0
- package/dist/esm/environment-detection.js +21 -0
- package/dist/esm/environment-detection.js.map +1 -0
- package/dist/esm/environment.js +34 -0
- package/dist/esm/environment.js.map +1 -0
- package/dist/esm/errors.js +18 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/index.js +380 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/math.js +51 -0
- package/dist/esm/math.js.map +1 -0
- package/dist/esm/number.js +10 -0
- package/dist/esm/number.js.map +1 -0
- package/dist/esm/objects.js +31 -0
- package/dist/esm/objects.js.map +1 -0
- package/dist/esm/strings.js +80 -0
- package/dist/esm/strings.js.map +1 -0
- package/dist/esm/validation.js +54 -0
- package/dist/esm/validation.js.map +1 -0
- package/dist/node/async.js +93 -0
- package/dist/node/async.js.map +1 -0
- package/dist/node/csv.js +102 -0
- package/dist/node/csv.js.map +1 -0
- package/dist/node/data.js +880 -0
- package/dist/node/data.js.map +1 -0
- package/dist/node/dates.js +324 -0
- package/dist/node/dates.js.map +1 -0
- package/dist/node/environment.js +278 -0
- package/dist/node/environment.js.map +1 -0
- package/dist/node/errors.js +89 -0
- package/dist/node/errors.js.map +1 -0
- package/dist/node/index.js +3151 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/json.js +107 -0
- package/dist/node/json.js.map +1 -0
- package/dist/node/math.js +413 -0
- package/dist/node/math.js.map +1 -0
- package/dist/node/number.js +42 -0
- package/dist/node/number.js.map +1 -0
- package/dist/node/objects.js +264 -0
- package/dist/node/objects.js.map +1 -0
- package/dist/node/strings.js +293 -0
- package/dist/node/strings.js.map +1 -0
- package/dist/node/tree.js +89 -0
- package/dist/node/tree.js.map +1 -0
- package/dist/node/validation-core.js +477 -0
- package/dist/node/validation-core.js.map +1 -0
- package/dist/node/validation-crypto.js +179 -0
- package/dist/node/validation-crypto.js.map +1 -0
- package/dist/node/validation.js +677 -0
- package/dist/node/validation.js.map +1 -0
- package/dist/node/validators.js +123 -0
- package/dist/node/validators.js.map +1 -0
- package/dist/node-esm/async.js +15 -0
- package/dist/node-esm/async.js.map +1 -0
- package/dist/node-esm/chunk-3YOF7NPT.js +299 -0
- package/dist/node-esm/chunk-3YOF7NPT.js.map +1 -0
- package/dist/node-esm/chunk-64TBXJQS.js +263 -0
- package/dist/node-esm/chunk-64TBXJQS.js.map +1 -0
- package/dist/node-esm/chunk-75XNTC34.js +60 -0
- package/dist/node-esm/chunk-75XNTC34.js.map +1 -0
- package/dist/node-esm/chunk-C4PKXIPB.js +278 -0
- package/dist/node-esm/chunk-C4PKXIPB.js.map +1 -0
- package/dist/node-esm/chunk-CMDFZME3.js +452 -0
- package/dist/node-esm/chunk-CMDFZME3.js.map +1 -0
- package/dist/node-esm/chunk-DZZPUYMP.js +74 -0
- package/dist/node-esm/chunk-DZZPUYMP.js.map +1 -0
- package/dist/node-esm/chunk-HTSEHRHI.js +195 -0
- package/dist/node-esm/chunk-HTSEHRHI.js.map +1 -0
- package/dist/node-esm/chunk-JCAUVOPH.js +27 -0
- package/dist/node-esm/chunk-JCAUVOPH.js.map +1 -0
- package/dist/node-esm/chunk-KBHE3K2F.js +505 -0
- package/dist/node-esm/chunk-KBHE3K2F.js.map +1 -0
- package/dist/node-esm/chunk-LYTET5NX.js +65 -0
- package/dist/node-esm/chunk-LYTET5NX.js.map +1 -0
- package/dist/node-esm/chunk-PZ5AY32C.js +10 -0
- package/dist/node-esm/chunk-PZ5AY32C.js.map +1 -0
- package/dist/node-esm/chunk-UKGXL2QO.js +383 -0
- package/dist/node-esm/chunk-UKGXL2QO.js.map +1 -0
- package/dist/node-esm/chunk-XAEYT23H.js +164 -0
- package/dist/node-esm/chunk-XAEYT23H.js.map +1 -0
- package/dist/node-esm/csv.js +63 -0
- package/dist/node-esm/csv.js.map +1 -0
- package/dist/node-esm/data.js +32 -0
- package/dist/node-esm/data.js.map +1 -0
- package/dist/node-esm/dates.js +78 -0
- package/dist/node-esm/dates.js.map +1 -0
- package/dist/node-esm/environment.js +34 -0
- package/dist/node-esm/environment.js.map +1 -0
- package/dist/node-esm/errors.js +18 -0
- package/dist/node-esm/errors.js.map +1 -0
- package/dist/node-esm/index.js +426 -0
- package/dist/node-esm/index.js.map +1 -0
- package/dist/node-esm/json.js +68 -0
- package/dist/node-esm/json.js.map +1 -0
- package/dist/node-esm/math.js +51 -0
- package/dist/node-esm/math.js.map +1 -0
- package/dist/node-esm/number.js +10 -0
- package/dist/node-esm/number.js.map +1 -0
- package/dist/node-esm/objects.js +31 -0
- package/dist/node-esm/objects.js.map +1 -0
- package/dist/node-esm/strings.js +80 -0
- package/dist/node-esm/strings.js.map +1 -0
- package/dist/node-esm/tree.js +8 -0
- package/dist/node-esm/tree.js.map +1 -0
- package/dist/node-esm/validation-core.js +54 -0
- package/dist/node-esm/validation-core.js.map +1 -0
- package/dist/node-esm/validation-crypto.js +26 -0
- package/dist/node-esm/validation-crypto.js.map +1 -0
- package/dist/node-esm/validation.js +606 -0
- package/dist/node-esm/validation.js.map +1 -0
- package/dist/node-esm/validators.js +98 -0
- package/dist/node-esm/validators.js.map +1 -0
- package/dist/types/async-C8gvbSG-.d.ts +453 -0
- package/dist/types/async.d.ts +1 -0
- package/dist/types/csv.d.ts +226 -0
- package/dist/types/data.d.ts +1561 -0
- package/dist/types/dates-hTiE0Z11.d.ts +298 -0
- package/dist/types/dates.d.ts +1 -0
- package/dist/types/environment-B8eLS7KT.d.ts +420 -0
- package/dist/types/environment-detection.d.ts +102 -0
- package/dist/types/environment.d.ts +1 -0
- package/dist/types/errors.d.ts +147 -0
- package/dist/types/index.d.ts +211 -0
- package/dist/types/json.d.ts +284 -0
- package/dist/types/math-BQ9Lwdp7.d.ts +2060 -0
- package/dist/types/math.d.ts +1 -0
- package/dist/types/number-CYnQfLWj.d.ts +44 -0
- package/dist/types/number.d.ts +1 -0
- package/dist/types/objects-BohS8GCS.d.ts +1185 -0
- package/dist/types/objects.d.ts +1 -0
- package/dist/types/strings-CiqRPYLL.d.ts +1349 -0
- package/dist/types/strings.d.ts +1 -0
- package/dist/types/tree.d.ts +284 -0
- package/dist/types/validation-core-DfHF8rCG.d.ts +238 -0
- package/dist/types/validation-crypto-browser.d.ts +56 -0
- package/dist/types/validation-crypto-node.d.ts +31 -0
- package/dist/types/validation.d.ts +1 -0
- package/dist/types/validators.d.ts +216 -0
- package/package.json +253 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/node/validation-crypto.ts
|
|
21
|
+
var validation_crypto_exports = {};
|
|
22
|
+
__export(validation_crypto_exports, {
|
|
23
|
+
escapeShellCommand: () => escapeShellCommand,
|
|
24
|
+
generateNonce: () => generateNonce,
|
|
25
|
+
generateSecureToken: () => generateSecureToken,
|
|
26
|
+
hashString: () => hashString,
|
|
27
|
+
isSecureUrl: () => isSecureUrl,
|
|
28
|
+
isValidBase64: () => isValidBase64,
|
|
29
|
+
isValidJWTFormat: () => isValidJWTFormat,
|
|
30
|
+
removeDangerousChars: () => removeDangerousChars,
|
|
31
|
+
sanitizeHtml: () => sanitizeHtml,
|
|
32
|
+
validatePassword: () => validatePassword
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(validation_crypto_exports);
|
|
35
|
+
var import_crypto = require("crypto");
|
|
36
|
+
var validatePassword = (password, criteria = {}) => {
|
|
37
|
+
const {
|
|
38
|
+
minLength = 8,
|
|
39
|
+
requireUppercase = true,
|
|
40
|
+
requireLowercase = true,
|
|
41
|
+
requireNumbers = true,
|
|
42
|
+
requireSpecialChars = true,
|
|
43
|
+
maxLength = 128,
|
|
44
|
+
forbiddenPatterns = []
|
|
45
|
+
} = criteria;
|
|
46
|
+
const errors = [];
|
|
47
|
+
let score = 0;
|
|
48
|
+
if (password.length < minLength) {
|
|
49
|
+
errors.push(`La contrase\xF1a debe tener al menos ${minLength} caracteres`);
|
|
50
|
+
} else {
|
|
51
|
+
score += 20;
|
|
52
|
+
}
|
|
53
|
+
if (password.length > maxLength) {
|
|
54
|
+
errors.push(`La contrase\xF1a no puede tener m\xE1s de ${maxLength} caracteres`);
|
|
55
|
+
}
|
|
56
|
+
if (requireUppercase && !/[A-Z]/.test(password)) {
|
|
57
|
+
errors.push("La contrase\xF1a debe contener al menos una letra may\xFAscula");
|
|
58
|
+
} else if (/[A-Z]/.test(password)) {
|
|
59
|
+
score += 15;
|
|
60
|
+
}
|
|
61
|
+
if (requireLowercase && !/[a-z]/.test(password)) {
|
|
62
|
+
errors.push("La contrase\xF1a debe contener al menos una letra min\xFAscula");
|
|
63
|
+
} else if (/[a-z]/.test(password)) {
|
|
64
|
+
score += 15;
|
|
65
|
+
}
|
|
66
|
+
if (requireNumbers && !/\d/.test(password)) {
|
|
67
|
+
errors.push("La contrase\xF1a debe contener al menos un n\xFAmero");
|
|
68
|
+
} else if (/\d/.test(password)) {
|
|
69
|
+
score += 15;
|
|
70
|
+
}
|
|
71
|
+
if (requireSpecialChars && !/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(password)) {
|
|
72
|
+
errors.push("La contrase\xF1a debe contener al menos un caracter especial");
|
|
73
|
+
} else if (/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(password)) {
|
|
74
|
+
score += 15;
|
|
75
|
+
}
|
|
76
|
+
for (const pattern of forbiddenPatterns) {
|
|
77
|
+
if (password.toLowerCase().includes(pattern.toLowerCase())) {
|
|
78
|
+
errors.push(`La contrase\xF1a no puede contener: ${pattern}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (password.length >= 12) score += 10;
|
|
82
|
+
if (password.length >= 16) score += 10;
|
|
83
|
+
if (/(.)\\1{2,}/.test(password)) score -= 10;
|
|
84
|
+
if (/123|abc|qwe/i.test(password)) score -= 15;
|
|
85
|
+
score = Math.max(0, Math.min(100, score));
|
|
86
|
+
let strength;
|
|
87
|
+
if (score < 30) strength = "weak";
|
|
88
|
+
else if (score < 60) strength = "fair";
|
|
89
|
+
else if (score < 80) strength = "good";
|
|
90
|
+
else strength = "strong";
|
|
91
|
+
return {
|
|
92
|
+
isValid: errors.length === 0,
|
|
93
|
+
errors,
|
|
94
|
+
strength,
|
|
95
|
+
score
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
var sanitizeHtml = (html) => {
|
|
99
|
+
if (!html) return "";
|
|
100
|
+
let sanitized = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "").replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, "");
|
|
101
|
+
sanitized = sanitized.replace(/ on\w+="[^"]*"/gi, "");
|
|
102
|
+
sanitized = sanitized.replace(/ on\w+='[^']*'/gi, "");
|
|
103
|
+
sanitized = sanitized.replace(/javascript:/gi, "");
|
|
104
|
+
sanitized = sanitized.replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi, "");
|
|
105
|
+
sanitized = sanitized.replace(/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi, "");
|
|
106
|
+
sanitized = sanitized.replace(/<embed\b[^>]*>/gi, "");
|
|
107
|
+
return sanitized.trim();
|
|
108
|
+
};
|
|
109
|
+
var isValidJWTFormat = (token) => {
|
|
110
|
+
if (!token || typeof token !== "string") return false;
|
|
111
|
+
const parts = token.split(".");
|
|
112
|
+
if (parts.length !== 3) return false;
|
|
113
|
+
try {
|
|
114
|
+
for (const part of parts) {
|
|
115
|
+
if (!part || !/^[A-Za-z0-9_-]+$/.test(part)) return false;
|
|
116
|
+
atob(part.replace(/-/g, "+").replace(/_/g, "/"));
|
|
117
|
+
}
|
|
118
|
+
return true;
|
|
119
|
+
} catch {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
var hashString = (input, salt = "") => {
|
|
124
|
+
return (0, import_crypto.createHash)("sha256").update(input + salt).digest("hex");
|
|
125
|
+
};
|
|
126
|
+
var generateSecureToken = (length = 32) => {
|
|
127
|
+
return (0, import_crypto.randomBytes)(length).toString("hex");
|
|
128
|
+
};
|
|
129
|
+
var isValidBase64 = (input) => {
|
|
130
|
+
if (!input || typeof input !== "string") return false;
|
|
131
|
+
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(input)) return false;
|
|
132
|
+
try {
|
|
133
|
+
const decoded = atob(input);
|
|
134
|
+
const reencoded = btoa(decoded);
|
|
135
|
+
return reencoded === input;
|
|
136
|
+
} catch {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
var escapeShellCommand = (input) => {
|
|
141
|
+
if (!input) return "";
|
|
142
|
+
return input.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, '\\"').replace(/;/g, "\\;").replace(/&/g, "\\&").replace(/\|/g, "\\|").replace(/`/g, "\\`").replace(/\$/g, "\\$").replace(/\(/g, "\\(").replace(/\)/g, "\\)").replace(/</g, "\\\\<").replace(/>/g, "\\\\>");
|
|
143
|
+
};
|
|
144
|
+
var isSecureUrl = (url) => {
|
|
145
|
+
if (!url || typeof url !== "string") return false;
|
|
146
|
+
try {
|
|
147
|
+
const parsed = new URL(url);
|
|
148
|
+
return parsed.protocol === "https:" || parsed.protocol === "http:" && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1");
|
|
149
|
+
} catch {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
var removeDangerousChars = (input, replacement = "") => {
|
|
154
|
+
if (!input) return "";
|
|
155
|
+
return input.replace(/[<>]/g, replacement).replace(/['"]/g, replacement).replace(/[&]/g, replacement).replace(/[\\x00-\\x1f\\x7f]/g, replacement);
|
|
156
|
+
};
|
|
157
|
+
var generateNonce = (length = 32) => {
|
|
158
|
+
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
159
|
+
let result = "";
|
|
160
|
+
const bytes = (0, import_crypto.randomBytes)(length);
|
|
161
|
+
for (let i = 0; i < length; i++) {
|
|
162
|
+
result += chars[bytes[i] % chars.length];
|
|
163
|
+
}
|
|
164
|
+
return result;
|
|
165
|
+
};
|
|
166
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
167
|
+
0 && (module.exports = {
|
|
168
|
+
escapeShellCommand,
|
|
169
|
+
generateNonce,
|
|
170
|
+
generateSecureToken,
|
|
171
|
+
hashString,
|
|
172
|
+
isSecureUrl,
|
|
173
|
+
isValidBase64,
|
|
174
|
+
isValidJWTFormat,
|
|
175
|
+
removeDangerousChars,
|
|
176
|
+
sanitizeHtml,
|
|
177
|
+
validatePassword
|
|
178
|
+
});
|
|
179
|
+
//# sourceMappingURL=validation-crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/node/validation-crypto.ts"],"sourcesContent":["/**\n * Node.js-specific validation utilities with crypto support\n * Uses Node.js crypto module for secure operations\n */\n\n/* eslint-disable complexity */\n\nimport { createHash, randomBytes } from 'crypto'\n\n// =============================================================================\n// PASSWORD VALIDATION (Node.js with crypto)\n// =============================================================================\n\nexport interface PasswordCriteria {\n minLength?: number\n requireUppercase?: boolean\n requireLowercase?: boolean\n requireNumbers?: boolean\n requireSpecialChars?: boolean\n maxLength?: number\n forbiddenPatterns?: string[]\n}\n\nexport interface PasswordValidationResult {\n isValid: boolean\n errors: string[]\n strength: 'weak' | 'fair' | 'good' | 'strong'\n score: number // 0-100\n}\n\nexport const validatePassword = (\n password: string,\n criteria: PasswordCriteria = {}\n): PasswordValidationResult => {\n const {\n minLength = 8,\n requireUppercase = true,\n requireLowercase = true,\n requireNumbers = true,\n requireSpecialChars = true,\n maxLength = 128,\n forbiddenPatterns = [],\n } = criteria\n\n const errors: string[] = []\n let score = 0\n\n if (password.length < minLength) {\n errors.push(`La contraseña debe tener al menos ${minLength} caracteres`)\n } else {\n score += 20\n }\n\n if (password.length > maxLength) {\n errors.push(`La contraseña no puede tener más de ${maxLength} caracteres`)\n }\n\n if (requireUppercase && !/[A-Z]/.test(password)) {\n errors.push('La contraseña debe contener al menos una letra mayúscula')\n } else if (/[A-Z]/.test(password)) {\n score += 15\n }\n\n if (requireLowercase && !/[a-z]/.test(password)) {\n errors.push('La contraseña debe contener al menos una letra minúscula')\n } else if (/[a-z]/.test(password)) {\n score += 15\n }\n\n if (requireNumbers && !/\\d/.test(password)) {\n errors.push('La contraseña debe contener al menos un número')\n } else if (/\\d/.test(password)) {\n score += 15\n }\n\n if (requireSpecialChars && !/[!@#$%^&*()_+\\-=[\\]{};':\"\\\\|,.<>/?]/.test(password)) {\n errors.push('La contraseña debe contener al menos un caracter especial')\n } else if (/[!@#$%^&*()_+\\-=[\\]{};':\"\\\\|,.<>/?]/.test(password)) {\n score += 15\n }\n\n for (const pattern of forbiddenPatterns) {\n if (password.toLowerCase().includes(pattern.toLowerCase())) {\n errors.push(`La contraseña no puede contener: ${pattern}`)\n }\n }\n\n if (password.length >= 12) score += 10\n if (password.length >= 16) score += 10\n\n if (/(.)\\\\1{2,}/.test(password)) score -= 10\n if (/123|abc|qwe/i.test(password)) score -= 15\n\n score = Math.max(0, Math.min(100, score))\n\n let strength: 'weak' | 'fair' | 'good' | 'strong'\n if (score < 30) strength = 'weak'\n else if (score < 60) strength = 'fair'\n else if (score < 80) strength = 'good'\n else strength = 'strong'\n\n return {\n isValid: errors.length === 0,\n errors,\n strength,\n score,\n }\n}\n\n// =============================================================================\n// SECURITY FUNCTIONS (Node.js crypto)\n// =============================================================================\n\nexport const sanitizeHtml = (html: string): string => {\n if (!html) return ''\n\n let sanitized = html\n .replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '')\n .replace(/<style\\b[^<]*(?:(?!<\\/style>)<[^<]*)*<\\/style>/gi, '')\n\n sanitized = sanitized.replace(/ on\\w+=\"[^\"]*\"/gi, '')\n sanitized = sanitized.replace(/ on\\w+='[^']*'/gi, '')\n sanitized = sanitized.replace(/javascript:/gi, '')\n sanitized = sanitized.replace(/<iframe\\b[^<]*(?:(?!<\\/iframe>)<[^<]*)*<\\/iframe>/gi, '')\n sanitized = sanitized.replace(/<object\\b[^<]*(?:(?!<\\/object>)<[^<]*)*<\\/object>/gi, '')\n sanitized = sanitized.replace(/<embed\\b[^>]*>/gi, '')\n\n return sanitized.trim()\n}\n\nexport const isValidJWTFormat = (token: string): boolean => {\n if (!token || typeof token !== 'string') return false\n\n const parts = token.split('.')\n if (parts.length !== 3) return false\n\n try {\n for (const part of parts) {\n if (!part || !/^[A-Za-z0-9_-]+$/.test(part)) return false\n atob(part.replace(/-/g, '+').replace(/_/g, '/'))\n }\n return true\n } catch {\n return false\n }\n}\n\nexport const hashString = (input: string, salt = ''): string => {\n return createHash('sha256')\n .update(input + salt)\n .digest('hex')\n}\n\nexport const generateSecureToken = (length = 32): string => {\n return randomBytes(length).toString('hex')\n}\n\nexport const isValidBase64 = (input: string): boolean => {\n if (!input || typeof input !== 'string') return false\n\n if (!/^[A-Za-z0-9+/]*={0,2}$/.test(input)) return false\n\n try {\n const decoded = atob(input)\n const reencoded = btoa(decoded)\n return reencoded === input\n } catch {\n return false\n }\n}\n\nexport const escapeShellCommand = (input: string): string => {\n if (!input) return ''\n\n return input\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/'/g, \"\\\\'\")\n .replace(/\"/g, '\\\\\"')\n .replace(/;/g, '\\\\;')\n .replace(/&/g, '\\\\&')\n .replace(/\\|/g, '\\\\|')\n .replace(/`/g, '\\\\`')\n .replace(/\\$/g, '\\\\$')\n .replace(/\\(/g, '\\\\(')\n .replace(/\\)/g, '\\\\)')\n .replace(/</g, '\\\\\\\\<')\n .replace(/>/g, '\\\\\\\\>')\n}\n\nexport const isSecureUrl = (url: string): boolean => {\n if (!url || typeof url !== 'string') return false\n\n try {\n const parsed = new URL(url)\n return (\n parsed.protocol === 'https:' ||\n (parsed.protocol === 'http:' &&\n (parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1'))\n )\n } catch {\n return false\n }\n}\n\nexport const removeDangerousChars = (input: string, replacement = ''): string => {\n if (!input) return ''\n\n return input\n .replace(/[<>]/g, replacement)\n .replace(/['\"]/g, replacement)\n .replace(/[&]/g, replacement)\n .replace(/[\\\\x00-\\\\x1f\\\\x7f]/g, replacement)\n}\n\nexport const generateNonce = (length = 32): string => {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'\n let result = ''\n\n const bytes = randomBytes(length)\n for (let i = 0; i < length; i++) {\n result += chars[bytes[i] % chars.length]\n }\n\n return result\n}\n"],"mappings":"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","names":[]}
|