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.
		
		
		
		
		
			
		
			
				
					
					
						
							86 lines
						
					
					
						
							2.4 KiB
						
					
					
				
			
		
		
	
	
							86 lines
						
					
					
						
							2.4 KiB
						
					
					
				'use strict'
 | 
						|
 | 
						|
const { groupRestore, nestedRestore } = require('./modifiers')
 | 
						|
 | 
						|
module.exports = restorer
 | 
						|
 | 
						|
function restorer ({ secret, wcLen }) {
 | 
						|
  return function compileRestore () {
 | 
						|
    if (this.restore) return
 | 
						|
    const paths = Object.keys(secret)
 | 
						|
    const resetters = resetTmpl(secret, paths)
 | 
						|
    const hasWildcards = wcLen > 0
 | 
						|
    const state = hasWildcards ? { secret, groupRestore, nestedRestore } : { secret }
 | 
						|
    /* eslint-disable-next-line */
 | 
						|
    this.restore = Function(
 | 
						|
      'o',
 | 
						|
      restoreTmpl(resetters, paths, hasWildcards)
 | 
						|
    ).bind(state)
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Mutates the original object to be censored by restoring its original values
 | 
						|
 * prior to censoring.
 | 
						|
 *
 | 
						|
 * @param {object} secret Compiled object describing which target fields should
 | 
						|
 * be censored and the field states.
 | 
						|
 * @param {string[]} paths The list of paths to censor as provided at
 | 
						|
 * initialization time.
 | 
						|
 *
 | 
						|
 * @returns {string} String of JavaScript to be used by `Function()`. The
 | 
						|
 * string compiles to the function that does the work in the description.
 | 
						|
 */
 | 
						|
function resetTmpl (secret, paths) {
 | 
						|
  return paths.map((path) => {
 | 
						|
    const { circle, escPath, leadingBracket } = secret[path]
 | 
						|
    const delim = leadingBracket ? '' : '.'
 | 
						|
    const reset = circle
 | 
						|
      ? `o.${circle} = secret[${escPath}].val`
 | 
						|
      : `o${delim}${path} = secret[${escPath}].val`
 | 
						|
    const clear = `secret[${escPath}].val = undefined`
 | 
						|
    return `
 | 
						|
      if (secret[${escPath}].val !== undefined) {
 | 
						|
        try { ${reset} } catch (e) {}
 | 
						|
        ${clear}
 | 
						|
      }
 | 
						|
    `
 | 
						|
  }).join('')
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Creates the body of the restore function
 | 
						|
 *
 | 
						|
 * Restoration of the redacted object happens
 | 
						|
 * backwards, in reverse order of redactions,
 | 
						|
 * so that repeated redactions on the same object
 | 
						|
 * property can be eventually rolled back to the
 | 
						|
 * original value.
 | 
						|
 *
 | 
						|
 * This way dynamic redactions are restored first,
 | 
						|
 * starting from the last one working backwards and
 | 
						|
 * followed by the static ones.
 | 
						|
 *
 | 
						|
 * @returns {string} the body of the restore function
 | 
						|
 */
 | 
						|
function restoreTmpl (resetters, paths, hasWildcards) {
 | 
						|
  const dynamicReset = hasWildcards === true ? `
 | 
						|
    const keys = Object.keys(secret)
 | 
						|
    const len = keys.length
 | 
						|
    for (var i = len - 1; i >= ${paths.length}; i--) {
 | 
						|
      const k = keys[i]
 | 
						|
      const o = secret[k]
 | 
						|
      if (o.flat === true) this.groupRestore(o)
 | 
						|
      else this.nestedRestore(o)
 | 
						|
      secret[k] = null
 | 
						|
    }
 | 
						|
  ` : ''
 | 
						|
 | 
						|
  return `
 | 
						|
    const secret = this.secret
 | 
						|
    ${dynamicReset}
 | 
						|
    ${resetters}
 | 
						|
    return o
 | 
						|
  `
 | 
						|
}
 |