diff --git a/static/js/graph.js b/static/js/graph.js index 1e63cdb..f477e0c 100644 --- a/static/js/graph.js +++ b/static/js/graph.js @@ -194,6 +194,7 @@ class GraphManager { + `; this.container.appendChild(controlsContainer); @@ -203,6 +204,7 @@ class GraphManager { document.getElementById('graph-reset').addEventListener('click', () => this.resetView()); document.getElementById('graph-physics').addEventListener('click', () => this.togglePhysics()); document.getElementById('graph-cluster').addEventListener('click', () => this.toggleClustering()); + document.getElementById('graph-clear').addEventListener('click', () => this.clear()); } /** diff --git a/static/js/main.js b/static/js/main.js index 3cdc34a..9889e0e 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -56,6 +56,7 @@ class DNSReconApp { startScan: document.getElementById('start-scan'), stopScan: document.getElementById('stop-scan'), exportResults: document.getElementById('export-results'), + configureApiKeys: document.getElementById('configure-api-keys'), // Status elements scanStatus: document.getElementById('scan-status'), @@ -69,12 +70,20 @@ class DNSReconApp { // Provider elements providerList: document.getElementById('provider-list'), - // Modal elements + // Node Modal elements nodeModal: document.getElementById('node-modal'), modalTitle: document.getElementById('modal-title'), modalDetails: document.getElementById('modal-details'), modalClose: document.getElementById('modal-close'), - + + // API Key Modal elements + apiKeyModal: document.getElementById('api-key-modal'), + apiKeyModalClose: document.getElementById('api-key-modal-close'), + virustotalApiKey: document.getElementById('virustotal-api-key'), + shodanApiKey: document.getElementById('shodan-api-key'), + saveApiKeys: document.getElementById('save-api-keys'), + resetApiKeys: document.getElementById('reset-api-keys'), + // Other elements sessionId: document.getElementById('session-id'), connectionStatus: document.getElementById('connection-status') @@ -139,6 +148,8 @@ class DNSReconApp { e.preventDefault(); this.exportResults(); }); + + this.elements.configureApiKeys.addEventListener('click', () => this.showApiKeyModal()); // Enter key support for target domain input this.elements.targetDomain.addEventListener('keypress', (e) => { @@ -148,19 +159,32 @@ class DNSReconApp { } }); - // Modal interactions + // Node Modal interactions if (this.elements.modalClose) { this.elements.modalClose.addEventListener('click', () => this.hideModal()); } - if (this.elements.nodeModal) { this.elements.nodeModal.addEventListener('click', (e) => { - if (e.target === this.elements.nodeModal) { - this.hideModal(); - } + if (e.target === this.elements.nodeModal) this.hideModal(); }); } - + + // API Key Modal interactions + if (this.elements.apiKeyModalClose) { + this.elements.apiKeyModalClose.addEventListener('click', () => this.hideApiKeyModal()); + } + if (this.elements.apiKeyModal) { + this.elements.apiKeyModal.addEventListener('click', (e) => { + if (e.target === this.elements.apiKeyModal) this.hideApiKeyModal(); + }); + } + if (this.elements.saveApiKeys) { + this.elements.saveApiKeys.addEventListener('click', () => this.saveApiKeys()); + } + if (this.elements.resetApiKeys) { + this.elements.resetApiKeys.addEventListener('click', () => this.resetApiKeys()); + } + // Custom events document.addEventListener('nodeSelected', (e) => { this.showNodeModal(e.detail.nodeId, e.detail.node); @@ -170,6 +194,7 @@ class DNSReconApp { document.addEventListener('keydown', (e) => { if (e.key === 'Escape') { this.hideModal(); + this.hideApiKeyModal(); } }); @@ -609,7 +634,6 @@ class DNSReconApp { } if (this.elements.stopScan) { this.elements.stopScan.disabled = true; - this.elements.stopScan.classList.add('loading'); } if (this.elements.targetDomain) this.elements.targetDomain.disabled = false; if (this.elements.maxDepth) this.elements.maxDepth.disabled = false; @@ -733,6 +757,62 @@ class DNSReconApp { this.elements.nodeModal.style.display = 'none'; } } + + /** + * Show API Key modal + */ + showApiKeyModal() { + if (this.elements.apiKeyModal) { + this.elements.apiKeyModal.style.display = 'block'; + } + } + + /** + * Hide API Key modal + */ + hideApiKeyModal() { + if (this.elements.apiKeyModal) { + this.elements.apiKeyModal.style.display = 'none'; + } + } + + /** + * Save API Keys + */ + async saveApiKeys() { + const shodanKey = this.elements.shodanApiKey.value.trim(); + const virustotalKey = this.elements.virustotalApiKey.value.trim(); + + const keys = {}; + if (shodanKey) keys.shodan = shodanKey; + if (virustotalKey) keys.virustotal = virustotalKey; + + if (Object.keys(keys).length === 0) { + this.showWarning('No API keys were entered.'); + return; + } + + try { + const response = await this.apiCall('/api/config/api-keys', 'POST', keys); + if (response.success) { + this.showSuccess(response.message); + this.hideApiKeyModal(); + this.loadProviders(); // Refresh provider status + } else { + throw new Error(response.error || 'Failed to save API keys'); + } + } catch (error) { + this.showError(`Error saving API keys: ${error.message}`); + } + } + + /** + * Reset API Key fields + */ + resetApiKeys() { + this.elements.shodanApiKey.value = ''; + this.elements.virustotalApiKey.value = ''; + } /** * Check if graph data has changed diff --git a/templates/index.html b/templates/index.html index aca67df..53f03bf 100644 --- a/templates/index.html +++ b/templates/index.html @@ -11,7 +11,6 @@