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
			| 
								 
											3 years ago
										 
									 | 
							
								'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
							 | 
						||
| 
								 | 
							
								  `
							 | 
						||
| 
								 | 
							
								}
							 |