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)` | ||
|  | } |