@loggerjs/processors 0.3.0 → 0.5.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.
- package/dist/index.cjs +95 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +95 -15
- package/dist/index.js.map +1 -1
- package/dist/privacy-guard.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1006,21 +1006,87 @@ function passesLuhn(input) {
|
|
|
1006
1006
|
}
|
|
1007
1007
|
return sum % 10 === 0;
|
|
1008
1008
|
}
|
|
1009
|
-
const DEFAULT_PATTERNS = [
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
{
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1009
|
+
const DEFAULT_PATTERNS = [{
|
|
1010
|
+
name: "bearer-token",
|
|
1011
|
+
pattern: /\bBearer\s+[A-Za-z0-9._~+/=-]+\b/g
|
|
1012
|
+
}, {
|
|
1013
|
+
name: "credit-card",
|
|
1014
|
+
pattern: /\b(?:\d[ -]*?){13,19}\b/g,
|
|
1015
|
+
validate: passesLuhn
|
|
1016
|
+
}];
|
|
1017
|
+
function isAsciiAlpha(code) {
|
|
1018
|
+
return code >= 65 && code <= 90 || code >= 97 && code <= 122;
|
|
1019
|
+
}
|
|
1020
|
+
function isAsciiAlphaNumeric(code) {
|
|
1021
|
+
return isAsciiAlpha(code) || code >= 48 && code <= 57;
|
|
1022
|
+
}
|
|
1023
|
+
function hasChar(code, chars) {
|
|
1024
|
+
return chars.includes(String.fromCharCode(code));
|
|
1025
|
+
}
|
|
1026
|
+
function isEmailLocalChar(code) {
|
|
1027
|
+
return isAsciiAlphaNumeric(code) || hasChar(code, "._%+-");
|
|
1028
|
+
}
|
|
1029
|
+
function isEmailDomainChar(code) {
|
|
1030
|
+
return isAsciiAlphaNumeric(code) || hasChar(code, "-.");
|
|
1031
|
+
}
|
|
1032
|
+
function hasValidEmailDomain(input, start, end) {
|
|
1033
|
+
let labelLength = 0;
|
|
1034
|
+
let dotCount = 0;
|
|
1035
|
+
let tldStart = -1;
|
|
1036
|
+
for (let index = start; index < end; index += 1) {
|
|
1037
|
+
if (input.charCodeAt(index) === 46) {
|
|
1038
|
+
if (labelLength === 0) return false;
|
|
1039
|
+
dotCount += 1;
|
|
1040
|
+
labelLength = 0;
|
|
1041
|
+
tldStart = index + 1;
|
|
1042
|
+
continue;
|
|
1043
|
+
}
|
|
1044
|
+
labelLength += 1;
|
|
1022
1045
|
}
|
|
1023
|
-
|
|
1046
|
+
if (dotCount === 0 || labelLength === 0 || tldStart < 0 || end - tldStart < 2) return false;
|
|
1047
|
+
for (let index = tldStart; index < end; index += 1) if (!isAsciiAlpha(input.charCodeAt(index))) return false;
|
|
1048
|
+
return true;
|
|
1049
|
+
}
|
|
1050
|
+
function redactEmailAddresses(input, path, options) {
|
|
1051
|
+
let output = "";
|
|
1052
|
+
let last = 0;
|
|
1053
|
+
let changed = false;
|
|
1054
|
+
let index = 0;
|
|
1055
|
+
while (index < input.length) {
|
|
1056
|
+
if (!isAsciiAlphaNumeric(input.charCodeAt(index))) {
|
|
1057
|
+
index += 1;
|
|
1058
|
+
continue;
|
|
1059
|
+
}
|
|
1060
|
+
const localStart = index;
|
|
1061
|
+
let cursor = index + 1;
|
|
1062
|
+
while (cursor < input.length && isEmailLocalChar(input.charCodeAt(cursor))) cursor += 1;
|
|
1063
|
+
if (input.charCodeAt(cursor) !== 64) {
|
|
1064
|
+
index = cursor + 1;
|
|
1065
|
+
continue;
|
|
1066
|
+
}
|
|
1067
|
+
const domainStart = cursor + 1;
|
|
1068
|
+
cursor = domainStart;
|
|
1069
|
+
while (cursor < input.length && isEmailDomainChar(input.charCodeAt(cursor))) cursor += 1;
|
|
1070
|
+
if (domainStart < cursor && hasValidEmailDomain(input, domainStart, cursor) && (cursor >= input.length || !isEmailLocalChar(input.charCodeAt(cursor)))) {
|
|
1071
|
+
output += input.slice(last, localStart);
|
|
1072
|
+
output += options.replacement;
|
|
1073
|
+
options.onRedact?.(path, "email");
|
|
1074
|
+
last = cursor;
|
|
1075
|
+
changed = true;
|
|
1076
|
+
index = cursor;
|
|
1077
|
+
continue;
|
|
1078
|
+
}
|
|
1079
|
+
index = domainStart;
|
|
1080
|
+
}
|
|
1081
|
+
if (!changed) return {
|
|
1082
|
+
value: input,
|
|
1083
|
+
changed: false
|
|
1084
|
+
};
|
|
1085
|
+
return {
|
|
1086
|
+
value: output + input.slice(last),
|
|
1087
|
+
changed: true
|
|
1088
|
+
};
|
|
1089
|
+
}
|
|
1024
1090
|
function matcherMatches(matcher, key, path, value) {
|
|
1025
1091
|
if (typeof matcher === "string") return matcher.toLowerCase() === key.toLowerCase();
|
|
1026
1092
|
if (matcher instanceof RegExp) {
|
|
@@ -1038,21 +1104,34 @@ function redact(path, reason, options) {
|
|
|
1038
1104
|
}
|
|
1039
1105
|
function guardString(input, path, options) {
|
|
1040
1106
|
let value = input;
|
|
1107
|
+
let changed = false;
|
|
1108
|
+
if (value.length > options.maxStringLength) {
|
|
1109
|
+
options.onRedact?.(path, "max-string-length");
|
|
1110
|
+
value = `${value.slice(0, options.maxStringLength)}${options.truncateSuffix}`;
|
|
1111
|
+
changed = true;
|
|
1112
|
+
}
|
|
1113
|
+
if (options.redactDefaultEmailPattern) {
|
|
1114
|
+
const emailResult = redactEmailAddresses(value, path, options);
|
|
1115
|
+
value = emailResult.value;
|
|
1116
|
+
changed ||= emailResult.changed;
|
|
1117
|
+
}
|
|
1041
1118
|
for (const item of options.patterns) {
|
|
1042
1119
|
item.pattern.lastIndex = 0;
|
|
1043
1120
|
value = value.replace(item.pattern, (match) => {
|
|
1044
1121
|
if (item.validate && !item.validate(match)) return match;
|
|
1045
1122
|
options.onRedact?.(path, item.name);
|
|
1123
|
+
changed = true;
|
|
1046
1124
|
return item.replacement ?? options.replacement;
|
|
1047
1125
|
});
|
|
1048
1126
|
}
|
|
1049
1127
|
if (value.length > options.maxStringLength) {
|
|
1050
1128
|
options.onRedact?.(path, "max-string-length");
|
|
1051
1129
|
value = `${value.slice(0, options.maxStringLength)}${options.truncateSuffix}`;
|
|
1130
|
+
changed = true;
|
|
1052
1131
|
}
|
|
1053
1132
|
return {
|
|
1054
1133
|
value,
|
|
1055
|
-
changed: value !== input
|
|
1134
|
+
changed: changed || value !== input
|
|
1056
1135
|
};
|
|
1057
1136
|
}
|
|
1058
1137
|
function guardValue(value, path, key, depth, options, seen) {
|
|
@@ -1131,6 +1210,7 @@ function privacyGuardProcessor(options = {}) {
|
|
|
1131
1210
|
denyKeys: options.denyKeys ?? DEFAULT_DENY_KEYS,
|
|
1132
1211
|
allowKeys: options.allowKeys ?? [],
|
|
1133
1212
|
patterns: options.patterns ?? DEFAULT_PATTERNS,
|
|
1213
|
+
redactDefaultEmailPattern: options.patterns === void 0,
|
|
1134
1214
|
replacement: options.replacement ?? "[REDACTED]",
|
|
1135
1215
|
maxDepth: Math.max(0, Math.floor(options.maxDepth ?? 8)),
|
|
1136
1216
|
maxStringLength: Math.max(1, Math.floor(options.maxStringLength ?? 8192)),
|