This commit is contained in:
overcuriousity 2025-09-10 16:45:05 +02:00
parent a0caedcb1f
commit 709d3b9f3d
3 changed files with 124 additions and 21 deletions

View File

@ -194,6 +194,7 @@ class GraphManager {
<button class="graph-control-btn" id="graph-reset" title="Reset View">[RESET]</button>
<button class="graph-control-btn" id="graph-physics" title="Toggle Physics">[PHYSICS]</button>
<button class="graph-control-btn" id="graph-cluster" title="Cluster Nodes">[CLUSTER]</button>
<button class="graph-control-btn" id="graph-clear" title="Clear Graph">[CLEAR]</button>
`;
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());
}
/**

View File

@ -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')
@ -140,6 +149,8 @@ class DNSReconApp {
this.exportResults();
});
this.elements.configureApiKeys.addEventListener('click', () => this.showApiKeyModal());
// Enter key support for target domain input
this.elements.targetDomain.addEventListener('keypress', (e) => {
if (e.key === 'Enter' && !this.isScanning) {
@ -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;
@ -734,6 +758,62 @@ class DNSReconApp {
}
}
/**
* 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
* @param {Object} graphData - New graph data

View File

@ -11,7 +11,6 @@
</head>
<body>
<div class="container">
<!-- Header -->
<header class="header">
<div class="header-content">
<div class="logo">
@ -25,9 +24,7 @@
</div>
</header>
<!-- Main Content -->
<main class="main-content">
<!-- Control Panel -->
<section class="control-panel">
<div class="panel-header">
<h2>Target Configuration</h2>
@ -71,7 +68,6 @@
</div>
</section>
<!-- Status Panel -->
<section class="status-panel">
<div class="panel-header">
<h2>Reconnaissance Status</h2>
@ -109,7 +105,6 @@
</div>
</section>
<!-- Visualization Panel -->
<section class="visualization-panel">
<div class="panel-header">
<h2>Infrastructure Map</h2>
@ -153,19 +148,16 @@
</div>
</section>
<!-- Provider Panel -->
<section class="provider-panel">
<div class="panel-header">
<h2>Data Providers</h2>
</div>
<div id="provider-list" class="provider-list">
<!-- Provider status will be populated here -->
</div>
</div>
</section>
</main>
<!-- Footer -->
<footer class="footer">
<div class="footer-content">
<span>DNSRecon v1.0 - Phase 1 Implementation</span>
@ -176,7 +168,6 @@
</div>
</footer>
<!-- Node Details Modal -->
<div id="node-modal" class="modal">
<div class="modal-content">
<div class="modal-header">
@ -185,14 +176,44 @@
</div>
<div class="modal-body">
<div id="modal-details">
<!-- Node details will be populated here -->
</div>
</div>
</div>
</div>
<div id="api-key-modal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3>Configure API Keys</h3>
<button id="api-key-modal-close" class="modal-close">[×]</button>
</div>
<div class="modal-body">
<p class="modal-description">
Enter your API keys for enhanced data providers. Keys are stored in memory for the current session only and are never saved to disk.
</p>
<div class="apikey-section">
<label for="virustotal-api-key">VirusTotal API Key</label>
<input type="password" id="virustotal-api-key" placeholder="Enter VirusTotal API Key">
<p class="apikey-help">Enables passive DNS and domain reputation lookups.</p>
</div>
<div class="apikey-section">
<label for="shodan-api-key">Shodan API Key</label>
<input type="password" id="shodan-api-key" placeholder="Enter Shodan API Key">
<p class="apikey-help">Provides infrastructure context and service information.</p>
</div>
<div class="button-group" style="flex-direction: row; justify-content: flex-end;">
<button id="reset-api-keys" class="btn btn-secondary">
<span>Reset</span>
</button>
<button id="save-api-keys" class="btn btn-primary">
<span>Save Keys</span>
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Scripts -->
<script src="{{ url_for('static', filename='js/graph.js') }}"></script>
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
</body>