From 2a31ba1103cd198349842e6e33ea86da823751bf Mon Sep 17 00:00:00 2001
From: Dominik Sigmund <dominik.sigmund@br.de>
Date: Mon, 11 Jul 2022 12:11:31 +0200
Subject: [PATCH] Added Secure shoow option

---
 README.md     | 24 +++++++++++++++++++++---
 index.js      | 27 +++++++++++++++++++++++++--
 index.test.js | 15 +++++++++++++--
 3 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/README.md b/README.md
index 2b27265..a7a9ca8 100755
--- a/README.md
+++ b/README.md
@@ -23,10 +23,28 @@ It reads from the following sources, performing a deep merge:
 Enviroment Variables can target deep nested settings:  
 The Setting _setting.deep.key_ can be reached with *SETTING_DEEP_KEY*
 
-You may use the function _reload()_ to reload the config from all sources.  
-`config.reload()``
+You may use the function __reload()_ to reload the config from all sources.  
+`config._reload()``
 
-This makes *reload* a reserved keyword
+This makes *_reload* a reserved keyword
+
+You may use the function __show()_ to display the config without:
+
+- password
+- secret
+- token
+- key
+- apiKey
+- apiToken
+- apiSecret
+- user
+- username
+
+Values will be replaced with the value "redacted"
+
+`config._show()``
+
+This makes *_show* a reserved keyword
 
 If you give a basePath, the config-Files are used from there.  
 Else the main dir of the application will be used.
diff --git a/index.js b/index.js
index 5fdb2be..a5d37ae 100755
--- a/index.js
+++ b/index.js
@@ -42,7 +42,7 @@ module.exports = function(basePath = undefined) {
     return schema[pList[len-1]]
   }
 
-  config.reload = function () {
+  config._reload = function () {
     try {
       fs.accessSync(configDefaults)
       config = merge(this, JSON.parse(fs.readFileSync(configDefaults, 'utf8')))
@@ -78,6 +78,29 @@ module.exports = function(basePath = undefined) {
       }
     }
   }
-  config.reload()
+  config._show = function () {
+    // clone the config object
+    let config = JSON.parse(JSON.stringify(this))
+    // remove _reload
+    delete config._reload
+    // remove _show
+    delete config._show
+    // remove _set
+    delete config._set
+    // remove _get
+    delete config._get
+    // redact all nested objects where the key is 
+    // 'password' or 'secret' or 'token' or 'key' or 'apiKey' or 'apiToken' or 'apiSecret'
+    // or 'user' or 'username'
+    let keys = objectDeepKeys(config)
+    for (let index = 0; index < keys.length; index++) {
+      const element = keys[index]
+      if (element.toLowerCase().includes('password') || element.toLowerCase().includes('secret') || element.toLowerCase().includes('token') || element.toLowerCase().includes('key') || element.toLowerCase().includes('apikey') || element.toLowerCase().includes('apitoken') || element.toLowerCase().includes('apisecret') || element.toLowerCase().includes('user') || element.toLowerCase().includes('username')) {
+        set(config, element, 'REDACTED')
+      }
+    }
+    return config
+  }
+  config._reload()
   return config
 }
\ No newline at end of file
diff --git a/index.test.js b/index.test.js
index cb18c57..f2905a2 100755
--- a/index.test.js
+++ b/index.test.js
@@ -119,7 +119,7 @@ describe('config', function() {
     expect(config.setting).toBe('file:file.txt')
   })
 
-  it('should reload if asked', async function() {
+  it('should _reload if asked', async function() {
     await fs.writeFile('config.defaults.json', JSON.stringify(jsonDefaults))
     await fs.writeFile('config.json', JSON.stringify(jsonLocals))
 
@@ -130,7 +130,7 @@ describe('config', function() {
     jsonLocals.setting = 'reloaded-value'
     await fs.writeFile('config.json', JSON.stringify(jsonLocals))
 
-    config.reload()
+    config._reload()
 
     await fs.unlink('config.json')
     await fs.unlink('config.defaults.json')
@@ -138,4 +138,15 @@ describe('config', function() {
 
     expect(config.setting).toBe('reloaded-value')
   })
+  it('should redact passwords if using _show', async function() {
+    await fs.writeFile('config.defaults.json', JSON.stringify(jsonDefaults))
+    await fs.writeFile('config.json', JSON.stringify(jsonLocals))
+
+    let config = new Config()
+
+    await fs.unlink('config.json')
+    await fs.unlink('config.defaults.json')
+    console.dir(config._show())
+    expect(config._show().even.deeper.key).toBe('REDACTED')
+  })
 })
-- 
GitLab