UNPKG

@superadnim/osint-mcp-server

Version:

Professional OSINT MCP Server for intelligence gathering with privacy protection

333 lines 13.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OSINTEngine = void 0; const uuid_1 = require("uuid"); const cache_manager_js_1 = require("../utils/cache-manager.js"); const rate_limiter_js_1 = require("../utils/rate-limiter.js"); const data_sources_js_1 = require("./data-sources.js"); const correlation_js_1 = require("./correlation.js"); const mind_map_js_1 = require("./mind-map.js"); class OSINTEngine { configManager; logger; cache; rateLimiter; dataSourceManager; correlationEngine; mindMapManager; constructor(configManager, logger) { this.configManager = configManager; this.logger = logger; this.cache = new cache_manager_js_1.CacheManager({ ttl: 3600 }); this.rateLimiter = new rate_limiter_js_1.RateLimiter(); const config = configManager.getConfig(); this.dataSourceManager = new data_sources_js_1.DataSourceManager(this.rateLimiter, this.cache, this.logger, config.sources.apiKeys); this.correlationEngine = new correlation_js_1.CorrelationEngine(this.logger); this.mindMapManager = new mind_map_js_1.MindMapManager(this.cache, this.logger); } async searchPeople(args) { const query = args.query; const searchType = args.search_type || 'auto'; const includeRelatives = args.include_relatives || false; const includeAddresses = args.include_addresses || true; const includePhones = args.include_phones || true; const includeEmails = args.include_emails || true; const confidenceThreshold = args.confidence_threshold || 0.3; const maxResults = args.max_results || 10; this.logger.audit('people_search_initiated', { query: this.maskSensitiveData(query), search_type: searchType, options: { includeRelatives, includeAddresses, includePhones, includeEmails, confidenceThreshold, maxResults, }, }); const investigationId = (0, uuid_1.v4)(); const detectedType = this.detectQueryType(query); try { const results = await this.dataSourceManager.searchAcrossSources('people', query, { type: detectedType, includeRelatives, includeAddresses, includePhones, includeEmails, maxResults, }); const correlatedData = this.correlationEngine.correlatePeopleData(results); const peopleSearchResult = { target: { query: this.maskSensitiveData(query), detected_type: detectedType, confidence: this.calculateConfidence(correlatedData), }, demographics: { names: correlatedData.names || [], age_range: correlatedData.age_range, gender: correlatedData.gender, ethnicity: correlatedData.ethnicity, }, contact_info: { phones: correlatedData.phones || [], emails: correlatedData.emails || [], addresses: correlatedData.addresses || [], }, relatives: correlatedData.relatives || [], associates: correlatedData.associates || [], social_profiles: correlatedData.social_profiles || [], sources: this.dataSourceManager.getSourcesByType('people').map(s => ({ id: s.id, name: s.name, type: s.type, tier: s.tier, rateLimit: s.rateLimit, baseUrl: s.baseUrl, endpoints: s.endpoints, })), investigation_id: investigationId, timestamp: new Date().toISOString(), }; this.logger.audit('people_search_completed', { investigation_id: investigationId, results_count: correlatedData.names?.length || 0, }); return peopleSearchResult; } catch (error) { this.logger.error('People search failed', { query: this.maskSensitiveData(query), error }); throw new Error('People search operation failed'); } } async lookupPhone(args) { const phone = args.phone; const includeCarrier = args.include_carrier !== false; const includeLocation = args.include_location !== false; const includeSpamCheck = args.include_spam_check !== false; const includeSocialAccounts = args.include_social_accounts || false; const formatInternational = args.format_international !== false; this.logger.audit('phone_lookup_initiated', { phone: this.maskPhone(phone), options: { includeCarrier, includeLocation, includeSpamCheck, includeSocialAccounts, formatInternational, }, }); try { const results = await this.dataSourceManager.searchAcrossSources('phone', phone, { includeCarrier, includeLocation, includeSpamCheck, includeSocialAccounts, formatInternational, }); const phoneData = this.correlationEngine.correlatePhoneData(results); const phoneResult = { phone_number: { original: this.maskPhone(phone), formatted: phoneData.formatted || this.maskPhone(phone), international: phoneData.international || this.maskPhone(phone), national: phoneData.national || this.maskPhone(phone), e164: phoneData.e164 || this.maskPhone(phone), }, carrier_info: phoneData.carrier_info || { name: 'Unknown', type: 'mobile', country: 'Unknown', }, location: phoneData.location || { country: 'Unknown', region: 'Unknown', timezone: 'Unknown', }, reputation: phoneData.reputation || { spam_score: 0, scam_reports: 0, whitelist_status: false, last_reported: 'Never', }, associated_accounts: phoneData.associated_accounts || [], registered_services: phoneData.registered_services || [], historical_data: phoneData.historical_data || [], }; this.logger.audit('phone_lookup_completed', { phone: this.maskPhone(phone), carrier: phoneResult.carrier_info.name, }); return phoneResult; } catch (error) { this.logger.error('Phone lookup failed', { phone: this.maskPhone(phone), error }); throw new Error('Phone lookup operation failed'); } } async analyzeEmail(args) { const email = args.email; const checkBreaches = args.check_breaches !== false; const enumerateAccounts = args.enumerate_accounts || false; const analyzeDomain = args.analyze_domain !== false; const checkDeliverability = args.check_deliverability || false; const includeMetadata = args.include_metadata || false; const deepScan = args.deep_scan || false; this.logger.audit('email_analysis_initiated', { email: this.maskEmail(email), options: { checkBreaches, enumerateAccounts, analyzeDomain, checkDeliverability, includeMetadata, deepScan, }, }); try { const results = await this.dataSourceManager.searchAcrossSources('email', email, { checkBreaches, enumerateAccounts, analyzeDomain, checkDeliverability, includeMetadata, deepScan, }); const emailData = this.correlationEngine.correlateEmailData(results); const emailResult = { email_address: { address: this.maskEmail(email), local_part: email.split('@')[0] || '', domain: email.split('@')[1] || '', is_valid: emailData.is_valid || false, is_disposable: emailData.is_disposable || false, is_business: emailData.is_business || false, }, domain_analysis: emailData.domain_analysis || { mx_records: [], organization: 'Unknown', creation_date: 'Unknown', registrar: 'Unknown', reputation_score: 0, }, breach_analysis: emailData.breach_analysis || { total_breaches: 0, breaches: [], exposed_data_types: [], latest_breach: 'None', risk_level: 'low', }, account_enumeration: emailData.account_enumeration || { confirmed_accounts: [], possible_accounts: [], total_platforms_checked: 0, }, deliverability: emailData.deliverability || { accepts_mail: false, mailbox_full: false, catch_all: false, role_account: false, }, }; this.logger.audit('email_analysis_completed', { email: this.maskEmail(email), breaches_found: emailResult.breach_analysis.total_breaches, }); return emailResult; } catch (error) { this.logger.error('Email analysis failed', { email: this.maskEmail(email), error }); throw new Error('Email analysis operation failed'); } } async enumerateUsername(args) { const username = args.username; this.logger.audit('username_enumeration_initiated', { username }); // Mock implementation - would implement actual username enumeration return { username, platforms_scanned: 0, confirmed_accounts: [], possible_accounts: [], statistics: { total_found: 0, active_accounts: 0, verified_accounts: 0, account_creation_timeline: [], }, }; } async reconDomain(args) { const domain = args.domain; this.logger.audit('domain_recon_initiated', { domain }); // Mock implementation - would implement actual domain reconnaissance return { domain, dns_records: { a: [], aaaa: [], mx: [], txt: [], ns: [], cname: [], soa: {}, }, whois_data: {}, subdomains: { discovered: [], total_found: 0, enumeration_methods: [], }, }; } async performGoogleDorking(args) { const query = args.query; const dorkType = args.dork_type; this.logger.audit('google_dorking_initiated', { query: this.maskSensitiveData(query), dork_type: dorkType }); // Mock implementation - would implement actual Google dorking return { query: this.maskSensitiveData(query), dork_type: dorkType, results: [], total_results: 0, }; } async manageMindMap(args) { const investigationId = args.investigation_id; const action = args.action; this.logger.audit('mind_map_action', { investigation_id: investigationId, action }); return this.mindMapManager.handleAction(investigationId, action, args); } detectQueryType(query) { if (query.includes('@')) return 'email'; if (/^\+?[\d\s\-\(\)]+$/.test(query)) return 'phone'; return 'name'; } calculateConfidence(data) { // Simple confidence calculation - would be more sophisticated in real implementation return 0.7; } maskSensitiveData(data) { // Mask sensitive parts of the query for logging if (data.includes('@')) { const [local, domain] = data.split('@'); return `${local.slice(0, 2)}***@${domain}`; } if (/^\+?[\d\s\-\(\)]+$/.test(data)) { return `***-***-${data.slice(-4)}`; } return data.split(' ').map(part => `${part.slice(0, 2)}***`).join(' '); } maskPhone(phone) { return `***-***-${phone.slice(-4)}`; } maskEmail(email) { const [local, domain] = email.split('@'); return `${local.slice(0, 2)}***@${domain}`; } } exports.OSINTEngine = OSINTEngine; //# sourceMappingURL=osint-engine.js.map