detecti-cli 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. detecti/__init__.py +0 -0
  2. detecti/cli.py +649 -0
  3. detecti/config.py +188 -0
  4. detecti/core/__init__.py +1 -0
  5. detecti/core/database/__init__.py +5 -0
  6. detecti/core/database/config_db.py +73 -0
  7. detecti/core/database/schema.py +136 -0
  8. detecti/core/database/storage.py +1388 -0
  9. detecti/core/engine.py +1032 -0
  10. detecti/core/models.py +278 -0
  11. detecti/data/config.sqlite +0 -0
  12. detecti/data/dbs/.gitkeep +2 -0
  13. detecti/data/dbs/example.com.sqlite +0 -0
  14. detecti/modules/__init__.py +29 -0
  15. detecti/modules/base.py +57 -0
  16. detecti/modules/censys.py +813 -0
  17. detecti/modules/crtsh.py +98 -0
  18. detecti/modules/exploitdb.py +138 -0
  19. detecti/modules/masscan.py +561 -0
  20. detecti/modules/nuclei.py +449 -0
  21. detecti/modules/nvd.py +300 -0
  22. detecti/modules/reverse_whois.py +225 -0
  23. detecti/modules/shodan.py +412 -0
  24. detecti/reporters/__init__.py +7 -0
  25. detecti/reporters/csv_reporter.py +74 -0
  26. detecti/reporters/html_reporter.py +356 -0
  27. detecti/reporters/json_reporter.py +26 -0
  28. detecti/reporters/markdown_reporter.py +203 -0
  29. detecti/utils/__init__.py +1 -0
  30. detecti/utils/http.py +294 -0
  31. detecti/utils/logger.py +378 -0
  32. detecti/utils/setup.py +453 -0
  33. detecti/web/__init__.py +6 -0
  34. detecti/web/api/__init__.py +1 -0
  35. detecti/web/api/auth.py +109 -0
  36. detecti/web/api/graph_builder.py +901 -0
  37. detecti/web/api/routes.py +1602 -0
  38. detecti/web/process_manager.py +283 -0
  39. detecti/web/server.py +183 -0
  40. detecti/web/static/android-chrome-192x192.png +0 -0
  41. detecti/web/static/android-chrome-512x512.png +0 -0
  42. detecti/web/static/apple-touch-icon.png +0 -0
  43. detecti/web/static/css/__init__.py +1 -0
  44. detecti/web/static/css/dashboard.css +3802 -0
  45. detecti/web/static/favicon-16x16.png +0 -0
  46. detecti/web/static/favicon-32x32.png +0 -0
  47. detecti/web/static/favicon.ico +0 -0
  48. detecti/web/static/img/DetecTI_Security_Logo.png +0 -0
  49. detecti/web/static/img/detecti-ico.png +0 -0
  50. detecti/web/static/index.html +677 -0
  51. detecti/web/static/js/__init__.py +1 -0
  52. detecti/web/static/js/api.js +177 -0
  53. detecti/web/static/js/cytoscape-cose-bilkent.js +458 -0
  54. detecti/web/static/js/cytoscape-dagre.js +397 -0
  55. detecti/web/static/js/cytoscape.min.js +31 -0
  56. detecti/web/static/js/dagre.min.js +3809 -0
  57. detecti/web/static/js/graph.js +7439 -0
  58. detecti/web/static/js/lucide.min.js +12 -0
  59. detecti/web/static/login.html +290 -0
  60. detecti/web/static/site.webmanifest +1 -0
  61. detecti_cli-2.0.0.dist-info/METADATA +554 -0
  62. detecti_cli-2.0.0.dist-info/RECORD +64 -0
  63. detecti_cli-2.0.0.dist-info/WHEEL +4 -0
  64. detecti_cli-2.0.0.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,677 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
6
+ <title>DetecTIHound Web Dashboard</title>
7
+ <!-- Favicon -->
8
+ <link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
9
+ <link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
10
+ <link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
11
+ <link rel="manifest" href="/static/site.webmanifest">
12
+ <link rel="shortcut icon" href="/static/favicon.ico">
13
+ <!-- Google Fonts - Inter & JetBrains Mono -->
14
+ <link rel="preconnect" href="https://fonts.googleapis.com">
15
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
16
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
17
+ <link rel="stylesheet" href="/static/css/dashboard.css?v=22">
18
+ <script src="/static/js/cytoscape.min.js"></script>
19
+ <script src="/static/js/cytoscape-cose-bilkent.js"></script>
20
+ <script src="/static/js/lucide.min.js"></script>
21
+ </head>
22
+ <body>
23
+ <div class="dashboard-container">
24
+ <!-- Header -->
25
+ <header class="dashboard-header">
26
+ <div class="header-accent-bar"></div>
27
+ <div class="header-content">
28
+ <!-- Left: Mobile Sidebar Toggle & Brand -->
29
+ <div class="header-left">
30
+ <button id="toggle-sidebar" class="sidebar-toggle-btn" aria-label="Toggle Sidebar Menu" title="Toggle Filters & Controls">
31
+ <i data-lucide="menu" class="ui-icon"></i>
32
+ </button>
33
+ <a href="https://detecti.com.br" target="_blank" rel="noopener noreferrer" class="header-brand" title="Visit DetecTI Security Official Website (detecti.com.br)">
34
+ <img src="/static/img/DetecTI_Security_Logo.png" alt="DetecTI Security Logo" class="brand-logo">
35
+ <div class="brand-text">
36
+ <h1 class="brand-title">Detec<span class="ti-highlight">TI</span>-CLI</h1>
37
+ <span class="brand-subtitle">Cyber Lead Intelligence</span>
38
+ </div>
39
+ </a>
40
+ <a href="https://detecti.com.br/docs/detecti-cli/en.html" target="_blank" rel="noopener noreferrer" class="header-docs-icon-btn" title="Official Documentation (Opens in new tab)" aria-label="Official Documentation">
41
+ <i data-lucide="book-open" class="ui-icon"></i>
42
+ </a>
43
+ </div>
44
+
45
+ <!-- Right: Database Selector, Export Actions & Targets Button -->
46
+ <div class="header-right">
47
+ <!-- Database Selector Dropdown -->
48
+ <div class="header-control-group db-dropdown-wrapper" id="db-dropdown-wrapper">
49
+ <button id="btn-db-dropdown" class="action-btn db-trigger-btn" aria-haspopup="true" aria-expanded="false" title="Switch SQLite Database">
50
+ <i data-lucide="database" class="ui-icon db-icon-main"></i>
51
+ <span id="current-db-label" class="current-db-label">Loading database...</span>
52
+ <i data-lucide="chevron-down" class="ui-icon dropdown-chevron"></i>
53
+ </button>
54
+ <div class="db-dropdown-menu" id="db-dropdown-menu">
55
+ <div class="db-dropdown-header">
56
+ <span>Attack Surface Databases</span>
57
+ <span class="db-count-badge" id="db-count-badge">0</span>
58
+ </div>
59
+ <div class="db-dropdown-list" id="db-dropdown-list">
60
+ <!-- Dynamic DB List Items populated via JS -->
61
+ </div>
62
+ </div>
63
+ </div>
64
+
65
+ <!-- Export Report Dropdown -->
66
+ <div class="header-control-group export-dropdown-wrapper">
67
+ <button id="btn-export-dropdown" class="action-btn export-btn export-trigger-btn" aria-haspopup="true" aria-expanded="false" title="Export Attack Surface & Intelligence Data">
68
+ <i data-lucide="download" class="ui-icon"></i>
69
+ <span>Export Data</span>
70
+ <i data-lucide="chevron-down" class="ui-icon dropdown-chevron"></i>
71
+ </button>
72
+ <div class="export-dropdown-menu" id="export-dropdown-menu">
73
+ <button class="export-dropdown-item" id="export-item-json">
74
+ <i data-lucide="file-code-2" class="ui-icon export-item-icon"></i>
75
+ <div class="export-item-text">
76
+ <span class="export-item-title">JSON</span>
77
+ <span class="export-item-desc">Structured scan results</span>
78
+ </div>
79
+ </button>
80
+ <button class="export-dropdown-item" id="export-item-md">
81
+ <i data-lucide="file-text" class="ui-icon export-item-icon"></i>
82
+ <div class="export-item-text">
83
+ <span class="export-item-title">Markdown</span>
84
+ <span class="export-item-desc">Executive documentation</span>
85
+ </div>
86
+ </button>
87
+ <button class="export-dropdown-item" id="export-item-html">
88
+ <i data-lucide="globe" class="ui-icon export-item-icon"></i>
89
+ <div class="export-item-text">
90
+ <span class="export-item-title">HTML</span>
91
+ <span class="export-item-desc">Interactive browser report</span>
92
+ </div>
93
+ </button>
94
+ <button class="export-dropdown-item" id="export-item-csv">
95
+ <i data-lucide="file-spreadsheet" class="ui-icon export-item-icon"></i>
96
+ <div class="export-item-text">
97
+ <span class="export-item-title">CSV</span>
98
+ <span class="export-item-desc">Spreadsheet data format</span>
99
+ </div>
100
+ </button>
101
+ </div>
102
+ </div>
103
+
104
+ <!-- Target Management Drawer Trigger Button (At the far right corner) -->
105
+ <div class="header-control-group">
106
+ <button id="btn-toggle-targets" class="action-btn targets-drawer-trigger-btn" aria-label="Toggle Target Management" title="Target Management & Active Scan">
107
+ <i data-lucide="crosshair" class="ui-icon"></i>
108
+ <span class="target-btn-label">Targets</span>
109
+ <span id="target-scan-indicator" class="target-scan-indicator" style="display: none;">
110
+ <span class="target-scan-pulse-dot"></span>
111
+ <span>Scanning...</span>
112
+ </span>
113
+ <span id="target-badge-count" class="target-count-badge" style="display: none;">0</span>
114
+ </button>
115
+ </div>
116
+ </div>
117
+ </div>
118
+ </header>
119
+
120
+ <!-- Main Content -->
121
+ <div class="dashboard-main">
122
+ <!-- Sidebar Backdrop for Mobile/Tablet -->
123
+ <div id="sidebar-backdrop" class="drawer-backdrop"></div>
124
+
125
+ <!-- Sidebar -->
126
+ <aside class="sidebar" id="dashboard-sidebar">
127
+ <!-- Sidebar Mobile Header -->
128
+ <div class="sidebar-mobile-header">
129
+ <span class="sidebar-mobile-title"><i data-lucide="activity" class="ui-icon"></i> Surface &amp; Controls</span>
130
+ <button id="close-sidebar" class="sidebar-close-btn" aria-label="Close Sidebar"><i data-lucide="x" class="ui-icon"></i></button>
131
+ </div>
132
+
133
+ <!-- Metrics Accordion Panel -->
134
+ <div class="panel metrics-panel lead-accordion-panel">
135
+ <details class="sidebar-accordion" id="metrics-accordion" name="sidebar-accordion-group" open>
136
+ <summary class="accordion-header">
137
+ <span class="accordion-title"><i data-lucide="bar-chart-3" class="ui-icon panel-title-icon"></i> Attack Surface Metrics</span>
138
+ <i data-lucide="chevron-down" class="ui-icon accordion-icon"></i>
139
+ </summary>
140
+ <div class="accordion-body">
141
+ <!-- Attack Surface Metrics: Organized in 2-Column Pairs -->
142
+ <div class="metric-grid">
143
+ <div class="metric-item">
144
+ <span class="metric-value" id="domains-count">-</span>
145
+ <span class="metric-label">Domains</span>
146
+ </div>
147
+ <div class="metric-item">
148
+ <span class="metric-value" id="subdomains-count">-</span>
149
+ <span class="metric-label">Subdomains</span>
150
+ </div>
151
+ <div class="metric-item">
152
+ <span class="metric-value" id="ips-count">-</span>
153
+ <span class="metric-label">IP Addresses</span>
154
+ </div>
155
+ <div class="metric-item">
156
+ <span class="metric-value" id="services-count">-</span>
157
+ <span class="metric-label">Open Services</span>
158
+ </div>
159
+ <div class="metric-item verified-highlight">
160
+ <span class="metric-value" id="verified-services-count">-</span>
161
+ <span class="metric-label">Verified Services</span>
162
+ </div>
163
+ <div class="metric-item critical">
164
+ <span class="metric-value" id="vulns-count">-</span>
165
+ <span class="metric-label">Vulnerabilities</span>
166
+ </div>
167
+ <div class="metric-item critical">
168
+ <span class="metric-value" id="kev-count">-</span>
169
+ <span class="metric-label">CISA KEV</span>
170
+ </div>
171
+ <div class="metric-item epss-highlight">
172
+ <span class="metric-value" id="epss-count">-</span>
173
+ <span class="metric-label">High EPSS (&gt;50%)</span>
174
+ </div>
175
+ </div>
176
+ </div>
177
+ </details>
178
+ </div>
179
+
180
+ <!-- Filters Accordion Panel -->
181
+ <div class="panel filters-accordion-panel lead-accordion-panel">
182
+ <details class="sidebar-accordion" id="filters-accordion" name="sidebar-accordion-group">
183
+ <summary class="accordion-header">
184
+ <span class="accordion-title"><i data-lucide="sliders-horizontal" class="ui-icon panel-title-icon"></i> Filters</span>
185
+ <i data-lucide="chevron-down" class="ui-icon accordion-icon"></i>
186
+ </summary>
187
+ <div class="accordion-body">
188
+ <div class="filter-group">
189
+ <label class="filter-checkbox filter-3d-matrix-item" style="border-bottom: 1px solid rgba(140, 82, 255, 0.25); padding-bottom: 0.7rem; margin-bottom: 0.2rem;">
190
+ <input type="checkbox" id="filter-3d-matrix">
191
+ <span class="checkmark"></span>
192
+ <span style="color: #00e5ff; font-weight: 600;">3D Risk Matrix</span>&nbsp;<span style="color: var(--text-muted); font-size: 0.78rem;">(Active + Threat + Impact)</span>
193
+ </label>
194
+ <label class="filter-checkbox">
195
+ <input type="checkbox" id="filter-kev">
196
+ <span class="checkmark"></span>
197
+ <span style="color: #ff4757; font-weight: 600;">CISA KEV</span>&nbsp;<span style="color: var(--text-muted); font-size: 0.78rem;">(Known Exploited)</span>
198
+ </label>
199
+ <label class="filter-checkbox">
200
+ <input type="checkbox" id="filter-high-epss">
201
+ <span class="checkmark"></span>
202
+ <span style="color: #ffa502; font-weight: 600;">High EPSS</span>&nbsp;<span style="color: var(--text-muted); font-size: 0.78rem;">(&gt;50% Probability)</span>
203
+ </label>
204
+ <label class="filter-checkbox">
205
+ <input type="checkbox" id="filter-critical">
206
+ <span class="checkmark"></span>
207
+ <span style="color: #ff3838; font-weight: 600;">Critical Severity</span>&nbsp;<span style="color: var(--text-muted); font-size: 0.78rem;">(CVSS 9.0+)</span>
208
+ </label>
209
+ <label class="filter-checkbox">
210
+ <input type="checkbox" id="filter-hide-low-info">
211
+ <span class="checkmark"></span>
212
+ <span style="color: #70a1ff; font-weight: 600;">Hide Low &amp; Info</span>&nbsp;<span style="color: var(--text-muted); font-size: 0.78rem;">(Noise Reduction)</span>
213
+ </label>
214
+ <label class="filter-checkbox">
215
+ <input type="checkbox" id="filter-nuclei-only">
216
+ <span class="checkmark"></span>
217
+ <span style="color: #c084fc; font-weight: 600;">Nuclei Findings Only</span>&nbsp;<span style="color: var(--text-muted); font-size: 0.78rem;">(Templates)</span>
218
+ </label>
219
+ <label class="filter-checkbox">
220
+ <input type="checkbox" id="filter-with-pocs">
221
+ <span class="checkmark"></span>
222
+ <span style="color: #00d2d3; font-weight: 600;">Verified Public PoCs</span>&nbsp;<span style="color: var(--text-muted); font-size: 0.78rem;">(ExploitDB / GitHub)</span>
223
+ </label>
224
+ <label class="filter-checkbox" style="border-top: 1px solid rgba(255, 255, 255, 0.08); padding-top: 0.5rem; margin-top: 0.2rem;">
225
+ <input type="checkbox" id="filter-services-only">
226
+ <span class="checkmark"></span>
227
+ <span style="color: #2ed573; font-weight: 600;">Exposed Services</span>&nbsp;<span style="color: var(--text-muted); font-size: 0.78rem;">(All Branches)</span>
228
+ </label>
229
+ <label class="filter-checkbox">
230
+ <input type="checkbox" id="filter-verified-services">
231
+ <span class="checkmark"></span>
232
+ <span style="color: #26de81; font-weight: 600;">Verified Active Services</span>&nbsp;<span style="color: var(--text-muted); font-size: 0.78rem;">(Masscan / HTTP)</span>
233
+ </label>
234
+ <label class="filter-checkbox">
235
+ <input type="checkbox" id="filter-vuln-services">
236
+ <span class="checkmark"></span>
237
+ <span style="color: #eb4d4b; font-weight: 600;">Vulnerable Services</span>&nbsp;<span style="color: var(--text-muted); font-size: 0.78rem;">(Direct Findings)</span>
238
+ </label>
239
+ </div>
240
+ </div>
241
+ </details>
242
+ </div>
243
+
244
+
245
+ <!-- Sidebar Footer -->
246
+ <div class="sidebar-footer">
247
+ <div class="sidebar-logout" style="padding-bottom: 15px; border-bottom: 1px solid rgba(255, 255, 255, 0.05); margin-bottom: 15px;">
248
+ <button id="btn-logout" class="action-btn" style="width: 100%; justify-content: center; background: rgba(239, 68, 68, 0.1); color: #ef4444; border: 1px solid rgba(239, 68, 68, 0.3);">
249
+ <i data-lucide="log-out" class="ui-icon"></i> Terminate Session
250
+ </button>
251
+ </div>
252
+ <div><a href="https://detecti.com.br/docs/detecti-cli/en.html" target="_blank" rel="noopener noreferrer" class="sidebar-docs-link"><i data-lucide="book-marked" class="ui-icon sidebar-docs-icon"></i> Official Documentation ↗</a></div>
253
+ <div class="sidebar-powered">Powered by <a href="https://detecti.com.br" target="_blank" rel="noopener noreferrer">Detec<span class="ti-highlight">TI</span> Security</a></div>
254
+ </div>
255
+ </aside>
256
+
257
+ <!-- Graph Container -->
258
+ <main class="graph-container">
259
+ <div class="canvas-search-container" style="position: absolute; top: 20px; left: 20px; z-index: 100; width: 350px; max-width: calc(100vw - 40px); background: #1e1e2d; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.3); border: 1px solid #333; padding: 5px;">
260
+ <div class="search-group" style="margin: 0; background: transparent; border: none; box-shadow: none;">
261
+ <i data-lucide="search" class="ui-icon search-lead-icon"></i>
262
+ <input type="text" id="search-input" placeholder="Search nodes (IP, domain, CVE, port...)" class="search-input" style="background: rgba(0,0,0,0.2); color: #fff;">
263
+ <button id="clear-search" class="clear-btn" aria-label="Clear Search"><i data-lucide="x" class="ui-icon"></i></button>
264
+ </div>
265
+ </div>
266
+ <div id="spacebar-pan-hint" class="spacebar-pan-hint"><i data-lucide="hand" class="ui-icon" style="width: 14px; height: 14px; vertical-align: middle;"></i> Pan Mode (Spacebar or Right-Click held) - Drag to move view</div>
267
+ <div id="cy" class="cytoscape-graph"></div>
268
+
269
+ <!-- Floating Graph Actions & Layout (Left side) -->
270
+ <div class="floating-controls" id="floating-controls">
271
+ <div class="floating-actions-group">
272
+ <button id="btn-float-fit" class="floating-btn" title="Fit to Screen" aria-label="Fit Graph"><i data-lucide="maximize-2" class="ui-icon"></i></button>
273
+ <button id="btn-float-reset" class="floating-btn" title="Reset Zoom" aria-label="Reset Zoom"><i data-lucide="rotate-ccw" class="ui-icon"></i></button>
274
+ <button id="btn-float-relayout" class="floating-btn" title="Re-layout Graph" aria-label="Re-layout Graph"><i data-lucide="refresh-cw" class="ui-icon"></i></button>
275
+ </div>
276
+ <div class="floating-layout-wrapper">
277
+ <select id="layout-select" class="floating-layout-select" aria-label="Select Graph Layout" title="Select Layout">
278
+ <option value="hierarchical-topdown" selected>Hierarchical (Top-Down)</option>
279
+ <option value="hierarchical-leftright">Hierarchical (Left-Right)</option>
280
+ <option value="cose">Force-Directed</option>
281
+ <option value="concentric">Concentric</option>
282
+ <option value="grid">Grid</option>
283
+ </select>
284
+ </div>
285
+ </div>
286
+
287
+ <div class="graph-loading" id="graph-loading">
288
+ <div class="spinner"></div>
289
+ <p>Loading EASM graph data...</p>
290
+ </div>
291
+ </main>
292
+ </div>
293
+
294
+ <!-- Inspector Backdrop for Mobile/Tablet -->
295
+ <div id="inspector-backdrop" class="drawer-backdrop"></div>
296
+
297
+ <!-- Inspector Drawer -->
298
+ <div class="inspector-drawer" id="inspector-drawer">
299
+ <div class="inspector-header">
300
+ <h3 id="inspector-title">Asset Inspector</h3>
301
+ <button class="close-btn" id="close-inspector" aria-label="Close Inspector"><i data-lucide="x" class="ui-icon"></i></button>
302
+ </div>
303
+ <div class="inspector-content" id="inspector-content">
304
+ <p>Click on any node in the graph to inspect its properties...</p>
305
+ </div>
306
+ </div>
307
+
308
+ <!-- Targets Drawer Backdrop for Mobile/Tablet -->
309
+ <div id="targets-backdrop" class="drawer-backdrop"></div>
310
+
311
+ <!-- Target Management Drawer (Right) -->
312
+ <div class="targets-drawer" id="targets-drawer">
313
+ <div class="targets-drawer-header">
314
+ <div class="targets-header-title">
315
+ <i data-lucide="crosshair" class="ui-icon targets-header-icon"></i>
316
+ <h3>Target Management</h3>
317
+ <span class="targets-counter" id="targets-header-count">0 Targets</span>
318
+ </div>
319
+ <div class="targets-header-actions">
320
+ <button class="close-btn" id="close-targets-drawer" aria-label="Close Targets Panel"><i data-lucide="x" class="ui-icon"></i></button>
321
+ </div>
322
+ </div>
323
+
324
+ <!-- Drawer Navigation Tabs -->
325
+ <div class="targets-drawer-tabs">
326
+ <button type="button" class="drawer-tab-btn active" data-tab="targets-tab">
327
+ <i data-lucide="crosshair" class="tab-icon"></i>
328
+ <span>Marked Targets</span>
329
+ </button>
330
+ <button type="button" class="drawer-tab-btn" data-tab="masscan-tab">
331
+ <i data-lucide="server" class="tab-icon"></i>
332
+ <span>Masscan</span>
333
+ </button>
334
+ <button type="button" class="drawer-tab-btn" data-tab="nuclei-tab">
335
+ <i data-lucide="shield-alert" class="tab-icon"></i>
336
+ <span>Nuclei</span>
337
+ </button>
338
+ </div>
339
+
340
+ <div class="targets-drawer-content">
341
+ <!-- TAB 1: Marked Targets & Execution Logs -->
342
+ <div class="drawer-tab-pane active" id="tab-pane-targets">
343
+ <!-- Top: Marked Targets Section -->
344
+ <div class="targets-section">
345
+ <div class="targets-section-title logs-header-row">
346
+ <div class="logs-title-left">
347
+ <i data-lucide="crosshair" class="ui-icon"></i>
348
+ <span>Marked Targets</span>
349
+ </div>
350
+ <button id="btn-clear-all-targets" class="btn-clear-logs" title="Remove all targets from list">
351
+ <i data-lucide="trash-2" class="ui-icon"></i>
352
+ <span>Clear All</span>
353
+ </button>
354
+ </div>
355
+ <div id="targets-list-container" class="targets-list-container">
356
+ <div class="targets-empty-state" id="targets-empty-state">
357
+ <i data-lucide="crosshair" class="empty-icon"></i>
358
+ <p>No IP targets marked yet.</p>
359
+ <span class="empty-hint">Right-click any IP Address or Organization node on the graph and select <strong>"Set as Target"</strong> to add.</span>
360
+ </div>
361
+ <div id="targets-items-list" class="targets-items-list"></div>
362
+ </div>
363
+ </div>
364
+
365
+ <!-- Bottom: Execution Stream Logs -->
366
+ <div class="targets-section logs-section">
367
+ <div class="targets-section-title logs-header-row">
368
+ <div class="logs-title-left">
369
+ <i data-lucide="terminal" class="ui-icon"></i>
370
+ <span>Scan Execution Stream</span>
371
+ </div>
372
+ <button id="btn-clear-scan-logs" class="btn-clear-logs" title="Clear console logs">
373
+ <i data-lucide="eraser" class="ui-icon"></i>
374
+ <span>Clear</span>
375
+ </button>
376
+ </div>
377
+ <div class="scan-live-console" id="scan-live-console">
378
+ <div class="console-line info">[System] Ready to scan targets and vulnerabilities.</div>
379
+ </div>
380
+ </div>
381
+ </div>
382
+
383
+ <!-- TAB 2: Masscan Port Scanner -->
384
+ <div class="drawer-tab-pane" id="tab-pane-masscan" style="display: none;">
385
+ <!-- Global Actions -->
386
+ <div class="targets-global-actions">
387
+ <button id="btn-scan-all-targets" class="btn-primary-action scan-all-btn" title="Run Masscan port scan on marked targets">
388
+ <i data-lucide="play" class="ui-icon"></i>
389
+ <span>Run Masscan on Targets</span>
390
+ </button>
391
+ </div>
392
+
393
+ <!-- Scan Configuration Section (Masscan Flags) -->
394
+ <div class="targets-section config-section">
395
+ <div class="targets-section-title">
396
+ <i data-lucide="sliders" class="ui-icon"></i>
397
+ <span>Masscan Port Scan Configuration</span>
398
+ </div>
399
+
400
+ <!-- Presets -->
401
+ <div class="form-group">
402
+ <label class="form-label">Port Preset:</label>
403
+ <div class="preset-buttons-group">
404
+ <button type="button" class="preset-btn active" data-preset="top100">Top 100</button>
405
+ <button type="button" class="preset-btn" data-preset="web">Web Ports</button>
406
+ <button type="button" class="preset-btn" data-preset="all">All Ports (0-65535)</button>
407
+ <button type="button" class="preset-btn" data-preset="custom">Custom</button>
408
+ </div>
409
+ </div>
410
+
411
+ <!-- Custom Ports Input (shown when custom selected or editable) -->
412
+ <div class="form-group" id="custom-ports-group" style="display: none;">
413
+ <label for="input-custom-ports" class="form-label">Custom Ports Specification:</label>
414
+ <input type="text" id="input-custom-ports" class="drawer-text-input" placeholder="e.g. -p21-25,80,443,3306,8080 or --top-ports 50" value="--top-ports 100">
415
+ </div>
416
+
417
+ <!-- Performance / Rate Slider -->
418
+ <div class="form-group">
419
+ <div class="slider-header">
420
+ <label for="input-scan-rate" class="form-label">Scan Rate (Packets/sec):</label>
421
+ <span id="scan-rate-display" class="rate-value-badge">1000 pps</span>
422
+ </div>
423
+ <input type="range" id="input-scan-rate" min="100" max="10000" step="100" value="1000" class="drawer-range-slider">
424
+ <div class="slider-ticks">
425
+ <span>100</span>
426
+ <span>1000</span>
427
+ <span>5000</span>
428
+ <span>10000</span>
429
+ </div>
430
+ </div>
431
+
432
+ <!-- Checkboxes -->
433
+ <div class="form-group checkboxes-group">
434
+ <label class="drawer-checkbox-label">
435
+ <input type="checkbox" id="chk-scan-pn" checked>
436
+ <span class="custom-checkbox"></span>
437
+ <span>-Pn (Disable ping / host discovery)</span>
438
+ </label>
439
+ <label class="drawer-checkbox-label">
440
+ <input type="checkbox" id="chk-scan-banners" checked>
441
+ <span class="custom-checkbox"></span>
442
+ <span>--banners (Banner grabbing & service detection)</span>
443
+ </label>
444
+ </div>
445
+
446
+ <!-- Extra Parameters -->
447
+ <div class="form-group">
448
+ <label for="input-extra-flags" class="form-label">Custom Flags / Extra Parameters:</label>
449
+ <input type="text" id="input-extra-flags" class="drawer-text-input" placeholder="e.g. --adapter-ip 192.168.1.50">
450
+ </div>
451
+ </div>
452
+ </div>
453
+
454
+ <!-- TAB 3: Vulnerability Scan (Nuclei) -->
455
+ <div class="drawer-tab-pane" id="tab-pane-nuclei" style="display: none;">
456
+ <div class="targets-global-actions">
457
+ <button id="btn-run-all-nuclei" class="btn-primary-action btn-nuclei-action" title="Run Nuclei vulnerability scan on all targets">
458
+ <i data-lucide="shield-alert" class="ui-icon"></i>
459
+ <span>Run Nuclei on All Targets</span>
460
+ </button>
461
+ </div>
462
+
463
+ <!-- Severity Selection -->
464
+ <div class="targets-section">
465
+ <div class="targets-section-title">
466
+ <i data-lucide="alert-triangle" class="ui-icon"></i>
467
+ <span>Vulnerability Severity Filter</span>
468
+ </div>
469
+ <div class="form-group checkboxes-group">
470
+ <label class="drawer-checkbox-label sev-critical">
471
+ <input type="checkbox" id="chk-nuclei-sev-critical" checked>
472
+ <span class="custom-checkbox custom-checkbox-red"></span>
473
+ <span class="sev-tag-label sev-critical-text">Critical</span>
474
+ </label>
475
+ <label class="drawer-checkbox-label sev-high">
476
+ <input type="checkbox" id="chk-nuclei-sev-high" checked>
477
+ <span class="custom-checkbox custom-checkbox-orange"></span>
478
+ <span class="sev-tag-label sev-high-text">High</span>
479
+ </label>
480
+ <label class="drawer-checkbox-label sev-medium">
481
+ <input type="checkbox" id="chk-nuclei-sev-medium">
482
+ <span class="custom-checkbox custom-checkbox-yellow"></span>
483
+ <span class="sev-tag-label sev-medium-text">Medium</span>
484
+ </label>
485
+ <label class="drawer-checkbox-label sev-low">
486
+ <input type="checkbox" id="chk-nuclei-sev-low">
487
+ <span class="custom-checkbox custom-checkbox-blue"></span>
488
+ <span class="sev-tag-label sev-low-text">Low</span>
489
+ </label>
490
+ <label class="drawer-checkbox-label sev-info">
491
+ <input type="checkbox" id="chk-nuclei-sev-info">
492
+ <span class="custom-checkbox custom-checkbox-slate"></span>
493
+ <span class="sev-tag-label sev-info-text">Info</span>
494
+ </label>
495
+ </div>
496
+ </div>
497
+
498
+ <!-- Template Tags Presets & Custom Tags -->
499
+ <div class="targets-section">
500
+ <div class="targets-section-title">
501
+ <i data-lucide="tags" class="ui-icon"></i>
502
+ <span>Template Tags Selection</span>
503
+ </div>
504
+ <div class="form-group">
505
+ <label class="form-label">Preset Tags:</label>
506
+ <div class="nuclei-tags-grid">
507
+ <label class="tag-chip-label">
508
+ <input type="checkbox" class="chk-nuclei-tag" value="cve" checked>
509
+ <span class="tag-chip">cve</span>
510
+ </label>
511
+ <label class="tag-chip-label">
512
+ <input type="checkbox" class="chk-nuclei-tag" value="exposure">
513
+ <span class="tag-chip">exposure</span>
514
+ </label>
515
+ <label class="tag-chip-label">
516
+ <input type="checkbox" class="chk-nuclei-tag" value="panel">
517
+ <span class="tag-chip">panel</span>
518
+ </label>
519
+ <label class="tag-chip-label">
520
+ <input type="checkbox" class="chk-nuclei-tag" value="default-credentials">
521
+ <span class="tag-chip">default-credentials</span>
522
+ </label>
523
+ <label class="tag-chip-label">
524
+ <input type="checkbox" class="chk-nuclei-tag" value="misconfig">
525
+ <span class="tag-chip">misconfig</span>
526
+ </label>
527
+ <label class="tag-chip-label">
528
+ <input type="checkbox" class="chk-nuclei-tag" value="takeover">
529
+ <span class="tag-chip">takeover</span>
530
+ </label>
531
+ </div>
532
+ </div>
533
+
534
+ <div class="form-group">
535
+ <label for="input-nuclei-custom-tags" class="form-label">Additional Custom Tags (comma-separated):</label>
536
+ <input type="text" id="input-nuclei-custom-tags" class="drawer-text-input" placeholder="e.g. ssl, rce, lfi, tech">
537
+ </div>
538
+ </div>
539
+
540
+ <!-- Performance Controls -->
541
+ <div class="targets-section">
542
+ <div class="targets-section-title">
543
+ <i data-lucide="gauge" class="ui-icon"></i>
544
+ <span>Performance Controls</span>
545
+ </div>
546
+ <div class="nuclei-perf-grid">
547
+ <div class="form-group">
548
+ <label for="input-nuclei-rate-limit" class="form-label">Rate Limit (-rl):</label>
549
+ <input type="number" id="input-nuclei-rate-limit" class="drawer-text-input" value="150" min="10" max="2000" step="10">
550
+ <span class="input-hint">req/sec</span>
551
+ </div>
552
+ <div class="form-group">
553
+ <label for="input-nuclei-concurrency" class="form-label">Concurrency (-c):</label>
554
+ <input type="number" id="input-nuclei-concurrency" class="drawer-text-input" value="25" min="1" max="200" step="5">
555
+ <span class="input-hint">parallel templates</span>
556
+ </div>
557
+ </div>
558
+ <div class="form-group">
559
+ <label for="input-nuclei-custom-flags" class="form-label">Extra Nuclei CLI Flags:</label>
560
+ <input type="text" id="input-nuclei-custom-flags" class="drawer-text-input" placeholder="e.g. -retries 2 -timeout 10">
561
+ </div>
562
+ </div>
563
+ </div>
564
+ </div>
565
+ </div>
566
+
567
+ <!-- Custom Node Right-Click Context Menu -->
568
+ <div id="cy-context-menu" class="cy-context-menu"></div>
569
+ </div>
570
+
571
+ <!-- Delete Database Confirmation Modal -->
572
+ <div class="modal-backdrop" id="delete-db-modal" style="display: none;">
573
+ <div class="modal-dialog delete-db-modal-dialog">
574
+ <div class="modal-header">
575
+ <div class="modal-title-row">
576
+ <i data-lucide="alert-triangle" class="ui-icon modal-danger-icon" style="color: #ef4444;"></i>
577
+ <h3>Delete Database</h3>
578
+ </div>
579
+ <button type="button" class="modal-close-btn" id="btn-close-delete-db-modal" aria-label="Close">
580
+ <i data-lucide="x" class="ui-icon"></i>
581
+ </button>
582
+ </div>
583
+ <div class="modal-body">
584
+ <p>Are you sure you want to delete database <strong id="delete-db-target-name" style="color: var(--cyan-accent, #00f0ff);"></strong>?</p>
585
+ <p class="modal-warning-text" style="color: var(--text-muted); font-size: 0.82rem; margin-top: 0.5rem; line-height: 1.4;">
586
+ This will permanently remove the SQLite file and all associated asset topology findings. This action cannot be undone.
587
+ </p>
588
+ </div>
589
+ <div class="modal-footer">
590
+ <button type="button" class="action-btn modal-cancel-btn" id="btn-cancel-delete-db">Cancel</button>
591
+ <button type="button" class="action-btn modal-danger-btn" id="btn-confirm-delete-db" style="background: #dc2626; border-color: #ef4444; color: #fff;">
592
+ <i data-lucide="trash-2" class="ui-icon" style="width: 14px; height: 14px;"></i>
593
+ <span>Delete Database</span>
594
+ </button>
595
+ </div>
596
+ </div>
597
+ </div>
598
+
599
+ <script src="/static/js/api.js?v=10"></script>
600
+ <script src="/static/js/graph.js?v=75"></script>
601
+
602
+ <script>
603
+ // Debug logging & icon initialization
604
+ console.log('DetecTI-CLI Dashboard loaded');
605
+ console.log('Cytoscape available:', typeof cytoscape !== 'undefined');
606
+ console.log('Current URL:', window.location.href);
607
+
608
+ document.addEventListener('DOMContentLoaded', () => {
609
+ if (typeof lucide !== 'undefined') {
610
+ lucide.createIcons();
611
+ }
612
+
613
+ const requiredElements = [
614
+ 'btn-toggle-targets', 'domains-count', 'subdomains-count',
615
+ 'ips-count', 'services-count', 'vulns-count', 'kev-count',
616
+ 'cy', 'graph-loading'
617
+ ];
618
+
619
+ requiredElements.forEach(id => {
620
+ const el = document.getElementById(id);
621
+ if (!el) {
622
+ console.error(`Required element missing: ${id}`);
623
+ }
624
+ });
625
+ });
626
+ </script>
627
+
628
+ <!-- Floating Leads Modal -->
629
+ <div id="floating-leads-modal" class="modal" style="display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 450px; max-width: 90vw; max-height: 85vh; background: #1e1e2d; border: 1px solid #333; border-radius: 8px; z-index: 10000; box-shadow: 0 10px 30px rgba(0,0,0,0.5); flex-direction: column;">
630
+ <div style="padding: 15px; border-bottom: 1px solid #333; display: flex; justify-content: space-between; align-items: center; background: #252536; border-radius: 8px 8px 0 0;">
631
+ <h3 style="margin: 0; color: #fff; font-size: 1.1rem; display: flex; align-items: center; gap: 8px;">
632
+ <i data-lucide="compass" style="width: 18px; height: 18px; color: #00f0ff;"></i> Explore Leads
633
+ </h3>
634
+ <button id="close-floating-leads" style="background: none; border: none; color: #999; cursor: pointer; font-size: 1.5rem; line-height: 1;">&times;</button>
635
+ </div>
636
+ <div style="padding: 15px; border-bottom: 1px solid #333; display: flex; gap: 10px; background: #2a2a3c;">
637
+ <button onclick="window.dashboard.selectAllLeads()" style="flex: 1; padding: 8px; background: rgba(0, 240, 255, 0.15); color: #00f0ff; border: 1px solid rgba(0, 240, 255, 0.3); border-radius: 4px; cursor: pointer; font-weight: bold;">Expand All Leads</button>
638
+ <button onclick="window.dashboard.deselectAllLeads()" style="flex: 1; padding: 8px; background: rgba(255, 255, 255, 0.05); color: #ccc; border: 1px solid #444; border-radius: 4px; cursor: pointer;">Collapse All</button>
639
+ </div>
640
+ <div style="padding: 10px 15px; border-bottom: 1px solid #333; background: #1e1e2d;">
641
+ <input type="text" id="explore-leads-search" placeholder="Search leads by name or IP..." onkeyup="window.dashboard.filterExploreLeads(this.value)" style="width: 100%; box-sizing: border-box; padding: 8px 12px; background: #252536; border: 1px solid #444; border-radius: 4px; color: #fff; font-size: 0.9rem;">
642
+ </div>
643
+ <div id="floating-leads-content" style="padding: 15px; overflow-y: auto; flex: 1;">
644
+ <div id="lead-list" class="lead-list">
645
+ <div class="lead-loading">Fetching leads...</div>
646
+ </div>
647
+ </div>
648
+ </div>
649
+
650
+
651
+ <script>
652
+ document.addEventListener('DOMContentLoaded', () => {
653
+ const logoutBtn = document.getElementById('btn-logout');
654
+ if (logoutBtn) {
655
+ logoutBtn.addEventListener('click', async () => {
656
+ logoutBtn.style.opacity = '0.5';
657
+ logoutBtn.innerHTML = '<i data-lucide="loader" class="ui-icon" style="animation: spin 1s linear infinite;"></i> Terminating...';
658
+ if (window.lucide) window.lucide.createIcons();
659
+
660
+ try {
661
+ const response = await fetch('/api/v1/auth/logout', { method: 'POST' });
662
+ if (response.ok) {
663
+ window.location.reload();
664
+ } else {
665
+ alert('Failed to terminate session properly. Check backend.');
666
+ }
667
+ } catch (e) {
668
+ alert('Network error during logout.');
669
+ }
670
+ logoutBtn.style.opacity = '1';
671
+ });
672
+ }
673
+ });
674
+ </script>
675
+
676
+ </body>
677
+ </html>