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