fast-redact
Advanced tools
Comparing version 1.3.0 to 1.4.0
@@ -14,2 +14,4 @@ 'use strict' | ||
const redactStaticMatchWildOutcome = fastRedact({ paths: ['a.b.c', 'a.d.a', 'a.d.b', 'a.d.c'] }) | ||
const noirCensorFunction = require('pino-noir')(['a.b.*'], (v) => v + '.') | ||
const redactCensorFunction = fastRedact({ paths: ['a.b.*'], censor: (v) => v + '.', serialize: false }) | ||
@@ -132,2 +134,14 @@ const obj = { | ||
setImmediate(cb) | ||
}, | ||
function benchNoirV2CensorFunction (cb) { | ||
for (var i = 0; i < max; i++) { | ||
noirCensorFunction.a(obj.a) | ||
} | ||
setImmediate(cb) | ||
}, | ||
function benchFastRedactCensorFunction (cb) { | ||
for (var i = 0; i < max; i++) { | ||
redactCensorFunction(obj) | ||
} | ||
setImmediate(cb) | ||
} | ||
@@ -134,0 +148,0 @@ ], 500) |
@@ -34,2 +34,4 @@ 'use strict' | ||
const isCensorFct = typeof censor === 'function' | ||
if (paths.length === 0) return serialize || noop | ||
@@ -44,3 +46,3 @@ | ||
return redactor({ secret, wcLen, serialize, strict }, state({ | ||
return redactor({ secret, wcLen, serialize, strict, isCensorFct }, state({ | ||
secret, | ||
@@ -47,0 +49,0 @@ censor, |
@@ -19,3 +19,3 @@ 'use strict' | ||
function groupRedact (o, path, censor) { | ||
function groupRedact (o, path, censor, isCensorFct) { | ||
const target = get(o, path) | ||
@@ -29,3 +29,3 @@ if (target == null) return { keys: null, values: null, target: null, flat: true } | ||
values[i] = target[k] | ||
target[k] = censor | ||
target[k] = isCensorFct ? censor(target[k]) : censor | ||
} | ||
@@ -43,3 +43,3 @@ return { keys, values, target, flat: true } | ||
function nestedRedact (store, o, path, ns, censor) { | ||
function nestedRedact (store, o, path, ns, censor, isCensorFct) { | ||
const target = get(o, path) | ||
@@ -51,3 +51,3 @@ if (target == null) return | ||
const key = keys[i] | ||
const { value, parent, exists } = specialSet(target, key, ns, censor) | ||
const { value, parent, exists } = specialSet(target, key, ns, censor, isCensorFct) | ||
@@ -65,3 +65,3 @@ if (exists === true && parent !== null) { | ||
function specialSet (o, k, p, v) { | ||
function specialSet (o, k, p, v, f) { | ||
var i = -1 | ||
@@ -79,3 +79,2 @@ var l = p.length | ||
k = p[i] | ||
nv = v | ||
oov = ov | ||
@@ -87,2 +86,3 @@ if (!(k in n)) { | ||
ov = n[k] | ||
nv = f ? v(ov) : v | ||
nv = (i !== li) ? ov : nv | ||
@@ -89,0 +89,0 @@ n[k] = (has(n, k) && nv === ov) || (nv === undefined && v !== undefined) ? n[k] : nv |
@@ -7,3 +7,3 @@ 'use strict' | ||
function redactor ({ secret, serialize, wcLen, strict }, state) { | ||
function redactor ({ secret, serialize, wcLen, strict, isCensorFct }, state) { | ||
/* eslint-disable-next-line */ | ||
@@ -15,5 +15,5 @@ const redact = Function('o', ` | ||
const { censor, secret } = this | ||
${redactTmpl(secret)} | ||
${redactTmpl(secret, isCensorFct)} | ||
this.compileRestore() | ||
${dynamicRedactTmpl(wcLen > 0)} | ||
${dynamicRedactTmpl(wcLen > 0, isCensorFct)} | ||
${resultTmpl(serialize)} | ||
@@ -29,3 +29,3 @@ `).bind(state) | ||
function redactTmpl (secret) { | ||
function redactTmpl (secret, isCensorFct) { | ||
return Object.keys(secret).map((path) => { | ||
@@ -62,3 +62,3 @@ const { escPath, leadingBracket } = secret[path] | ||
secret[${escPath}].val = val | ||
o${delim}${path} = censor | ||
o${delim}${path} = ${isCensorFct ? 'censor(val)' : 'censor'} | ||
${circularDetection} | ||
@@ -71,3 +71,3 @@ } | ||
function dynamicRedactTmpl (hasWildcards) { | ||
function dynamicRedactTmpl (hasWildcards, isCensorFct) { | ||
return hasWildcards === true ? ` | ||
@@ -80,4 +80,4 @@ { | ||
secret[beforeStr] = secret[beforeStr] || [] | ||
nestedRedact(secret[beforeStr], o, before, after, censor) | ||
} else secret[beforeStr] = groupRedact(o, before, censor) | ||
nestedRedact(secret[beforeStr], o, before, after, censor, ${isCensorFct}) | ||
} else secret[beforeStr] = groupRedact(o, before, censor, ${isCensorFct}) | ||
} | ||
@@ -84,0 +84,0 @@ } |
@@ -9,2 +9,3 @@ 'use strict' | ||
censor, | ||
isCensorFct, | ||
compileRestore, | ||
@@ -17,3 +18,3 @@ serialize, | ||
} = o | ||
const builder = [{ secret, censor, compileRestore }] | ||
const builder = [{ secret, censor, isCensorFct, compileRestore }] | ||
builder.push({ secret }) | ||
@@ -20,0 +21,0 @@ if (serialize !== false) builder.push({ serialize }) |
@@ -9,3 +9,2 @@ 'use strict' | ||
const { | ||
ERR_CENSOR_MUST_NOT_BE_FUNCTION = () => 'fast-redact – censor may not be a function', | ||
ERR_PATHS_MUST_BE_STRINGS = () => 'fast-redact - Paths must be strings', | ||
@@ -15,6 +14,3 @@ ERR_INVALID_PATH = (s) => `fast-redact – Invalid path (${s})` | ||
return function validate ({ paths, serialize, censor }) { | ||
if (typeof censor === 'function') { | ||
throw Error(ERR_CENSOR_MUST_NOT_BE_FUNCTION()) | ||
} | ||
return function validate ({ paths }) { | ||
paths.forEach((s) => { | ||
@@ -21,0 +17,0 @@ if (typeof s !== 'string') { |
{ | ||
"name": "fast-redact", | ||
"version": "1.3.0", | ||
"version": "1.4.0", | ||
"description": "very fast object redaction", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -104,6 +104,5 @@ # fast-redact | ||
#### `censor` – `<Any type - Except Function>` – `('[REDACTED]')` | ||
#### `censor` – `<Any type>` – `('[REDACTED]')` | ||
This is the value which overwrites redacted properties. It can be any type, | ||
except a function. | ||
This is the value which overwrites redacted properties. | ||
@@ -114,4 +113,5 @@ Setting `censor` to `undefined` will cause properties to removed as long as this is | ||
Supplying a function as a `censor` will cause `fast-redact` to throw. This means | ||
a function censor to be introduced in the future without it being a breaking change. | ||
Setting `censor` to a function will cause `fast-redact` to invoke it with the original | ||
value. The output of the `censor` function sets the redacted value. | ||
Please note that asynchronous functions are not supported. | ||
@@ -280,2 +280,2 @@ #### `serialize` – `Function | Boolean` – `(JSON.stringify)` | ||
Sponsored by [nearForm](http://www.nearform.com) | ||
Sponsored by [nearForm](http://www.nearform.com) |
@@ -7,2 +7,3 @@ 'use strict' | ||
const censor = '[REDACTED]' | ||
const censorFct = value => !value ? value : 'xxx' + value.substr(-2) | ||
@@ -199,2 +200,32 @@ test('returns no-op when passed no paths [serialize: false]', ({ end, doesNotThrow }) => { | ||
test('masks according to supplied censor function', ({ end, is }) => { | ||
const redact = fastRedact({ paths: ['a'], censor: censorFct, serialize: false }) | ||
is(redact({ a: '0123456' }).a, 'xxx56') | ||
end() | ||
}) | ||
test('masks according to supplied censor function with wildcards', ({ end, is }) => { | ||
const redact = fastRedact({ paths: '*', censor: censorFct, serialize: false }) | ||
is(redact({ a: '0123456' }).a, 'xxx56') | ||
end() | ||
}) | ||
test('masks according to supplied censor function with nested wildcards', ({ end, is }) => { | ||
const redact = fastRedact({ paths: ['*.b'], censor: censorFct, serialize: false }) | ||
is(redact({ a: { b: '0123456' } }).a.b, 'xxx56') | ||
is(redact({ c: { b: '0123456', d: 'pristine' } }).c.b, 'xxx56') | ||
is(redact({ c: { b: '0123456', d: 'pristine' } }).c.d, 'pristine') | ||
end() | ||
}) | ||
test('redact.restore function places original values back in place with censor function', ({ end, is }) => { | ||
const redact = fastRedact({ paths: ['a'], censor: censorFct, serialize: false }) | ||
const o = { a: 'qwerty' } | ||
redact(o) | ||
is(o.a, 'xxxty') | ||
redact.restore(o) | ||
is(o.a, 'qwerty') | ||
end() | ||
}) | ||
test('serializes with JSON.stringify by default', ({ end, is }) => { | ||
@@ -253,3 +284,3 @@ const redact = fastRedact({ paths: ['a'] }) | ||
test('censor may be any type, except function which will throw', ({ end, same, throws }) => { | ||
test('censor may be any type, including function', ({ end, same }) => { | ||
const redactToString = fastRedact({ paths: ['a.b.c', 'a.b.d.*'], censor: 'censor', serialize: false }) | ||
@@ -266,2 +297,3 @@ const redactToUndefined = fastRedact({ paths: ['a.b.c', 'a.b.d.*'], censor: undefined, serialize: false }) | ||
const redactToError = fastRedact({ paths: ['a.b.c', 'a.b.d.*'], censor: Error('redacted'), serialize: false }) | ||
const redactToFunction = fastRedact({ paths: ['a.b.c', 'a.b.d.*'], censor: () => 'redacted', serialize: false }) | ||
same(redactToString({ a: { b: { c: 's', d: { x: 's', y: 's' } } } }), { a: { b: { c: 'censor', d: { x: 'censor', y: 'censor' } } } }) | ||
@@ -277,3 +309,3 @@ same(redactToUndefined({ a: { b: { c: 's', d: { x: 's', y: 's' } } } }), { a: { b: { c: undefined, d: { x: undefined, y: undefined } } } }) | ||
same(redactToError({ a: { b: { c: 's', d: { x: 's', y: 's' } } } }), { a: { b: { c: Error('redacted'), d: { x: Error('redacted'), y: Error('redacted') } } } }) | ||
throws(() => fastRedact({ paths: ['a.b.c', 'a.b.d.*'], censor: () => {}, serialize: false })) | ||
same(redactToFunction({ a: { b: { c: 's', d: { x: 's', y: 's' } } } }), { a: { b: { c: 'redacted', d: { x: 'redacted', y: 'redacted' } } } }) | ||
end() | ||
@@ -843,3 +875,3 @@ }) | ||
const redact = fastRedact({ paths: ['foo.bar'], strict: false }) | ||
const o = { bar: undefined } | ||
const o = { bar: undefined } | ||
is(redact({ foo: o }), '{"foo":{}}') | ||
@@ -846,0 +878,0 @@ is(o.hasOwnProperty('bar'), true) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
179717
37
1828
279