admin / SAynapse-Horizon
publicSelf Hosted Cyber Threat Intelligence Hub
SAynapse-Horizon / Synapse-Horizon-v2 / backend / src / sources / index.js
2183 B · main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | // Source registry + orchestration. Each module exports { meta, configured, fetchSource }. import * as urlhaus from './urlhaus.js' import * as threatfox from './threatfox.js' import * as feodo from './feodo.js' import * as phishtank from './phishtank.js' import * as cisakev from './cisakev.js' import * as blocklistde from './blocklistde.js' import * as otx from './otx.js' import * as rss from './rss.js' import { demoBatch } from './demo.js' import { ok } from '../normalize.js' const MODULES = { urlhaus, threatfox, feodo, phishtank, cisakev, blocklistde, otx, rss } export const SOURCE_KEYS = Object.keys(MODULES) const demoEnabled = () => process.env.HORIZON_DEMO === '1' || process.env.HORIZON_DEMO === 'true' /** Static descriptor of every source and whether it currently has its credentials. */ export function describeSources() { return SOURCE_KEYS.map((key) => ({ key, requiresKey: MODULES[key].meta.requiresKey, configured: MODULES[key].configured(), })) } /** * Fetch the requested sources concurrently, isolating failures per source. * @param {string[]} keys source keys to pull (defaults to all) * @returns {Promise<{iocs: object[], status: Record<string, object>}>} */ export async function runSources(keys = SOURCE_KEYS) { const selected = keys.filter((k) => MODULES[k]) const demo = demoEnabled() const settled = await Promise.allSettled( selected.map(async (key) => { const mod = MODULES[key] // Demo mode substitutes synthetic data for any source lacking credentials. if (demo && !mod.configured()) { return [key, ok(demoBatch(key), 'demo data (HORIZON_DEMO)')] } const result = await mod.fetchSource() return [key, result] }) ) const iocs = [] const status = {} settled.forEach((r, i) => { const key = selected[i] if (r.status === 'fulfilled') { const [, result] = r.value status[key] = { status: result.status, count: result.count, message: result.message || null } iocs.push(...result.iocs) } else { status[key] = { status: 'error', count: 0, message: String(r.reason?.message || r.reason) } } }) return { iocs, status } } |