logger.js 3.3 KB

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