1 | 'use strict'
|
2 |
|
3 | const fastRedact = require('fast-redact')
|
4 | const { redactFmtSym, wildcardFirstSym } = require('./symbols')
|
5 | const { rx, validator } = fastRedact
|
6 |
|
7 | const validate = validator({
|
8 | ERR_PATHS_MUST_BE_STRINGS: () => 'pino – redacted paths must be strings',
|
9 | ERR_INVALID_PATH: (s) => `pino – redact paths array contains an invalid path (${s})`
|
10 | })
|
11 |
|
12 | const CENSOR = '[Redacted]'
|
13 | const strict = false
|
14 |
|
15 | function redaction (opts, serialize) {
|
16 | const { paths, censor } = handle(opts)
|
17 |
|
18 | const shape = paths.reduce((o, str) => {
|
19 | rx.lastIndex = 0
|
20 | const first = rx.exec(str)
|
21 | const next = rx.exec(str)
|
22 |
|
23 |
|
24 | let ns = first[1] !== undefined
|
25 | ? first[1].replace(/^(?:"|'|`)(.*)(?:"|'|`)$/, '$1')
|
26 | : first[0]
|
27 |
|
28 | if (ns === '*') {
|
29 | ns = wildcardFirstSym
|
30 | }
|
31 |
|
32 |
|
33 | if (next === null) {
|
34 | o[ns] = null
|
35 | return o
|
36 | }
|
37 |
|
38 |
|
39 |
|
40 | if (o[ns] === null) {
|
41 | return o
|
42 | }
|
43 |
|
44 | const { index } = next
|
45 | const nextPath = `${str.substr(index, str.length - 1)}`
|
46 |
|
47 | o[ns] = o[ns] || []
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 | if (ns !== wildcardFirstSym && o[ns].length === 0) {
|
55 |
|
56 | o[ns].push(...(o[wildcardFirstSym] || []))
|
57 | }
|
58 |
|
59 | if (ns === wildcardFirstSym) {
|
60 |
|
61 | Object.keys(o).forEach(function (k) {
|
62 | if (o[k]) {
|
63 | o[k].push(nextPath)
|
64 | }
|
65 | })
|
66 | }
|
67 |
|
68 | o[ns].push(nextPath)
|
69 | return o
|
70 | }, {})
|
71 |
|
72 |
|
73 |
|
74 |
|
75 | const result = {
|
76 | [redactFmtSym]: fastRedact({ paths, censor, serialize, strict })
|
77 | }
|
78 |
|
79 | const topCensor = (...args) =>
|
80 | typeof censor === 'function' ? serialize(censor(...args)) : serialize(censor)
|
81 |
|
82 | return [...Object.keys(shape), ...Object.getOwnPropertySymbols(shape)].reduce((o, k) => {
|
83 |
|
84 | if (shape[k] === null) o[k] = topCensor
|
85 | else o[k] = fastRedact({ paths: shape[k], censor, serialize, strict })
|
86 | return o
|
87 | }, result)
|
88 | }
|
89 |
|
90 | function handle (opts) {
|
91 | if (Array.isArray(opts)) {
|
92 | opts = { paths: opts, censor: CENSOR }
|
93 | validate(opts)
|
94 | return opts
|
95 | }
|
96 | var { paths, censor = CENSOR, remove } = opts
|
97 | if (Array.isArray(paths) === false) { throw Error('pino – redact must contain an array of strings') }
|
98 | if (remove === true) censor = undefined
|
99 | validate({ paths, censor })
|
100 |
|
101 | return { paths, censor }
|
102 | }
|
103 |
|
104 | module.exports = redaction
|