@superadnim/osint-mcp-server
Version:
Professional OSINT MCP Server for intelligence gathering with privacy protection
333 lines • 13.5 kB
JavaScript
"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