Reputation: 1548
I have a function which loops over the keys of an object and looks for sensitive keys like email, key, password, apiKey, secrets, secret and userKey.
If it finds any that have a value, it redacts the value.
However, its failing sometimes with an error like:
"RangeError: Maximum call stack size exceeded"
Whats causing the endless recursion
??
const deepObjectRedactor = obj => {
const sensitiveKeys = [
'email',
'key',
'password',
'apiKey',
'secrets',
'secret',
'userKey'
];
Object.keys(obj).forEach(key => {
if (
sensitiveKeys.map(e => e.toLowerCase()).includes(key.toLowerCase()) &&
obj[key]
) {
obj[key] = '**********';
return;
}
if (obj[key] && typeof obj[key] === 'object') {
deepObjectRedactor(obj[key]);
}
});
};
// function invoking the redactor
const customRedactorFormat = info => {
if (info.message && typeof info.message === 'object') {
deepObjectRedactor(info.message);
}
return info;
});
Upvotes: 1
Views: 128
Reputation: 135187
You can write a generic map
that works for objects and arrays. And then write redact
as a specialization of map
-
function map (t, f)
{ switch (t?.constructor)
{ case Array:
return t.map((v, k) => f(k, map(v, f)))
case Object:
return Object.fromEntries(
Object.entries(t).map(([k, v]) => [k, f(k, map(v, f))])
)
default:
return t
}
}
const redact = (t, keys = new Set) =>
map(t, (k, v) => keys.has(k) ? "*****" : v)
const data =
[ { user: 1, cc: 1234, password: "foo" }
, { nested: [ { a: 1, pin: 999 }, { b: 2, pin: 333 } ] }
, { deeply: [ { nested: [ { user: 2, password: "here" } ] } ] }
]
console.log(redact(data, new Set(["cc", "password", "pin"])))
[
{
"user": 1,
"cc": "*****",
"password": "*****"
},
{
"nested": [
{
"a": 1,
"pin": "*****"
},
{
"b": 2,
"pin": "*****"
}
]
},
{
"deeply": [
{
"nested": [
{
"user": 2,
"password": "*****"
}
]
}
]
}
]
Upvotes: 1