import * as plugins from './plugins.js'; import * as paths from './paths.js'; import axios from 'axios'; export interface IThreatFoxData { ID: string; Dateadded: string; URL: string; URLStatus: string; Threat: string; AssociatedTags: string; ThreatFoxLink: string; Reporter: string; } export class ThreatFox { private static readonly THREATFOX_API_URL: string = 'https://threatfox.abuse.ch/export/csv/full'; // Replace with actual API endpoint public async getData(): Promise { plugins.smartfile.fs.ensureDirSync(paths.threatFoxTmp); const zipPath = plugins.path.join(paths.threatFoxTmp, 'threatfox.zip'); const csvPath = plugins.path.join(paths.threatFoxTmp, 'full.csv'); const response = await axios.get(ThreatFox.THREATFOX_API_URL, { responseType: 'stream' }); await new Promise((resolve, reject) => { const fileStream = plugins.fs.createWriteStream(zipPath); response.data.pipe(fileStream); fileStream.on('finish', resolve); fileStream.on('error', reject); }); await new Promise((resolve, reject) => { plugins.stream.pipeline( plugins.fs.createReadStream(zipPath), plugins.unzipper.Extract({ path: paths.threatFoxTmp }), (err) => { if (err) reject(err); else resolve(null); } ); }); let data: IThreatFoxData[] = []; await new Promise((resolve, reject) => { plugins.stream.pipeline( plugins.fs.createReadStream(csvPath), plugins.csv({ headers: ['ID', 'Dateadded', 'URL', 'URLStatus', 'Threat', 'AssociatedTags', 'ThreatFoxLink', 'Reporter'], mapValues: ({ header, value }) => value.trim() }), (err) => { if (err) reject(err); } ) .on('data', (row) => { data.push(row); }) .on('end', resolve) .on('error', reject); }); data = data.map((item) => { return { ...item, URL: item.URL?.replace('http', 'ht-NOCLICK-NOLINK-tp'), } }); plugins.smartfile.fs.removeSync(paths.threatFoxTmp); return data; } }