46 lines
1.6 KiB
JavaScript
46 lines
1.6 KiB
JavaScript
|
|
'use strict';
|
||
|
|
|
||
|
|
// The logger must never let secrets/PII reach the output. These tests pin the
|
||
|
|
// redaction contract for a financial app.
|
||
|
|
const test = require('node:test');
|
||
|
|
const assert = require('node:assert/strict');
|
||
|
|
|
||
|
|
const { redact } = require('../utils/logger.cts');
|
||
|
|
|
||
|
|
test('masks sensitive object keys at any depth', () => {
|
||
|
|
const out = redact({
|
||
|
|
username: 'alice',
|
||
|
|
password: 'hunter2',
|
||
|
|
totp_secret: 'JBSWY3DPEHPK3PXP',
|
||
|
|
nested: { access_token: 'abc123', client_secret: 'shh', keep: 'visible' },
|
||
|
|
encrypted_secret: 'e2:deadbeef',
|
||
|
|
});
|
||
|
|
assert.equal(out.username, 'alice');
|
||
|
|
assert.equal(out.password, '«redacted»');
|
||
|
|
assert.equal(out.totp_secret, '«redacted»');
|
||
|
|
assert.equal(out.nested.access_token, '«redacted»');
|
||
|
|
assert.equal(out.nested.client_secret, '«redacted»');
|
||
|
|
assert.equal(out.nested.keep, 'visible');
|
||
|
|
assert.equal(out.encrypted_secret, '«redacted»');
|
||
|
|
});
|
||
|
|
|
||
|
|
test('masks bearer tokens and JWTs inside strings', () => {
|
||
|
|
assert.match(redact('Authorization: Bearer abcdef.ghijk.lmnop'), /«redacted»/);
|
||
|
|
assert.match(
|
||
|
|
redact('token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.payloadpayloadpayload.sig'),
|
||
|
|
/«redacted»/,
|
||
|
|
);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('leaves normal values (ids, amounts, names) untouched', () => {
|
||
|
|
const out = redact({ id: 42, amount_cents: 12345, name: 'Electric Company', active: true });
|
||
|
|
assert.deepEqual(out, { id: 42, amount_cents: 12345, name: 'Electric Company', active: true });
|
||
|
|
});
|
||
|
|
|
||
|
|
test('Error becomes its stack/message string', () => {
|
||
|
|
const e = new Error('boom');
|
||
|
|
const out = redact(e);
|
||
|
|
assert.equal(typeof out, 'string');
|
||
|
|
assert.match(out, /boom/);
|
||
|
|
});
|