it
This commit is contained in:
parent
a0caedcb1f
commit
709d3b9f3d
@ -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-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-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-cluster" title="Cluster Nodes">[CLUSTER]</button>
|
||||||
|
<button class="graph-control-btn" id="graph-clear" title="Clear Graph">[CLEAR]</button>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
this.container.appendChild(controlsContainer);
|
this.container.appendChild(controlsContainer);
|
||||||
@ -203,6 +204,7 @@ class GraphManager {
|
|||||||
document.getElementById('graph-reset').addEventListener('click', () => this.resetView());
|
document.getElementById('graph-reset').addEventListener('click', () => this.resetView());
|
||||||
document.getElementById('graph-physics').addEventListener('click', () => this.togglePhysics());
|
document.getElementById('graph-physics').addEventListener('click', () => this.togglePhysics());
|
||||||
document.getElementById('graph-cluster').addEventListener('click', () => this.toggleClustering());
|
document.getElementById('graph-cluster').addEventListener('click', () => this.toggleClustering());
|
||||||
|
document.getElementById('graph-clear').addEventListener('click', () => this.clear());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,6 +56,7 @@ class DNSReconApp {
|
|||||||
startScan: document.getElementById('start-scan'),
|
startScan: document.getElementById('start-scan'),
|
||||||
stopScan: document.getElementById('stop-scan'),
|
stopScan: document.getElementById('stop-scan'),
|
||||||
exportResults: document.getElementById('export-results'),
|
exportResults: document.getElementById('export-results'),
|
||||||
|
configureApiKeys: document.getElementById('configure-api-keys'),
|
||||||
|
|
||||||
// Status elements
|
// Status elements
|
||||||
scanStatus: document.getElementById('scan-status'),
|
scanStatus: document.getElementById('scan-status'),
|
||||||
@ -69,12 +70,20 @@ class DNSReconApp {
|
|||||||
// Provider elements
|
// Provider elements
|
||||||
providerList: document.getElementById('provider-list'),
|
providerList: document.getElementById('provider-list'),
|
||||||
|
|
||||||
// Modal elements
|
// Node Modal elements
|
||||||
nodeModal: document.getElementById('node-modal'),
|
nodeModal: document.getElementById('node-modal'),
|
||||||
modalTitle: document.getElementById('modal-title'),
|
modalTitle: document.getElementById('modal-title'),
|
||||||
modalDetails: document.getElementById('modal-details'),
|
modalDetails: document.getElementById('modal-details'),
|
||||||
modalClose: document.getElementById('modal-close'),
|
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
|
// Other elements
|
||||||
sessionId: document.getElementById('session-id'),
|
sessionId: document.getElementById('session-id'),
|
||||||
connectionStatus: document.getElementById('connection-status')
|
connectionStatus: document.getElementById('connection-status')
|
||||||
@ -140,6 +149,8 @@ class DNSReconApp {
|
|||||||
this.exportResults();
|
this.exportResults();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.elements.configureApiKeys.addEventListener('click', () => this.showApiKeyModal());
|
||||||
|
|
||||||
// Enter key support for target domain input
|
// Enter key support for target domain input
|
||||||
this.elements.targetDomain.addEventListener('keypress', (e) => {
|
this.elements.targetDomain.addEventListener('keypress', (e) => {
|
||||||
if (e.key === 'Enter' && !this.isScanning) {
|
if (e.key === 'Enter' && !this.isScanning) {
|
||||||
@ -148,19 +159,32 @@ class DNSReconApp {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Modal interactions
|
// Node Modal interactions
|
||||||
if (this.elements.modalClose) {
|
if (this.elements.modalClose) {
|
||||||
this.elements.modalClose.addEventListener('click', () => this.hideModal());
|
this.elements.modalClose.addEventListener('click', () => this.hideModal());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.elements.nodeModal) {
|
if (this.elements.nodeModal) {
|
||||||
this.elements.nodeModal.addEventListener('click', (e) => {
|
this.elements.nodeModal.addEventListener('click', (e) => {
|
||||||
if (e.target === this.elements.nodeModal) {
|
if (e.target === this.elements.nodeModal) this.hideModal();
|
||||||
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
|
// Custom events
|
||||||
document.addEventListener('nodeSelected', (e) => {
|
document.addEventListener('nodeSelected', (e) => {
|
||||||
this.showNodeModal(e.detail.nodeId, e.detail.node);
|
this.showNodeModal(e.detail.nodeId, e.detail.node);
|
||||||
@ -170,6 +194,7 @@ class DNSReconApp {
|
|||||||
document.addEventListener('keydown', (e) => {
|
document.addEventListener('keydown', (e) => {
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') {
|
||||||
this.hideModal();
|
this.hideModal();
|
||||||
|
this.hideApiKeyModal();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -609,7 +634,6 @@ class DNSReconApp {
|
|||||||
}
|
}
|
||||||
if (this.elements.stopScan) {
|
if (this.elements.stopScan) {
|
||||||
this.elements.stopScan.disabled = true;
|
this.elements.stopScan.disabled = true;
|
||||||
this.elements.stopScan.classList.add('loading');
|
|
||||||
}
|
}
|
||||||
if (this.elements.targetDomain) this.elements.targetDomain.disabled = false;
|
if (this.elements.targetDomain) this.elements.targetDomain.disabled = false;
|
||||||
if (this.elements.maxDepth) this.elements.maxDepth.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
|
* Check if graph data has changed
|
||||||
* @param {Object} graphData - New graph data
|
* @param {Object} graphData - New graph data
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<!-- Header -->
|
|
||||||
<header class="header">
|
<header class="header">
|
||||||
<div class="header-content">
|
<div class="header-content">
|
||||||
<div class="logo">
|
<div class="logo">
|
||||||
@ -25,9 +24,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<!-- Main Content -->
|
|
||||||
<main class="main-content">
|
<main class="main-content">
|
||||||
<!-- Control Panel -->
|
|
||||||
<section class="control-panel">
|
<section class="control-panel">
|
||||||
<div class="panel-header">
|
<div class="panel-header">
|
||||||
<h2>Target Configuration</h2>
|
<h2>Target Configuration</h2>
|
||||||
@ -71,7 +68,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Status Panel -->
|
|
||||||
<section class="status-panel">
|
<section class="status-panel">
|
||||||
<div class="panel-header">
|
<div class="panel-header">
|
||||||
<h2>Reconnaissance Status</h2>
|
<h2>Reconnaissance Status</h2>
|
||||||
@ -109,7 +105,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Visualization Panel -->
|
|
||||||
<section class="visualization-panel">
|
<section class="visualization-panel">
|
||||||
<div class="panel-header">
|
<div class="panel-header">
|
||||||
<h2>Infrastructure Map</h2>
|
<h2>Infrastructure Map</h2>
|
||||||
@ -153,19 +148,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Provider Panel -->
|
|
||||||
<section class="provider-panel">
|
<section class="provider-panel">
|
||||||
<div class="panel-header">
|
<div class="panel-header">
|
||||||
<h2>Data Providers</h2>
|
<h2>Data Providers</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="provider-list" class="provider-list">
|
<div id="provider-list" class="provider-list">
|
||||||
<!-- Provider status will be populated here -->
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<!-- Footer -->
|
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<div class="footer-content">
|
<div class="footer-content">
|
||||||
<span>DNSRecon v1.0 - Phase 1 Implementation</span>
|
<span>DNSRecon v1.0 - Phase 1 Implementation</span>
|
||||||
@ -176,7 +168,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<!-- Node Details Modal -->
|
|
||||||
<div id="node-modal" class="modal">
|
<div id="node-modal" class="modal">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
@ -185,14 +176,44 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div id="modal-details">
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Scripts -->
|
|
||||||
<script src="{{ url_for('static', filename='js/graph.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/graph.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
|
||||||
</body>
|
</body>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user