You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					100 lines
				
				3.0 KiB
			
		
		
			
		
	
	
					100 lines
				
				3.0 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'use strict'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const rx = require('./rx')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = redactor
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function redactor ({ secret, serialize, wcLen, strict, isCensorFct, censorFctTakesPath }, state) {
							 | 
						||
| 
								 | 
							
								  /* eslint-disable-next-line */
							 | 
						||
| 
								 | 
							
								  const redact = Function('o', `
							 | 
						||
| 
								 | 
							
								    if (typeof o !== 'object' || o == null) {
							 | 
						||
| 
								 | 
							
								      ${strictImpl(strict, serialize)}
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    const { censor, secret } = this
							 | 
						||
| 
								 | 
							
								    ${redactTmpl(secret, isCensorFct, censorFctTakesPath)}
							 | 
						||
| 
								 | 
							
								    this.compileRestore()
							 | 
						||
| 
								 | 
							
								    ${dynamicRedactTmpl(wcLen > 0, isCensorFct, censorFctTakesPath)}
							 | 
						||
| 
								 | 
							
								    ${resultTmpl(serialize)}
							 | 
						||
| 
								 | 
							
								  `).bind(state)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (serialize === false) {
							 | 
						||
| 
								 | 
							
								    redact.restore = (o) => state.restore(o)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return redact
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function redactTmpl (secret, isCensorFct, censorFctTakesPath) {
							 | 
						||
| 
								 | 
							
								  return Object.keys(secret).map((path) => {
							 | 
						||
| 
								 | 
							
								    const { escPath, leadingBracket, path: arrPath } = secret[path]
							 | 
						||
| 
								 | 
							
								    const skip = leadingBracket ? 1 : 0
							 | 
						||
| 
								 | 
							
								    const delim = leadingBracket ? '' : '.'
							 | 
						||
| 
								 | 
							
								    const hops = []
							 | 
						||
| 
								 | 
							
								    var match
							 | 
						||
| 
								 | 
							
								    while ((match = rx.exec(path)) !== null) {
							 | 
						||
| 
								 | 
							
								      const [ , ix ] = match
							 | 
						||
| 
								 | 
							
								      const { index, input } = match
							 | 
						||
| 
								 | 
							
								      if (index > skip) hops.push(input.substring(0, index - (ix ? 0 : 1)))
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    var existence = hops.map((p) => `o${delim}${p}`).join(' && ')
							 | 
						||
| 
								 | 
							
								    if (existence.length === 0) existence += `o${delim}${path} != null`
							 | 
						||
| 
								 | 
							
								    else existence += ` && o${delim}${path} != null`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const circularDetection = `
							 | 
						||
| 
								 | 
							
								      switch (true) {
							 | 
						||
| 
								 | 
							
								        ${hops.reverse().map((p) => `
							 | 
						||
| 
								 | 
							
								          case o${delim}${p} === censor:
							 | 
						||
| 
								 | 
							
								            secret[${escPath}].circle = ${JSON.stringify(p)}
							 | 
						||
| 
								 | 
							
								            break
							 | 
						||
| 
								 | 
							
								        `).join('\n')}
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    `
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const censorArgs = censorFctTakesPath
							 | 
						||
| 
								 | 
							
								      ? `val, ${JSON.stringify(arrPath)}`
							 | 
						||
| 
								 | 
							
								      : `val`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return `
							 | 
						||
| 
								 | 
							
								      if (${existence}) {
							 | 
						||
| 
								 | 
							
								        const val = o${delim}${path}
							 | 
						||
| 
								 | 
							
								        if (val === censor) {
							 | 
						||
| 
								 | 
							
								          secret[${escPath}].precensored = true
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								          secret[${escPath}].val = val
							 | 
						||
| 
								 | 
							
								          o${delim}${path} = ${isCensorFct ? `censor(${censorArgs})` : 'censor'}
							 | 
						||
| 
								 | 
							
								          ${circularDetection}
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    `
							 | 
						||
| 
								 | 
							
								  }).join('\n')
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function dynamicRedactTmpl (hasWildcards, isCensorFct, censorFctTakesPath) {
							 | 
						||
| 
								 | 
							
								  return hasWildcards === true ? `
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      const { wildcards, wcLen, groupRedact, nestedRedact } = this
							 | 
						||
| 
								 | 
							
								      for (var i = 0; i < wcLen; i++) {
							 | 
						||
| 
								 | 
							
								        const { before, beforeStr, after, nested } = wildcards[i]
							 | 
						||
| 
								 | 
							
								        if (nested === true) {
							 | 
						||
| 
								 | 
							
								          secret[beforeStr] = secret[beforeStr] || []
							 | 
						||
| 
								 | 
							
								          nestedRedact(secret[beforeStr], o, before, after, censor, ${isCensorFct}, ${censorFctTakesPath})
							 | 
						||
| 
								 | 
							
								        } else secret[beforeStr] = groupRedact(o, before, censor, ${isCensorFct}, ${censorFctTakesPath})
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  ` : ''
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function resultTmpl (serialize) {
							 | 
						||
| 
								 | 
							
								  return serialize === false ? `return o` : `
							 | 
						||
| 
								 | 
							
								    var s = this.serialize(o)
							 | 
						||
| 
								 | 
							
								    this.restore(o)
							 | 
						||
| 
								 | 
							
								    return s
							 | 
						||
| 
								 | 
							
								  `
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function strictImpl (strict, serialize) {
							 | 
						||
| 
								 | 
							
								  return strict === true
							 | 
						||
| 
								 | 
							
								    ? `throw Error('fast-redact: primitives cannot be redacted')`
							 | 
						||
| 
								 | 
							
								    : serialize === false ? `return o` : `return this.serialize(o)`
							 | 
						||
| 
								 | 
							
								}
							 |