@reldens/utils 0.52.0 → 0.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/events-manager.js +25 -4
- package/package.json +1 -1
- package/tests/events-manager-test.js +71 -44
- package/tests/run.js +8 -6
package/lib/events-manager.js
CHANGED
|
@@ -21,10 +21,11 @@ class EventsManager
|
|
|
21
21
|
this.maxEventKeyLength = 1000;
|
|
22
22
|
this.maxListeners = 10000;
|
|
23
23
|
this.maxEventArgs = 50;
|
|
24
|
-
this.sensitiveFields = ['password', 'token', 'secret', '
|
|
24
|
+
this.sensitiveFields = ['password', 'token', 'secret', 'auth', 'credential'];
|
|
25
25
|
this.hasLoggedMaxListeners = false;
|
|
26
26
|
this.symbolString = '--[[await-event-emitter]]--';
|
|
27
27
|
this.typeKeyName = sc.isFunction(Symbol) ? Symbol.for(this.symbolString) : this.symbolString;
|
|
28
|
+
this.enableSensitiveDataFiltering = false;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
assertType(type)
|
|
@@ -81,6 +82,9 @@ class EventsManager
|
|
|
81
82
|
Logger.warning('Event arguments exceed maximum: '+args.length);
|
|
82
83
|
return [];
|
|
83
84
|
}
|
|
85
|
+
if(!this.enableSensitiveDataFiltering){
|
|
86
|
+
return args;
|
|
87
|
+
}
|
|
84
88
|
return args.map(arg => {
|
|
85
89
|
if(sc.isObject(arg)){
|
|
86
90
|
return this.filterSensitiveData(arg);
|
|
@@ -89,11 +93,21 @@ class EventsManager
|
|
|
89
93
|
});
|
|
90
94
|
}
|
|
91
95
|
|
|
92
|
-
filterSensitiveData(obj)
|
|
96
|
+
filterSensitiveData(obj, visited = new WeakSet())
|
|
93
97
|
{
|
|
94
98
|
if(!sc.isObject(obj)){
|
|
95
99
|
return obj;
|
|
96
100
|
}
|
|
101
|
+
if(visited.has(obj)){
|
|
102
|
+
return '[CIRCULAR]';
|
|
103
|
+
}
|
|
104
|
+
if(obj instanceof Map || obj instanceof Set || obj instanceof Date || obj instanceof Array){
|
|
105
|
+
return obj;
|
|
106
|
+
}
|
|
107
|
+
if(Object.getPrototypeOf(obj) !== Object.prototype){
|
|
108
|
+
return obj;
|
|
109
|
+
}
|
|
110
|
+
visited.add(obj);
|
|
97
111
|
let filtered = {};
|
|
98
112
|
for(let key of Object.keys(obj)){
|
|
99
113
|
if(sc.hasDangerousKeys(null, key)){
|
|
@@ -107,11 +121,16 @@ class EventsManager
|
|
|
107
121
|
continue;
|
|
108
122
|
}
|
|
109
123
|
if(sc.isObject(obj[key])){
|
|
110
|
-
filtered[key] = this.filterSensitiveData(obj[key]);
|
|
124
|
+
filtered[key] = this.filterSensitiveData(obj[key], visited);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if(sc.isFunction(obj[key])) {
|
|
128
|
+
filtered[key] = obj[key];
|
|
111
129
|
continue;
|
|
112
130
|
}
|
|
113
131
|
filtered[key] = obj[key];
|
|
114
132
|
}
|
|
133
|
+
visited.delete(obj);
|
|
115
134
|
return filtered;
|
|
116
135
|
}
|
|
117
136
|
|
|
@@ -442,7 +461,9 @@ class EventsManager
|
|
|
442
461
|
}
|
|
443
462
|
let logMessage = type+' Event: '+key;
|
|
444
463
|
if(args && 0 < args.length){
|
|
445
|
-
let filteredArgs =
|
|
464
|
+
let filteredArgs = this.enableSensitiveDataFiltering
|
|
465
|
+
? args.map(arg => this.filterSensitiveData(arg))
|
|
466
|
+
: args;
|
|
446
467
|
logMessage += ' with '+filteredArgs.length+' arguments';
|
|
447
468
|
}
|
|
448
469
|
Logger.debug(logMessage);
|
package/package.json
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Reldens - TestEventsManager
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
1
7
|
const EventsManager = require('../lib/events-manager');
|
|
2
8
|
|
|
3
9
|
class TestEventsManager
|
|
@@ -8,6 +14,7 @@ class TestEventsManager
|
|
|
8
14
|
this.testResults = [];
|
|
9
15
|
this.testCount = 0;
|
|
10
16
|
this.passedCount = 0;
|
|
17
|
+
this.currentTestMethod = '';
|
|
11
18
|
}
|
|
12
19
|
|
|
13
20
|
test(name, testFn)
|
|
@@ -15,11 +22,13 @@ class TestEventsManager
|
|
|
15
22
|
this.testCount++;
|
|
16
23
|
try{
|
|
17
24
|
testFn();
|
|
18
|
-
|
|
25
|
+
let logMessage = '✓ PASS: '+this.currentTestMethod+' - '+name;
|
|
26
|
+
console.log(logMessage);
|
|
19
27
|
this.passedCount++;
|
|
20
28
|
this.testResults.push({name, status: 'PASS'});
|
|
21
29
|
} catch(error){
|
|
22
|
-
|
|
30
|
+
let logMessage = '✗ FAIL: '+this.currentTestMethod+' - '+name+' - '+error.message;
|
|
31
|
+
console.log(logMessage);
|
|
23
32
|
this.testResults.push({name, status: 'FAIL', error: error.message});
|
|
24
33
|
}
|
|
25
34
|
}
|
|
@@ -31,21 +40,23 @@ class TestEventsManager
|
|
|
31
40
|
}
|
|
32
41
|
}
|
|
33
42
|
|
|
34
|
-
runAllTests()
|
|
43
|
+
async runAllTests()
|
|
35
44
|
{
|
|
36
45
|
console.log('Running tests for EventsManager...\n');
|
|
37
|
-
|
|
38
46
|
let methodNames = Object.getOwnPropertyNames(Object.getPrototypeOf(this));
|
|
39
47
|
let testMethods = methodNames.filter(name =>
|
|
40
48
|
name.startsWith('test') &&
|
|
41
49
|
'function' === typeof this[name] &&
|
|
42
50
|
name !== 'test'
|
|
43
51
|
);
|
|
44
|
-
|
|
45
52
|
for(let methodName of testMethods){
|
|
46
|
-
this
|
|
53
|
+
this.currentTestMethod = methodName;
|
|
54
|
+
try{
|
|
55
|
+
await this[methodName]();
|
|
56
|
+
} catch(error){
|
|
57
|
+
console.error('Test method failed:', methodName, error.message);
|
|
58
|
+
}
|
|
47
59
|
}
|
|
48
|
-
|
|
49
60
|
this.printSummary();
|
|
50
61
|
}
|
|
51
62
|
|
|
@@ -289,16 +300,17 @@ class TestEventsManager
|
|
|
289
300
|
let loggedMessages = [];
|
|
290
301
|
let originalDebug = console.log;
|
|
291
302
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
303
|
+
try{
|
|
304
|
+
console.log = (...args) => loggedMessages.push(args.join(' '));
|
|
305
|
+
process.env.RELDENS_LOG_LEVEL = 8;
|
|
306
|
+
for(let i = 0; i < 10; i++){
|
|
307
|
+
emitter.on('test-max-'+i, () => {});
|
|
308
|
+
}
|
|
309
|
+
} finally{
|
|
310
|
+
console.log = originalDebug;
|
|
311
|
+
delete process.env.RELDENS_LOG_LEVEL;
|
|
297
312
|
}
|
|
298
313
|
|
|
299
|
-
console.log = originalDebug;
|
|
300
|
-
delete process.env.RELDENS_LOG_LEVEL;
|
|
301
|
-
|
|
302
314
|
let debugLogs = loggedMessages.filter(log => log.includes('High listener count detected'));
|
|
303
315
|
this.assert(1 === debugLogs.length, 'Should log high listener count only once');
|
|
304
316
|
this.assert(true === emitter.hasLoggedMaxListeners, 'Should set flag after logging');
|
|
@@ -498,14 +510,15 @@ class TestEventsManager
|
|
|
498
510
|
let loggedMessages = [];
|
|
499
511
|
let originalLog = console.log;
|
|
500
512
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
513
|
+
try{
|
|
514
|
+
console.log = (...args) => loggedMessages.push(args.join(' '));
|
|
515
|
+
process.env.RELDENS_LOG_LEVEL = 8;
|
|
516
|
+
let sensitiveArgs = [{password: 'secret', safe: 'data'}];
|
|
517
|
+
emitter.logDebugEvent('test', 'Fire', sensitiveArgs);
|
|
518
|
+
} finally{
|
|
519
|
+
console.log = originalLog;
|
|
520
|
+
delete process.env.RELDENS_LOG_LEVEL;
|
|
521
|
+
}
|
|
509
522
|
|
|
510
523
|
let debugLog = loggedMessages.find(log => log.includes('Fire Event: test'));
|
|
511
524
|
this.assert(debugLog, 'Should log debug event');
|
|
@@ -580,13 +593,14 @@ class TestEventsManager
|
|
|
580
593
|
|
|
581
594
|
let loggedMessages = [];
|
|
582
595
|
let originalLog = console.log;
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
596
|
+
try{
|
|
597
|
+
console.log = (...args) => loggedMessages.push(args.join(' '));
|
|
598
|
+
process.env.RELDENS_LOG_LEVEL = 8;
|
|
599
|
+
emitter.logDebugEvent('non-matching-key', 'Listen');
|
|
600
|
+
} finally{
|
|
601
|
+
console.log = originalLog;
|
|
602
|
+
delete process.env.RELDENS_LOG_LEVEL;
|
|
603
|
+
}
|
|
590
604
|
|
|
591
605
|
let debugLogs = loggedMessages.filter(log => log.includes('Listen Event:'));
|
|
592
606
|
this.assert(0 === debugLogs.length, 'Should not log when no pattern matches');
|
|
@@ -894,17 +908,16 @@ class TestEventsManager
|
|
|
894
908
|
let emitter = new EventsManager();
|
|
895
909
|
let loggedEvents = [];
|
|
896
910
|
let originalLog = console.log;
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
911
|
+
try{
|
|
912
|
+
console.log = (...args) => loggedEvents.push(args.join(' '));
|
|
913
|
+
process.env.RELDENS_LOG_LEVEL = 8;
|
|
914
|
+
emitter.debug = 'all';
|
|
915
|
+
emitter.on('debug-test', () => {});
|
|
916
|
+
await emitter.emit('debug-test');
|
|
917
|
+
} finally{
|
|
918
|
+
console.log = originalLog;
|
|
919
|
+
delete process.env.RELDENS_LOG_LEVEL;
|
|
920
|
+
}
|
|
908
921
|
let hasListenLog = loggedEvents.some(log => log.includes('Listen Event:'));
|
|
909
922
|
let hasFireLog = loggedEvents.some(log => log.includes('Fire Event:'));
|
|
910
923
|
this.assert(hasListenLog, 'Should log listen events');
|
|
@@ -1058,6 +1071,17 @@ class TestEventsManager
|
|
|
1058
1071
|
});
|
|
1059
1072
|
}
|
|
1060
1073
|
|
|
1074
|
+
testFilterSensitiveDataWithCircularReferences()
|
|
1075
|
+
{
|
|
1076
|
+
this.test('filterSensitiveData handles circular references', () => {
|
|
1077
|
+
let emitter = new EventsManager();
|
|
1078
|
+
let obj = {safe: 'data'};
|
|
1079
|
+
obj.circular = obj;
|
|
1080
|
+
let result = emitter.filterSensitiveData(obj);
|
|
1081
|
+
this.assert('[CIRCULAR]' === result.circular, 'Should handle circular refs');
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1061
1085
|
printSummary()
|
|
1062
1086
|
{
|
|
1063
1087
|
console.log('\n'+'='.repeat(50));
|
|
@@ -1067,7 +1091,6 @@ class TestEventsManager
|
|
|
1067
1091
|
console.log('Passed:', this.passedCount);
|
|
1068
1092
|
console.log('Failed:', this.testCount - this.passedCount);
|
|
1069
1093
|
console.log('Success rate:', Math.round((this.passedCount / this.testCount) * 100)+'%');
|
|
1070
|
-
|
|
1071
1094
|
if(this.testCount - this.passedCount > 0){
|
|
1072
1095
|
console.log('\nFailed tests:');
|
|
1073
1096
|
for(let result of this.testResults){
|
|
@@ -1076,9 +1099,13 @@ class TestEventsManager
|
|
|
1076
1099
|
}
|
|
1077
1100
|
}
|
|
1078
1101
|
}
|
|
1102
|
+
console.log('\n'+'='.repeat(60));
|
|
1103
|
+
if(this.testCount - this.passedCount === 0){
|
|
1104
|
+
console.log('All tests completed successfully!');
|
|
1105
|
+
}
|
|
1106
|
+
console.log('='.repeat(60));
|
|
1079
1107
|
}
|
|
1080
1108
|
|
|
1081
1109
|
}
|
|
1082
1110
|
|
|
1083
|
-
|
|
1084
|
-
testRunner.runAllTests();
|
|
1111
|
+
module.exports.TestEventsManager = TestEventsManager;
|
package/tests/run.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
console.log('Running all tests...\n');
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
async function runTests(){
|
|
4
4
|
console.log('='.repeat(60));
|
|
5
|
-
console.log('TESTING
|
|
5
|
+
console.log('TESTING IMPLEMENTATION');
|
|
6
6
|
console.log('='.repeat(60));
|
|
7
|
-
require('./events-manager-test.js');
|
|
7
|
+
const { TestEventsManager } = require('./events-manager-test.js');
|
|
8
|
+
let testInstance = new TestEventsManager();
|
|
9
|
+
await testInstance.runAllTests();
|
|
10
|
+
}
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
} catch(error){
|
|
12
|
+
runTests().catch(error => {
|
|
11
13
|
console.error('\nTest execution failed:', error.message);
|
|
12
14
|
process.exit(1);
|
|
13
|
-
}
|
|
15
|
+
});
|