First commit
This commit is contained in:
227
node_modules/@pinojs/redact/test/multiple-wildcards.test.js
generated
vendored
Normal file
227
node_modules/@pinojs/redact/test/multiple-wildcards.test.js
generated
vendored
Normal file
@@ -0,0 +1,227 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('node:test')
|
||||
const { strict: assert } = require('node:assert')
|
||||
const slowRedact = require('../index.js')
|
||||
|
||||
// Tests for Issue #2319: @pinojs/redact fails to redact patterns with 3+ consecutive wildcards
|
||||
test('three consecutive wildcards: *.*.*.password (4 levels deep)', () => {
|
||||
const obj = {
|
||||
simple: { password: 'secret-2-levels' },
|
||||
user: { auth: { password: 'secret-3-levels' } },
|
||||
nested: { deep: { auth: { password: 'secret-4-levels' } } }
|
||||
}
|
||||
|
||||
const redact = slowRedact({
|
||||
paths: ['*.*.*.password']
|
||||
})
|
||||
const result = redact(obj)
|
||||
const parsed = JSON.parse(result)
|
||||
|
||||
// Only the 4-level deep password should be redacted
|
||||
assert.strictEqual(parsed.simple.password, 'secret-2-levels', '2-level password should NOT be redacted')
|
||||
assert.strictEqual(parsed.user.auth.password, 'secret-3-levels', '3-level password should NOT be redacted')
|
||||
assert.strictEqual(parsed.nested.deep.auth.password, '[REDACTED]', '4-level password SHOULD be redacted')
|
||||
})
|
||||
|
||||
test('four consecutive wildcards: *.*.*.*.password (5 levels deep)', () => {
|
||||
const obj = {
|
||||
simple: { password: 'secret-2-levels' },
|
||||
user: { auth: { password: 'secret-3-levels' } },
|
||||
nested: { deep: { auth: { password: 'secret-4-levels' } } },
|
||||
config: { user: { auth: { settings: { password: 'secret-5-levels' } } } }
|
||||
}
|
||||
|
||||
const redact = slowRedact({
|
||||
paths: ['*.*.*.*.password']
|
||||
})
|
||||
const result = redact(obj)
|
||||
const parsed = JSON.parse(result)
|
||||
|
||||
// Only the 5-level deep password should be redacted
|
||||
assert.strictEqual(parsed.simple.password, 'secret-2-levels', '2-level password should NOT be redacted')
|
||||
assert.strictEqual(parsed.user.auth.password, 'secret-3-levels', '3-level password should NOT be redacted')
|
||||
assert.strictEqual(parsed.nested.deep.auth.password, 'secret-4-levels', '4-level password should NOT be redacted')
|
||||
assert.strictEqual(parsed.config.user.auth.settings.password, '[REDACTED]', '5-level password SHOULD be redacted')
|
||||
})
|
||||
|
||||
test('five consecutive wildcards: *.*.*.*.*.password (6 levels deep)', () => {
|
||||
const obj = {
|
||||
simple: { password: 'secret-2-levels' },
|
||||
user: { auth: { password: 'secret-3-levels' } },
|
||||
nested: { deep: { auth: { password: 'secret-4-levels' } } },
|
||||
config: { user: { auth: { settings: { password: 'secret-5-levels' } } } },
|
||||
data: {
|
||||
reqConfig: {
|
||||
data: {
|
||||
credentials: {
|
||||
settings: {
|
||||
password: 'secret-6-levels'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const redact = slowRedact({
|
||||
paths: ['*.*.*.*.*.password']
|
||||
})
|
||||
const result = redact(obj)
|
||||
const parsed = JSON.parse(result)
|
||||
|
||||
// Only the 6-level deep password should be redacted
|
||||
assert.strictEqual(parsed.simple.password, 'secret-2-levels', '2-level password should NOT be redacted')
|
||||
assert.strictEqual(parsed.user.auth.password, 'secret-3-levels', '3-level password should NOT be redacted')
|
||||
assert.strictEqual(parsed.nested.deep.auth.password, 'secret-4-levels', '4-level password should NOT be redacted')
|
||||
assert.strictEqual(parsed.config.user.auth.settings.password, 'secret-5-levels', '5-level password should NOT be redacted')
|
||||
assert.strictEqual(parsed.data.reqConfig.data.credentials.settings.password, '[REDACTED]', '6-level password SHOULD be redacted')
|
||||
})
|
||||
|
||||
test('three wildcards with censor function receives correct values', () => {
|
||||
const obj = {
|
||||
nested: { deep: { auth: { password: 'secret-value' } } }
|
||||
}
|
||||
|
||||
const censorCalls = []
|
||||
const redact = slowRedact({
|
||||
paths: ['*.*.*.password'],
|
||||
censor: (value, path) => {
|
||||
censorCalls.push({ value, path: [...path] })
|
||||
return '[REDACTED]'
|
||||
}
|
||||
})
|
||||
|
||||
const result = redact(obj)
|
||||
const parsed = JSON.parse(result)
|
||||
|
||||
// Should have been called exactly once with the correct value
|
||||
assert.strictEqual(censorCalls.length, 1, 'censor should be called once')
|
||||
assert.strictEqual(censorCalls[0].value, 'secret-value', 'censor should receive the actual value')
|
||||
assert.deepStrictEqual(censorCalls[0].path, ['nested', 'deep', 'auth', 'password'], 'censor should receive correct path')
|
||||
assert.strictEqual(parsed.nested.deep.auth.password, '[REDACTED]')
|
||||
})
|
||||
|
||||
test('three wildcards with multiple matches', () => {
|
||||
const obj = {
|
||||
api1: { v1: { auth: { token: 'token1' } } },
|
||||
api2: { v2: { auth: { token: 'token2' } } },
|
||||
api3: { v1: { auth: { token: 'token3' } } }
|
||||
}
|
||||
|
||||
const redact = slowRedact({
|
||||
paths: ['*.*.*.token']
|
||||
})
|
||||
const result = redact(obj)
|
||||
const parsed = JSON.parse(result)
|
||||
|
||||
// All three tokens should be redacted
|
||||
assert.strictEqual(parsed.api1.v1.auth.token, '[REDACTED]')
|
||||
assert.strictEqual(parsed.api2.v2.auth.token, '[REDACTED]')
|
||||
assert.strictEqual(parsed.api3.v1.auth.token, '[REDACTED]')
|
||||
})
|
||||
|
||||
test('three wildcards with remove option', () => {
|
||||
const obj = {
|
||||
nested: { deep: { auth: { password: 'secret', username: 'admin' } } }
|
||||
}
|
||||
|
||||
const redact = slowRedact({
|
||||
paths: ['*.*.*.password'],
|
||||
remove: true
|
||||
})
|
||||
const result = redact(obj)
|
||||
const parsed = JSON.parse(result)
|
||||
|
||||
// Password should be removed entirely
|
||||
assert.strictEqual('password' in parsed.nested.deep.auth, false, 'password key should be removed')
|
||||
assert.strictEqual(parsed.nested.deep.auth.username, 'admin', 'username should remain')
|
||||
})
|
||||
|
||||
test('mixed: two and three wildcards in same redactor', () => {
|
||||
const obj = {
|
||||
user: { auth: { password: 'secret-3-levels' } },
|
||||
config: { deep: { auth: { password: 'secret-4-levels' } } }
|
||||
}
|
||||
|
||||
const redact = slowRedact({
|
||||
paths: ['*.*.password', '*.*.*.password']
|
||||
})
|
||||
const result = redact(obj)
|
||||
const parsed = JSON.parse(result)
|
||||
|
||||
// Both should be redacted
|
||||
assert.strictEqual(parsed.user.auth.password, '[REDACTED]', '3-level should be redacted by *.*.password')
|
||||
assert.strictEqual(parsed.config.deep.auth.password, '[REDACTED]', '4-level should be redacted by *.*.*.password')
|
||||
})
|
||||
|
||||
test('three wildcards should not call censor for non-existent paths', () => {
|
||||
const obj = {
|
||||
shallow: { data: 'value' },
|
||||
nested: { deep: { auth: { password: 'secret' } } }
|
||||
}
|
||||
|
||||
let censorCallCount = 0
|
||||
const redact = slowRedact({
|
||||
paths: ['*.*.*.password'],
|
||||
censor: (value, path) => {
|
||||
censorCallCount++
|
||||
return '[REDACTED]'
|
||||
}
|
||||
})
|
||||
|
||||
redact(obj)
|
||||
|
||||
// Should only be called once for the path that exists
|
||||
assert.strictEqual(censorCallCount, 1, 'censor should only be called for existing paths')
|
||||
})
|
||||
|
||||
test('three wildcards with arrays', () => {
|
||||
const obj = {
|
||||
users: [
|
||||
{ auth: { password: 'secret1' } },
|
||||
{ auth: { password: 'secret2' } }
|
||||
]
|
||||
}
|
||||
|
||||
const redact = slowRedact({
|
||||
paths: ['*.*.*.password']
|
||||
})
|
||||
const result = redact(obj)
|
||||
const parsed = JSON.parse(result)
|
||||
|
||||
// Both passwords should be redacted (users[0].auth.password is 4 levels)
|
||||
assert.strictEqual(parsed.users[0].auth.password, '[REDACTED]')
|
||||
assert.strictEqual(parsed.users[1].auth.password, '[REDACTED]')
|
||||
})
|
||||
|
||||
test('four wildcards with authorization header (real-world case)', () => {
|
||||
const obj = {
|
||||
requests: {
|
||||
api1: {
|
||||
config: {
|
||||
headers: {
|
||||
authorization: 'Bearer secret-token'
|
||||
}
|
||||
}
|
||||
},
|
||||
api2: {
|
||||
config: {
|
||||
headers: {
|
||||
authorization: 'Bearer another-token'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const redact = slowRedact({
|
||||
paths: ['*.*.*.*.authorization']
|
||||
})
|
||||
const result = redact(obj)
|
||||
const parsed = JSON.parse(result)
|
||||
|
||||
// Both authorization headers should be redacted
|
||||
assert.strictEqual(parsed.requests.api1.config.headers.authorization, '[REDACTED]')
|
||||
assert.strictEqual(parsed.requests.api2.config.headers.authorization, '[REDACTED]')
|
||||
})
|
||||
Reference in New Issue
Block a user