From e08922a19e6ad6c4a9ed423d89f871ae07e9e02f Mon Sep 17 00:00:00 2001 From: Sefinek Date: Thu, 5 Sep 2024 19:13:02 +0200 Subject: [PATCH] Update (not finished yet) --- scripts/csv.js | 36 +++++++++++++++++++++++------------- scripts/sefinekAPI.js | 25 ++++++++++++++++++------- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/scripts/csv.js b/scripts/csv.js index 78bf9c9..5eb0405 100644 --- a/scripts/csv.js +++ b/scripts/csv.js @@ -17,15 +17,13 @@ const checkCSVSize = () => { }; const escapeCSVValue = value => { - if (typeof value === 'string' && value.includes(',')) { - return `"${value.replace(/"/g, '""')}"`; - } - return value; + if (typeof value === 'string' && value.includes(',')) return `"${value.replace(/"/g, '""')}"`; + return value || ''; }; const logToCSV = (rayId, ip, hostname, endpoint, useragent, action, country, sefinekAPI) => { checkCSVSize(); - const logLine = `${new Date().toISOString()},${rayId},${ip},${hostname},${escapeCSVValue(endpoint)},${escapeCSVValue(useragent || '')},${action},${country},${sefinekAPI || false}`; + const logLine = `${new Date().toISOString()},${rayId},${ip},${hostname},${escapeCSVValue(endpoint)},${escapeCSVValue(useragent)},${action},${country || 'N/A'},${sefinekAPI || false}`; fs.appendFileSync(CSV_FILE_PATH, logLine + '\n'); }; @@ -38,9 +36,22 @@ const readReportedIPs = () => { .slice(1) .filter(line => line.trim() !== '') .map(line => { - const [timestamp, rayId, ip, hostname, endpoint, useragent, action, country, sefinekAPI] = line.split(','); - return { timestamp: new Date(timestamp), rayId, ip, hostname, endpoint, useragent, action, country, sefinekAPI }; - }); + const parts = line.match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g); + if (!parts || parts.length < 9) return null; + + return { + timestamp: new Date(parts[0]), + rayId: parts[1], + ip: parts[2], + hostname: parts[3], + endpoint: parts[4], + useragent: parts[5], + action: parts[6], + country: parts[7], + sefinekAPI: parts[8] + }; + }) + .filter(item => item !== null); }; const updateSefinekAPIInCSV = (rayId, reportedToSefinekAPI) => { @@ -53,11 +64,10 @@ const updateSefinekAPIInCSV = (rayId, reportedToSefinekAPI) => { const lines = content.split('\n'); const updatedLines = lines.map(line => { - if (line.includes(rayId)) { - const [timestamp, rayIdExisting, ip, hostname, endpoint, useragent, action, country] = line.split(','); - if (rayIdExisting === rayId) { - return `${timestamp},${rayId},${ip},${hostname},${escapeCSVValue(endpoint)},${escapeCSVValue(useragent)},${action},${country},${reportedToSefinekAPI}`; - } + const parts = line.split(/,(?=(?:[^"]*"[^"]*")*[^"]*$)/g); + if (parts.length >= 9 && parts[1] === rayId) { + parts[8] = reportedToSefinekAPI; + return parts.join(','); } return line; }); diff --git a/scripts/sefinekAPI.js b/scripts/sefinekAPI.js index 238dc6a..de26b36 100644 --- a/scripts/sefinekAPI.js +++ b/scripts/sefinekAPI.js @@ -5,18 +5,32 @@ const log = require('./log.js'); const SEFINEK_API_URL = `${process.env.NODE_ENV === 'production' ? 'https://api.sefinek.net' : 'http://127.0.0.1:4010'}/api/v2/cloudflare-waf-abuseipdb/post`; module.exports = async () => { - const reportedIPs = readReportedIPs(); + const reportedIPs = readReportedIPs().filter(ip => ip.action === 'Reported' && ip.sefinekAPI === 'false'); if (reportedIPs.length === 0) { - log('info', 'No reported IPs to send to Sefinek API.'); + log('info', 'No reported IPs with action "Reported" and SefinekAPI false to send to Sefinek API.'); + return; + } + + const uniqueLogs = reportedIPs.reduce((acc, ip) => { + if (!acc.seen.has(ip.ip)) { + acc.seen.add(ip.ip); + acc.logs.push(ip); + } + return acc; + }, { seen: new Set(), logs: [] }).logs; + + if (uniqueLogs.length === 0) { + log('info', 'No unique IPs to send.'); return; } try { const res = await axios.post(SEFINEK_API_URL, { - reportedIPs: reportedIPs.map(ip => ({ + reportedIPs: uniqueLogs.map(ip => ({ rayId: ip.rayId, ip: ip.ip, endpoint: ip.endpoint, + useragent: ip.useragent.replace(/"/g, ''), action: ip.action, country: ip.country })) @@ -24,10 +38,7 @@ module.exports = async () => { log('info', `Logs (${res.data.count}) sent to Sefinek API. Status: ${res.status}`); - reportedIPs.forEach(ip => { - updateSefinekAPIInCSV(ip.rayId, true); - }); - + uniqueLogs.forEach(ip => updateSefinekAPIInCSV(ip.rayId, true)); } catch (err) { log('error', `Failed to send logs to Sefinek API. Error: ${err.message}`); }