@gyramais/log-redaction 0.1.0 → 0.2.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/README.md +7 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +63 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +69 -0
package/README.md
CHANGED
|
@@ -19,6 +19,13 @@ Esses quatro são os usados por **todas as 9 variantes** da classe
|
|
|
19
19
|
`looksPersonal`, `maskPii`) e as constantes também são exportados, para quem
|
|
20
20
|
precise compor caso específico ou testar direto.
|
|
21
21
|
|
|
22
|
+
**Documento sai parcial:** `cpf`, `cnpj`, `document`, `documents`, `newDocument` e
|
|
23
|
+
`signerDocument` preservam os 3 primeiros e os 2 últimos dígitos
|
|
24
|
+
(`11122233344` -> `111******44`), em vez de virarem `****`. É a convenção que já
|
|
25
|
+
existia em `gyra-integration/src/common/utils/mask-document.ts`, e os casos da spec
|
|
26
|
+
daquele arquivo são testados aqui para as implementações não divergirem. As outras
|
|
27
|
+
chaves de PII seguem em mascaramento total.
|
|
28
|
+
|
|
22
29
|
Sem dependência de runtime.
|
|
23
30
|
|
|
24
31
|
## Proveniência
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export declare const SENSITIVE_FIELDS: string[];
|
|
|
4
4
|
export declare const OAUTH_CALLBACK_ONLY_FIELDS: string[];
|
|
5
5
|
export declare const OIDC_CALLBACK_MARKERS: string[];
|
|
6
6
|
export declare const PII_FIELDS: string[];
|
|
7
|
+
export declare const DOCUMENT_FIELDS: string[];
|
|
7
8
|
export declare const AMBIGUOUS_PII_FIELDS: string[];
|
|
8
9
|
export declare const LOOKS_PERSONAL: RegExp;
|
|
9
10
|
export declare const FORMATTING_NOISE: RegExp;
|
|
@@ -15,10 +16,12 @@ export declare const MAX_MASK_DEPTH = 4;
|
|
|
15
16
|
export declare const normalizeKey: (key: string) => string;
|
|
16
17
|
export declare const isSensitive: (key: string) => boolean;
|
|
17
18
|
export declare const isPii: (key: string) => boolean;
|
|
19
|
+
export declare const isDocument: (key: string) => boolean;
|
|
18
20
|
export declare const isAmbiguousPii: (key: string, value: unknown) => boolean;
|
|
19
21
|
export declare const isOauthCallbackOnly: (key: string) => boolean;
|
|
20
22
|
export declare const isOidcCallbackShape: (obj: Record<string, unknown>) => boolean;
|
|
21
23
|
export declare const maskPii: (value: unknown) => unknown;
|
|
24
|
+
export declare const maskDocument: (value: unknown) => unknown;
|
|
22
25
|
export declare const pickSafeHeaders: (headers: IncomingHttpHeaders | undefined) => Record<string, unknown>;
|
|
23
26
|
export declare const maskSensitive: <T>(value: T, depth?: number, seen?: WeakSet<object>) => T;
|
|
24
27
|
export declare const maskUrl: (url: string) => string;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAQhD,eAAO,MAAM,YAAY,UAMxB,CAAC;AAGF,eAAO,MAAM,gBAAgB,UAuB5B,CAAC;AAWF,eAAO,MAAM,0BAA0B,UAAY,CAAC;AAGpD,eAAO,MAAM,qBAAqB,UAAsB,CAAC;AAgBzD,eAAO,MAAM,UAAU,UActB,CAAC;AAQF,eAAO,MAAM,oBAAoB,UAAS,CAAC;AAM3C,eAAO,MAAM,cAAc,QAAqB,CAAC;AAKjD,eAAO,MAAM,gBAAgB,QAAa,CAAC;AAE3C,eAAO,MAAM,aAAa,GAAI,OAAO,OAAO,KAAG,OAEW,CAAC;AAE3D,eAAO,MAAM,QAAQ,SAAS,CAAC;AAC/B,eAAO,MAAM,SAAS,+BAA0B,CAAC;AACjD,eAAO,MAAM,QAAQ,eAAe,CAAC;AAIrC,eAAO,MAAM,cAAc,IAAI,CAAC;AAOhC,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,KAAG,MACH,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAQhD,eAAO,MAAM,YAAY,UAMxB,CAAC;AAGF,eAAO,MAAM,gBAAgB,UAuB5B,CAAC;AAWF,eAAO,MAAM,0BAA0B,UAAY,CAAC;AAGpD,eAAO,MAAM,qBAAqB,UAAsB,CAAC;AAgBzD,eAAO,MAAM,UAAU,UActB,CAAC;AAUF,eAAO,MAAM,eAAe,UAO3B,CAAC;AAQF,eAAO,MAAM,oBAAoB,UAAS,CAAC;AAM3C,eAAO,MAAM,cAAc,QAAqB,CAAC;AAKjD,eAAO,MAAM,gBAAgB,QAAa,CAAC;AAE3C,eAAO,MAAM,aAAa,GAAI,OAAO,OAAO,KAAG,OAEW,CAAC;AAE3D,eAAO,MAAM,QAAQ,SAAS,CAAC;AAC/B,eAAO,MAAM,SAAS,+BAA0B,CAAC;AACjD,eAAO,MAAM,QAAQ,eAAe,CAAC;AAIrC,eAAO,MAAM,cAAc,IAAI,CAAC;AAOhC,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,KAAG,MACH,CAAC;AAWzC,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,OACH,CAAC;AACxC,eAAO,MAAM,KAAK,GAAI,KAAK,MAAM,KAAG,OAA0C,CAAC;AAC/E,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,KAAG,OACH,CAAC;AAYvC,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,EAAE,OAAO,OAAO,KAAG,OAEkB,CAAC;AAEhF,eAAO,MAAM,mBAAmB,GAAI,KAAK,MAAM,KAAG,OACD,CAAC;AAElD,eAAO,MAAM,mBAAmB,GAAI,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,OACM,CAAC;AAK1E,eAAO,MAAM,OAAO,GAAI,OAAO,OAAO,KAAG,OAgBxC,CAAC;AAgBF,eAAO,MAAM,YAAY,GAAI,OAAO,OAAO,KAAG,OA6B7C,CAAC;AAIF,eAAO,MAAM,eAAe,GAC1B,SAAS,mBAAmB,GAAG,SAAS,KACvC,MAAM,CAAC,MAAM,EAAE,OAAO,CAcxB,CAAC;AAcF,eAAO,MAAM,aAAa,GAAI,CAAC,EAC7B,OAAO,CAAC,EACR,cAAS,EACT,sBAA4B,KAC3B,CA8CF,CAAC;AAMF,eAAO,MAAM,OAAO,GAAI,KAAK,MAAM,KAAG,MAgCrC,CAAC;AAOF,eAAO,MAAM,aAAa,GACxB,KAAK,OAAO,KACX;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAUlD,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.describeError = exports.maskUrl = exports.maskSensitive = exports.pickSafeHeaders = exports.maskPii = exports.isOidcCallbackShape = exports.isOauthCallbackOnly = exports.isAmbiguousPii = exports.isPii = exports.isSensitive = exports.normalizeKey = exports.MAX_MASK_DEPTH = exports.CIRCULAR = exports.TRUNCATED = exports.REDACTED = exports.looksPersonal = exports.FORMATTING_NOISE = exports.LOOKS_PERSONAL = exports.AMBIGUOUS_PII_FIELDS = exports.PII_FIELDS = exports.OIDC_CALLBACK_MARKERS = exports.OAUTH_CALLBACK_ONLY_FIELDS = exports.SENSITIVE_FIELDS = exports.SAFE_HEADERS = void 0;
|
|
4
|
+
exports.describeError = exports.maskUrl = exports.maskSensitive = exports.pickSafeHeaders = exports.maskDocument = exports.maskPii = exports.isOidcCallbackShape = exports.isOauthCallbackOnly = exports.isAmbiguousPii = exports.isDocument = exports.isPii = exports.isSensitive = exports.normalizeKey = exports.MAX_MASK_DEPTH = exports.CIRCULAR = exports.TRUNCATED = exports.REDACTED = exports.looksPersonal = exports.FORMATTING_NOISE = exports.LOOKS_PERSONAL = exports.AMBIGUOUS_PII_FIELDS = exports.DOCUMENT_FIELDS = exports.PII_FIELDS = exports.OIDC_CALLBACK_MARKERS = exports.OAUTH_CALLBACK_ONLY_FIELDS = exports.SENSITIVE_FIELDS = exports.SAFE_HEADERS = void 0;
|
|
5
5
|
// Allowlist: só o que está listado aqui chega ao log. Uma denylist
|
|
6
6
|
// (`delete headers.authorization`) falharia em silêncio no dia em que alguém
|
|
7
7
|
// adicionasse um header novo carregando credencial.
|
|
@@ -81,6 +81,22 @@ exports.PII_FIELDS = [
|
|
|
81
81
|
'signerPhoneNumber',
|
|
82
82
|
'signerName',
|
|
83
83
|
];
|
|
84
|
+
// Documento é PII, mas de um tipo em que dígito parcial ainda é útil para
|
|
85
|
+
// investigar sem identificar a pessoa. Estas chaves recebem mascaramento PARCIAL
|
|
86
|
+
// (`maskDocument`) em vez de `****`; as outras chaves de PII_FIELDS seguem no
|
|
87
|
+
// mascaramento total.
|
|
88
|
+
//
|
|
89
|
+
// A lista é subconjunto de PII_FIELDS de propósito: a ordem de checagem em
|
|
90
|
+
// `maskSensitive` testa documento ANTES de PII, então o que estiver aqui ganha o
|
|
91
|
+
// tratamento parcial e o resto cai no total.
|
|
92
|
+
exports.DOCUMENT_FIELDS = [
|
|
93
|
+
'cpf',
|
|
94
|
+
'cnpj',
|
|
95
|
+
'document',
|
|
96
|
+
'documents',
|
|
97
|
+
'newDocument',
|
|
98
|
+
'signerDocument',
|
|
99
|
+
];
|
|
84
100
|
// Chaves cujo significado varia entre os 15 serviços. Aqui a decisão é pelo
|
|
85
101
|
// VALOR, não pelo nome: `to` é destinatário de e-mail no gyra-communication, mas
|
|
86
102
|
// é data ISO em `UsageQueryDto.to` (gyra-billing) e limite de faixa numérica em
|
|
@@ -117,11 +133,14 @@ const SENSITIVE_KEYS = new Set(exports.SENSITIVE_FIELDS.map(exports.normalizeKey
|
|
|
117
133
|
const OAUTH_CALLBACK_ONLY_KEYS = new Set(exports.OAUTH_CALLBACK_ONLY_FIELDS.map(exports.normalizeKey));
|
|
118
134
|
const OIDC_MARKER_KEYS = new Set(exports.OIDC_CALLBACK_MARKERS.map(exports.normalizeKey));
|
|
119
135
|
const PII_KEYS = new Set(exports.PII_FIELDS.map(exports.normalizeKey));
|
|
136
|
+
const DOCUMENT_KEYS = new Set(exports.DOCUMENT_FIELDS.map(exports.normalizeKey));
|
|
120
137
|
const AMBIGUOUS_PII_KEYS = new Set(exports.AMBIGUOUS_PII_FIELDS.map(exports.normalizeKey));
|
|
121
138
|
const isSensitive = (key) => SENSITIVE_KEYS.has((0, exports.normalizeKey)(key));
|
|
122
139
|
exports.isSensitive = isSensitive;
|
|
123
140
|
const isPii = (key) => PII_KEYS.has((0, exports.normalizeKey)(key));
|
|
124
141
|
exports.isPii = isPii;
|
|
142
|
+
const isDocument = (key) => DOCUMENT_KEYS.has((0, exports.normalizeKey)(key));
|
|
143
|
+
exports.isDocument = isDocument;
|
|
125
144
|
// Chave ambígua: só é PII se o valor parecer dado pessoal.
|
|
126
145
|
//
|
|
127
146
|
// O ramo de array é obrigatório, não conveniência: `InternalAlertDto.to` é
|
|
@@ -156,6 +175,43 @@ const maskPii = (value) => {
|
|
|
156
175
|
return at > 0 ? `${exports.REDACTED}${value.slice(at)}` : exports.REDACTED;
|
|
157
176
|
};
|
|
158
177
|
exports.maskPii = maskPii;
|
|
178
|
+
// Preserva os 3 primeiros e os 2 últimos dígitos, mascarando o meio.
|
|
179
|
+
//
|
|
180
|
+
// Convenção da plataforma, não invenção deste pacote: é o mesmo formato de
|
|
181
|
+
// `gyra-integration/src/common/utils/mask-document.ts`, já em produção e já
|
|
182
|
+
// justificado ali como "LGPD — não logar documento cru".
|
|
183
|
+
//
|
|
184
|
+
// A LGPD não prescreve contagem de dígitos — é principiológica. O que este formato
|
|
185
|
+
// entrega é minimização com utilidade: dá para correlacionar duas linhas do mesmo
|
|
186
|
+
// documento e conferir prefixo de CNPJ sem reconstruir o número.
|
|
187
|
+
//
|
|
188
|
+
// Documento com 5 dígitos ou menos é mascarado por inteiro: não sobraria meio para
|
|
189
|
+
// esconder, e `12***45` de um número de 7 dígitos revelaria quase tudo.
|
|
190
|
+
const MIN_DOCUMENT_DIGITS_TO_PARTIAL = 5;
|
|
191
|
+
const maskDocument = (value) => {
|
|
192
|
+
if (Array.isArray(value)) {
|
|
193
|
+
return value.map(exports.maskDocument);
|
|
194
|
+
}
|
|
195
|
+
if (value === null || value === undefined) {
|
|
196
|
+
return value;
|
|
197
|
+
}
|
|
198
|
+
if (typeof value !== 'string' && typeof value !== 'number') {
|
|
199
|
+
return exports.REDACTED;
|
|
200
|
+
}
|
|
201
|
+
// Pontuação sai antes: `12.345.678/0001-99` e `12345678000199` são o mesmo
|
|
202
|
+
// documento, e têm que sair mascarados igual.
|
|
203
|
+
const digits = String(value).replace(/\D/g, '');
|
|
204
|
+
if (!digits) {
|
|
205
|
+
return exports.REDACTED;
|
|
206
|
+
}
|
|
207
|
+
if (digits.length <= MIN_DOCUMENT_DIGITS_TO_PARTIAL) {
|
|
208
|
+
return '*'.repeat(digits.length);
|
|
209
|
+
}
|
|
210
|
+
const head = digits.slice(0, 3);
|
|
211
|
+
const tail = digits.slice(-2);
|
|
212
|
+
return `${head}${'*'.repeat(digits.length - 5)}${tail}`;
|
|
213
|
+
};
|
|
214
|
+
exports.maskDocument = maskDocument;
|
|
159
215
|
// Node normaliza os nomes dos headers de entrada para minúsculas em
|
|
160
216
|
// `req.headers`, então a comparação é direta.
|
|
161
217
|
const pickSafeHeaders = (headers) => {
|
|
@@ -206,6 +262,9 @@ const maskSensitive = (value, depth = 0, seen = new WeakSet()) => {
|
|
|
206
262
|
if ((0, exports.isSensitive)(key) || (oidcCallback && (0, exports.isOauthCallbackOnly)(key))) {
|
|
207
263
|
masked[key] = exports.REDACTED;
|
|
208
264
|
}
|
|
265
|
+
else if ((0, exports.isDocument)(key)) {
|
|
266
|
+
masked[key] = (0, exports.maskDocument)(nested);
|
|
267
|
+
}
|
|
209
268
|
else if ((0, exports.isPii)(key) || (0, exports.isAmbiguousPii)(key, nested)) {
|
|
210
269
|
masked[key] = (0, exports.maskPii)(nested);
|
|
211
270
|
}
|
|
@@ -247,6 +306,9 @@ const maskUrl = (url) => {
|
|
|
247
306
|
if ((0, exports.isSensitive)(key) || (0, exports.isOauthCallbackOnly)(key)) {
|
|
248
307
|
masked.append(key, exports.REDACTED);
|
|
249
308
|
}
|
|
309
|
+
else if ((0, exports.isDocument)(key)) {
|
|
310
|
+
masked.append(key, String((0, exports.maskDocument)(value)));
|
|
311
|
+
}
|
|
250
312
|
else if ((0, exports.isPii)(key) || (0, exports.isAmbiguousPii)(key, value)) {
|
|
251
313
|
masked.append(key, String((0, exports.maskPii)(value)));
|
|
252
314
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -108,6 +108,23 @@ export const PII_FIELDS = [
|
|
|
108
108
|
'signerName',
|
|
109
109
|
];
|
|
110
110
|
|
|
111
|
+
// Documento é PII, mas de um tipo em que dígito parcial ainda é útil para
|
|
112
|
+
// investigar sem identificar a pessoa. Estas chaves recebem mascaramento PARCIAL
|
|
113
|
+
// (`maskDocument`) em vez de `****`; as outras chaves de PII_FIELDS seguem no
|
|
114
|
+
// mascaramento total.
|
|
115
|
+
//
|
|
116
|
+
// A lista é subconjunto de PII_FIELDS de propósito: a ordem de checagem em
|
|
117
|
+
// `maskSensitive` testa documento ANTES de PII, então o que estiver aqui ganha o
|
|
118
|
+
// tratamento parcial e o resto cai no total.
|
|
119
|
+
export const DOCUMENT_FIELDS = [
|
|
120
|
+
'cpf',
|
|
121
|
+
'cnpj',
|
|
122
|
+
'document',
|
|
123
|
+
'documents',
|
|
124
|
+
'newDocument',
|
|
125
|
+
'signerDocument',
|
|
126
|
+
];
|
|
127
|
+
|
|
111
128
|
// Chaves cujo significado varia entre os 15 serviços. Aqui a decisão é pelo
|
|
112
129
|
// VALOR, não pelo nome: `to` é destinatário de e-mail no gyra-communication, mas
|
|
113
130
|
// é data ISO em `UsageQueryDto.to` (gyra-billing) e limite de faixa numérica em
|
|
@@ -153,11 +170,14 @@ const OAUTH_CALLBACK_ONLY_KEYS = new Set(
|
|
|
153
170
|
);
|
|
154
171
|
const OIDC_MARKER_KEYS = new Set(OIDC_CALLBACK_MARKERS.map(normalizeKey));
|
|
155
172
|
const PII_KEYS = new Set(PII_FIELDS.map(normalizeKey));
|
|
173
|
+
const DOCUMENT_KEYS = new Set(DOCUMENT_FIELDS.map(normalizeKey));
|
|
156
174
|
const AMBIGUOUS_PII_KEYS = new Set(AMBIGUOUS_PII_FIELDS.map(normalizeKey));
|
|
157
175
|
|
|
158
176
|
export const isSensitive = (key: string): boolean =>
|
|
159
177
|
SENSITIVE_KEYS.has(normalizeKey(key));
|
|
160
178
|
export const isPii = (key: string): boolean => PII_KEYS.has(normalizeKey(key));
|
|
179
|
+
export const isDocument = (key: string): boolean =>
|
|
180
|
+
DOCUMENT_KEYS.has(normalizeKey(key));
|
|
161
181
|
|
|
162
182
|
// Chave ambígua: só é PII se o valor parecer dado pessoal.
|
|
163
183
|
//
|
|
@@ -200,6 +220,51 @@ export const maskPii = (value: unknown): unknown => {
|
|
|
200
220
|
return at > 0 ? `${REDACTED}${value.slice(at)}` : REDACTED;
|
|
201
221
|
};
|
|
202
222
|
|
|
223
|
+
// Preserva os 3 primeiros e os 2 últimos dígitos, mascarando o meio.
|
|
224
|
+
//
|
|
225
|
+
// Convenção da plataforma, não invenção deste pacote: é o mesmo formato de
|
|
226
|
+
// `gyra-integration/src/common/utils/mask-document.ts`, já em produção e já
|
|
227
|
+
// justificado ali como "LGPD — não logar documento cru".
|
|
228
|
+
//
|
|
229
|
+
// A LGPD não prescreve contagem de dígitos — é principiológica. O que este formato
|
|
230
|
+
// entrega é minimização com utilidade: dá para correlacionar duas linhas do mesmo
|
|
231
|
+
// documento e conferir prefixo de CNPJ sem reconstruir o número.
|
|
232
|
+
//
|
|
233
|
+
// Documento com 5 dígitos ou menos é mascarado por inteiro: não sobraria meio para
|
|
234
|
+
// esconder, e `12***45` de um número de 7 dígitos revelaria quase tudo.
|
|
235
|
+
const MIN_DOCUMENT_DIGITS_TO_PARTIAL = 5;
|
|
236
|
+
|
|
237
|
+
export const maskDocument = (value: unknown): unknown => {
|
|
238
|
+
if (Array.isArray(value)) {
|
|
239
|
+
return value.map(maskDocument);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (value === null || value === undefined) {
|
|
243
|
+
return value;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (typeof value !== 'string' && typeof value !== 'number') {
|
|
247
|
+
return REDACTED;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Pontuação sai antes: `12.345.678/0001-99` e `12345678000199` são o mesmo
|
|
251
|
+
// documento, e têm que sair mascarados igual.
|
|
252
|
+
const digits = String(value).replace(/\D/g, '');
|
|
253
|
+
|
|
254
|
+
if (!digits) {
|
|
255
|
+
return REDACTED;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (digits.length <= MIN_DOCUMENT_DIGITS_TO_PARTIAL) {
|
|
259
|
+
return '*'.repeat(digits.length);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const head = digits.slice(0, 3);
|
|
263
|
+
const tail = digits.slice(-2);
|
|
264
|
+
|
|
265
|
+
return `${head}${'*'.repeat(digits.length - 5)}${tail}`;
|
|
266
|
+
};
|
|
267
|
+
|
|
203
268
|
// Node normaliza os nomes dos headers de entrada para minúsculas em
|
|
204
269
|
// `req.headers`, então a comparação é direta.
|
|
205
270
|
export const pickSafeHeaders = (
|
|
@@ -265,6 +330,8 @@ export const maskSensitive = <T>(
|
|
|
265
330
|
for (const [key, nested] of Object.entries(masked)) {
|
|
266
331
|
if (isSensitive(key) || (oidcCallback && isOauthCallbackOnly(key))) {
|
|
267
332
|
masked[key] = REDACTED;
|
|
333
|
+
} else if (isDocument(key)) {
|
|
334
|
+
masked[key] = maskDocument(nested);
|
|
268
335
|
} else if (isPii(key) || isAmbiguousPii(key, nested)) {
|
|
269
336
|
masked[key] = maskPii(nested);
|
|
270
337
|
} else {
|
|
@@ -308,6 +375,8 @@ export const maskUrl = (url: string): string => {
|
|
|
308
375
|
for (const [key, value] of params) {
|
|
309
376
|
if (isSensitive(key) || isOauthCallbackOnly(key)) {
|
|
310
377
|
masked.append(key, REDACTED);
|
|
378
|
+
} else if (isDocument(key)) {
|
|
379
|
+
masked.append(key, String(maskDocument(value)));
|
|
311
380
|
} else if (isPii(key) || isAmbiguousPii(key, value)) {
|
|
312
381
|
masked.append(key, String(maskPii(value)));
|
|
313
382
|
} else {
|