const fs = require('fs'); const winston = require("winston"); const logger = winston.createLogger({ level: 'info', format: winston.format.combine( winston.format.timestamp(), winston.format.printf(info => { return `${info.timestamp} ${info.level}: ${info.message}`; }) ), transports: [ new winston.transports.Console(), new winston.transports.File({ filename: './log/RuleEngineError.log', level: 'error' }), new winston.transports.File({ filename: './log/Combined.log' }) ] }); exports.RuleEngine = class RuleEngine { constructor(ruleSetFileMask) { this.ruleSet = JSON.parse(fs.readFileSync('./rules/' + ruleSetFileMask + '.rule.json', 'utf8')); } processData(inputLine) { let inputData = inputLine.data; logger.log("debug", "ProcessingType " + inputLine.processingType + " RuleSet: " + this.ruleSet); let allWhiteFilterRules = this.ruleSet[inputLine.processingType].rules; if (this.processLogicOr(allWhiteFilterRules, inputData)) { return (true); } logger.log("debug", "No whitelisting matched; returning false"); return (false); } processLogicAnd(allWhiteFilterRules, inputData) { let retVal = true; logger.log("debug", "Logic AND - start"); for (let i = 0; i < allWhiteFilterRules.length; i++) { let theWhiteFilterRule = allWhiteFilterRules[i]; logger.log("debug", " Logic AND - whiteFilterRule: " + JSON.stringify(theWhiteFilterRule)); if (theWhiteFilterRule.Logic === "-") { if (!this.processLogicFlat(theWhiteFilterRule, inputData) && retVal === true) { logger.log("debug", " Logic AND - FLAT - Changing Result to false"); retVal = false; }; } else if (theWhiteFilterRule.Logic === "|") { if (!this.processLogicOr(theWhiteFilterRule.rules, inputData) && retVal === true) { logger.log("debug", " Logic AND - OR - Changing Result to false"); retVal = false; }; } else if (theWhiteFilterRule.Logic === "&") { if (!this.processLogicAnd(theWhiteFilterRule.rules, inputData) && retVal === true) { logger.log("debug", " Logic AND - AND - Changing Result to false"); retVal = false; }; } }; logger.log("debug", "Logic AND - end - result: " + retVal); return (retVal); } processLogicOr(allWhiteFilterRules, inputData) { logger.log("debug", "Logic OR - start"); for (let i = 0; i < allWhiteFilterRules.length; i++) { let theWhiteFilterRule = allWhiteFilterRules[i]; logger.log("debug", " Logic OR - whiteFilterRule: "+JSON.stringify(theWhiteFilterRule)); if (theWhiteFilterRule.Logic === "-") { if (this.processLogicFlat(theWhiteFilterRule, inputData)) { logger.log("debug", " Logic OR - FLAT - RETURNING OUT"); return (true); }; } else if (theWhiteFilterRule.Logic === "|") { if (this.processLogicOr(theWhiteFilterRule.rules, inputData)) { logger.log("debug", " Logic OR - OR - RETURNING OUT"); return (true) }; } else if (theWhiteFilterRule.Logic === "&") { if (this.processLogicAnd(theWhiteFilterRule.rules, inputData)) { logger.log("debug", " Logic OR - AND - RETURNING OUT"); return (true) }; } }; logger.log("debug", "Logic OR - end"); return(false); } processLogicFlat(theWhiteFilterRule, inputData) { logger.log("debug", "Logic FLAT start - whiteFilterRule: "+JSON.stringify(theWhiteFilterRule)); if (theWhiteFilterRule.Comp === "===") { if (inputData[theWhiteFilterRule.Field] === theWhiteFilterRule.Value) { logger.log("debug", "Logic FLAT - Exiting out"); return (true); } } else if (theWhiteFilterRule.Comp === "~") { logger.log("debug","RegexFilter: " + theWhiteFilterRule.Value + " || " + inputData[theWhiteFilterRule.Field]); let result = this.reTest(theWhiteFilterRule.Value, inputData[theWhiteFilterRule.Field]); if (result) { logger.log("debug", "Logic FLAT - Exiting out"); return (true); } } logger.log("debug", "Logic FLAT - end"); } reTest(regex, data) { let match = regex.match(new RegExp('^/(.*?)/([giumy]*)$')); regex = new RegExp(match[1], match[2]); return regex.test(data); } }