logger.js 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /* global test:false, expect:false, describe:false, beforeAll:false, */
  2. const chalk = require('chalk')
  3. const logger = require('../../src/server/logger')
  4. const maskables = ['ToBeMasked1', 'toBeMasked2', 'toBeMasked(And)?Escaped']
  5. function captureConsoleLog (log) {
  6. let loggedMessage = null
  7. // override the default console.log to capture the logged message
  8. const defaultConsoleLog = console.log
  9. try {
  10. console.log = (logPrefix, message) => {
  11. loggedMessage = message
  12. defaultConsoleLog(logPrefix, message)
  13. }
  14. } finally {
  15. log()
  16. // restore the default console.log before using "expect" to avoid weird log behaviors
  17. console.log = defaultConsoleLog
  18. }
  19. return loggedMessage
  20. }
  21. describe('Test Logger secret mask', () => {
  22. beforeAll(() => {
  23. logger.setMaskables(maskables)
  24. })
  25. test('masks secret values present in log.info messages', () => {
  26. const loggedMessage = captureConsoleLog(() => {
  27. logger.info('this info has ToBeMasked1 and toBeMasked2 and case-insensitive TOBEMasKED2')
  28. })
  29. const exptectedMsg = 'this info has ****** and ****** and case-insensitive ******'
  30. expect(loggedMessage).toBeTruthy()
  31. expect(loggedMessage).toBe(exptectedMsg)
  32. })
  33. test('masks secret values present in log.warn messages', () => {
  34. const loggedMessage = captureConsoleLog(() => {
  35. logger.warn('this warning has ToBeMasked1 and toBeMasked2 and case-insensitive TOBEMasKED2')
  36. })
  37. const exptectedMsg = chalk.bold.yellow('this warning has ****** and ****** and case-insensitive ******')
  38. expect(loggedMessage).toBeTruthy()
  39. expect(loggedMessage).toBe(exptectedMsg)
  40. })
  41. test('masks secret values present in log.error messages', () => {
  42. const loggedMessage = captureConsoleLog(() => {
  43. logger.error(new Error('this error has ToBeMasked1 and toBeMasked2 and case-insensitive TOBEMasKED2'))
  44. })
  45. const exptectedMsg = chalk.bold.red('Error: this error has ****** and ****** and case-insensitive ******')
  46. expect(loggedMessage).toBeTruthy()
  47. expect(loggedMessage).toBe(exptectedMsg)
  48. })
  49. test('masks secret values present in log.error stack trace', () => {
  50. const loggedMessage = captureConsoleLog(() => {
  51. const err = new Error('this error has ToBeMasked1 and toBeMasked2 and case-insensitive TOBEMasKED2')
  52. logger.error(err, '', '', true)
  53. })
  54. const exptectedMsg = chalk.bold.red('Error: this error has ****** and ****** and case-insensitive ******')
  55. expect(loggedMessage).toBeTruthy()
  56. expect(loggedMessage.startsWith(exptectedMsg)).toBe(true)
  57. expect(loggedMessage.includes('ToBeMasked1')).toBe(false)
  58. expect(loggedMessage.includes('toBeMasked2')).toBe(false)
  59. expect(loggedMessage.includes('TOBEMasKED2')).toBe(false)
  60. })
  61. test('escape regex characters from secret values before masking them', () => {
  62. const loggedMessage = captureConsoleLog(() => {
  63. logger.warn('this warning has ToBeMasked(And)?Escaped but not toBeMaskedEscaped ')
  64. })
  65. const exptectedMsg = chalk.bold.yellow('this warning has ****** but not toBeMaskedEscaped ')
  66. expect(loggedMessage).toBeTruthy()
  67. expect(loggedMessage).toBe(exptectedMsg)
  68. })
  69. test('masks inside object', () => {
  70. const loggedMessage = captureConsoleLog(() => {
  71. logger.warn({ a: 1, deep: { secret: 'there is a ToBeMasked1 hiding here' } })
  72. })
  73. expect(loggedMessage).toBeTruthy()
  74. expect(!maskables.some((maskable) => loggedMessage.includes(maskable))).toBeTruthy()
  75. })
  76. })