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