lanscape 1.3.4__py3-none-any.whl → 1.3.5a1__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.
@@ -117,6 +117,7 @@ hr {
117
117
  }
118
118
  h1.title{
119
119
  cursor: pointer;
120
+ margin: 0;
120
121
  }
121
122
  .title span {
122
123
  color: var(--text-accent-color);
@@ -163,18 +164,21 @@ details {
163
164
  border-radius: 5px !important; /* override bootstrap stuff */
164
165
  padding-right: 34px;
165
166
  margin-right: -34px;
167
+ margin-left: -41px;
168
+ padding-left: calc(41px + 5px);
166
169
  }
167
170
 
168
171
 
169
172
  #scan-form .input-group button {
170
173
  background-color: var(--primary-bg-accent);
171
174
  border: 0;
172
- border-left: 1px var(--border-color) solid;
175
+
173
176
  transition: all .2s ease-in-out;
174
177
  height: 40px;
175
- border-radius: 0 5px 5px 0;
176
178
  margin-top: 1px;
177
179
  transform: translateX(.5px);
180
+ z-index: 3;
181
+ margin-left: 0;
178
182
  }
179
183
  #scan-form .input-group button:hover {
180
184
  background-color: var(--primary-bg-accent-hover);
@@ -182,6 +186,15 @@ details {
182
186
  #scan-form .input-group button:active {
183
187
  background-color: var(--primary-accent);
184
188
  }
189
+ #scan-form .input-group button.start {
190
+ border-radius: 5px 0 0 5px;
191
+ border-right: 1px var(--border-color) solid;
192
+ width: 40px; /* added because it looks gross on icon load */
193
+ }
194
+ #scan-form .input-group button.end {
195
+ border-radius: 0 5px 5px 0;
196
+ border-left: 1px var(--border-color) solid;
197
+ }
185
198
 
186
199
  .label-container {
187
200
  display: flex;
@@ -256,8 +269,69 @@ details {
256
269
  }
257
270
  }
258
271
 
272
+ #advanced-modal {
273
+ --bs-modal-width: 750px;
274
+ }
275
+ #advanced-modal .modal-content {
276
+ background-color: var(--primary-bg);
277
+ }
278
+ #advanced-modal .descriptor {
279
+ align-content: end;
280
+ text-align: center;
281
+ color: var(--text-placeholder);
282
+ padding-bottom: 10px;
283
+ }
284
+ #advanced-modal .col-2-percent {
285
+ flex: 0 0 auto;
286
+ width: 2%;
287
+ }
288
+ #advanced-modal label {
289
+ font-size: 12px;
290
+ }
291
+ #advanced-modal .form-check {
292
+ width: fit-content;
293
+ }
294
+ #advanced-modal h6 {
295
+ color: var(--primary-accent);
296
+ }
297
+ #advanced-modal .config-option {
298
+ background-color: var(--primary-bg-accent);
299
+ border: 1px solid var(--border-color);
300
+ border-radius: 5px;
301
+ cursor: pointer;
302
+ text-align: center;
303
+ margin: 0 5px;
304
+ transition: all .2s ease-in-out;
305
+ }
259
306
 
260
-
307
+ #advanced-modal .config-option.active {
308
+ border-color: var(--primary-accent);
309
+ box-shadow: 0 0 5px var(--primary-accent);
310
+ background-color: var(--primary-bg);
311
+ }
312
+ #advanced-modal .config-option:hover {
313
+ background-color: var(--primary-bg);
314
+ box-shadow: 0 0 5px var(--primary-accent);
315
+ }
316
+ #advanced-modal .config-option.active:hover {
317
+ background-color: var(--primary-bg-accent);
318
+ box-shadow: 0 0 5px var(--primary-accent);
319
+ }
320
+ #advanced-modal .config-option h5 {
321
+ flex-wrap: wrap;
322
+ }
323
+ #advanced-modal .config-option h5 span {
324
+ display: block; /* "waaaah span shouldnt be block" bite me. */
325
+ width: 100%;
326
+ padding: 5px;
327
+ font-size: 2em;
328
+ }
329
+ #advanced-modal .config-option p {
330
+ font-size: 0.8em;
331
+ color: var(--text-placeholder);
332
+ margin: 0;
333
+ padding: 5px;
334
+ }
261
335
 
262
336
 
263
337
  /* Card Styles */
@@ -286,7 +360,7 @@ form {
286
360
  flex-grow: 1;
287
361
  display: flex;
288
362
  flex-direction: column;
289
- margin-bottom: 15px;
363
+ margin-bottom: 5px;
290
364
  }
291
365
 
292
366
  label {
@@ -310,6 +384,12 @@ input[type="text"]:focus, select:focus, .form-control:focus {
310
384
  border-color: var(--primary-accent);
311
385
  outline: none;
312
386
  }
387
+ input[type="text"]:read-only, .form-control:read-only {
388
+ background-color: var(--secondary-bg);
389
+ color: var(--text-placeholder);
390
+ border-color: var(--secondary-accent);
391
+ outline: none;
392
+ }
313
393
 
314
394
  input::placeholder {
315
395
  color: var(--text-placeholder) !important;
@@ -326,6 +406,7 @@ button {
326
406
  #scan-form #scan-submit {
327
407
  border: none;
328
408
  padding: 10px 20px;
409
+ margin-top: 15px;
329
410
  }
330
411
 
331
412
  /* Button Styling */
@@ -378,20 +459,6 @@ input[type="range"] {
378
459
  margin: 5px 0;
379
460
  }
380
461
 
381
- input[type="range"]::-webkit-slider-thumb,
382
- input[type="range"]::-moz-range-thumb {
383
- -webkit-appearance: none;
384
- appearance: none;
385
- width: 16px;
386
- height: 16px;
387
- border-radius: 50%;
388
- background: var(--primary-accent);
389
- cursor: pointer;
390
- }
391
- #parallelism-value span {
392
- color: var(--text-danger-color);
393
- font-weight: 500;
394
- }
395
462
  .port-list-wrapper {
396
463
  position: relative;
397
464
  display: inline-block;
@@ -400,12 +467,13 @@ input[type="range"]::-moz-range-thumb {
400
467
 
401
468
  .port-list {
402
469
  position: relative;
403
- background-color: var(--body-bg);
470
+ background-color: var(--secondary-bg);
404
471
  border: 1px solid var(--border-color);
405
472
  color: var(--text-color);
406
473
  padding: 10px;
407
474
  cursor: pointer;
408
475
  width: 100%;
476
+ height: 42px;
409
477
  user-select: none;
410
478
  appearance: none; /* Hide default arrow */
411
479
  transition: all .2s ease-in-out;
@@ -419,7 +487,7 @@ input[type="range"]::-moz-range-thumb {
419
487
  .port-list-wrapper::after {
420
488
  content: '▼';
421
489
  position: absolute;
422
- top: 14px;
490
+ top: 10px;
423
491
  right: 10px;
424
492
  pointer-events: none;
425
493
  color: var(--text-color);
@@ -451,6 +519,12 @@ input[type="range"]::-moz-range-thumb {
451
519
  color: var(--text-color);
452
520
  }
453
521
 
522
+
523
+
524
+ .text-color {
525
+ color: var(--text-color) !important;
526
+ }
527
+
454
528
  .text-secondary {
455
529
  color: var(--secondary-accent) !important;
456
530
  }
@@ -2,21 +2,15 @@
2
2
 
3
3
  $(document).ready(function() {
4
4
  // Load port lists into the dropdown
5
- getPortLists();
6
-
7
- $('#parallelism').on('input', function() {
8
- const val = $('#parallelism').val();
9
- let ans = val;
10
-
11
- if (parseFloat(val) > 1) {
12
- ans += ' <span>Warning: Increased parallelism may have inaccurate results<span>'
13
- }
14
- $('#parallelism-value').html(ans);
15
- });
16
5
  const scanId = getActiveScanId();
17
6
  if (scanId) {
18
7
  showScan(scanId);
19
8
  }
9
+
10
+ // this prevents the browser from
11
+ // triggering the shutdown beacon
12
+ // when user clicks the logo
13
+ setUrlParam('loaded', 'true')
20
14
 
21
15
 
22
16
  // Handle form submission
@@ -39,18 +33,19 @@ $(document).ready(function() {
39
33
  $('#ip-table-frame').attr('src', newSrc);
40
34
  });
41
35
 
36
+ $('#settings-btn').on('click', function() {
37
+ $('#advanced-modal').modal('show');
38
+ });
39
+
42
40
  });
43
41
 
44
42
  function submitNewScan() {
45
- const formData = {
46
- subnet: $('#subnet').val(),
47
- port_list: $('#port-list').text(),
48
- parallelism: $('#parallelism').val()
49
- };
43
+ const config = getScanConfig();
44
+ config.subnet = $('#subnet').val();
50
45
  $.ajax('/api/scan', {
51
- data : JSON.stringify(formData),
52
- contentType : 'application/json',
53
- type : 'POST',
46
+ data: JSON.stringify(config),
47
+ contentType: 'application/json',
48
+ type: 'POST',
54
49
  success: function(response) {
55
50
  if (response.status === 'running') {
56
51
  showScan(response.scan_id);
@@ -75,37 +70,9 @@ function showScan(scanId) {
75
70
  //$('#overview-frame').attr('src', '/scan/' + scanId + '/overview');
76
71
  $('#ip-table-frame').attr('src', '/scan/' + scanId + '/table');
77
72
 
78
- // set url query string 'scan_id' to the scan_id
79
- const url = new URL(window.location.href);
80
- url.searchParams.set('scan_id', scanId);
81
- // set url to the new url
82
- window.history.pushState({}, '', url);
73
+ setUrlParam('scan_id', scanId);
83
74
  }
84
75
 
85
- function getPortLists() {
86
- $.get('/api/port/list', function(data) {
87
- const customSelect = $('#port-list');
88
- const customSelectDropdown = $('#port-list-dropdown');
89
- customSelectDropdown.empty();
90
-
91
- // Populate the dropdown with the options
92
- data.forEach(function(portList) {
93
- customSelectDropdown.append('<div>' + portList + '</div>');
94
- });
95
-
96
- // Handle dropdown click
97
- customSelect.on('click', function() {
98
- customSelectDropdown.toggleClass('open');
99
- });
100
-
101
- // Handle option selection
102
- customSelectDropdown.on('click', 'div', function() {
103
- const selectedOption = $(this).text();
104
- customSelect.text(selectedOption);
105
- customSelectDropdown.removeClass('open');
106
- });
107
- });
108
- }
109
76
 
110
77
  $(document).on('click', function(event) {
111
78
  if (!$(event.target).closest('.port-list-wrapper').length) {
@@ -234,6 +201,16 @@ $('#ip-table-frame').on('load', function() {
234
201
  observeIframeContent(this); // Start observing for dynamic changes
235
202
  });
236
203
 
204
+ function setUrlParam(param, value) {
205
+ const url = new URL(window.location.href);
206
+ if (value === null || value === undefined) {
207
+ url.searchParams.delete(param);
208
+ } else {
209
+ url.searchParams.set(param, value);
210
+ }
211
+ window.history.pushState({}, '', url);
212
+ }
213
+
237
214
 
238
215
 
239
216
  $(window).on('resize', function() {
@@ -0,0 +1,107 @@
1
+ let defaultScanConfigs = {};
2
+ let activeConfigName = 'balanced';
3
+
4
+ $(document).ready(function() {
5
+ // load port lists
6
+ getPortLists(function() {
7
+ // THEN get scan config defaults
8
+ getScanDefaults(function() {
9
+ // THEN set the default scan config
10
+ setScanConfig('balanced');
11
+ })
12
+ });
13
+
14
+ $('#t_cnt_port_scan, #t_cnt_port_test').on('input', updatePortTotals);
15
+ $('#ping_attempts, #ping_ping_count').on('input', updatePingTotals);
16
+ });
17
+
18
+ function getScanDefaults(callback=null) {
19
+ $.getJSON('/api/tools/config/defaults', (data) => {
20
+ defaultScanConfigs = data;
21
+ if (callback) callback();
22
+ });
23
+ }
24
+
25
+ function setScanConfig(configName) {
26
+ const config = defaultScanConfigs[configName];
27
+ if (!config) return;
28
+ activeConfigName = configName;
29
+
30
+ // highlight selected preset
31
+ $('.config-option').removeClass('active');
32
+ $(`#config-${configName}`).addClass('active');
33
+
34
+ // basic settings
35
+ $('#port_list').val(config.port_list);
36
+ $('#t_multiplier').val(config.t_multiplier);
37
+ $('#t_cnt_port_scan').val(config.t_cnt_port_scan);
38
+ $('#t_cnt_port_test').val(config.t_cnt_port_test);
39
+ $('#t_cnt_isalive').val(config.t_cnt_isalive);
40
+ $('#task_scan_ports').prop('checked', config.task_scan_ports);
41
+ $('#task_scan_port_services').prop('checked', config.task_scan_port_services);
42
+ $('#lookup_type').val(config.lookup_type);
43
+
44
+ // ping config
45
+ $('#ping_attempts').val(config.ping_config.attempts);
46
+ $('#ping_ping_count').val(config.ping_config.ping_count);
47
+ $('#ping_retry_delay').val(config.ping_config.retry_delay);
48
+ $('#ping_timeout').val(config.ping_config.timeout);
49
+
50
+ // arp config
51
+ $('#arp_attempts').val(config.arp_config.attempts);
52
+ $('#arp_timeout').val(config.arp_config.timeout);
53
+
54
+ updatePortTotals();
55
+ updatePingTotals();
56
+ }
57
+
58
+ function getScanConfig() {
59
+ return {
60
+ port_list: $('#port_list').val(),
61
+ t_cnt_port_scan: parseInt($('#t_cnt_port_scan').val()),
62
+ t_cnt_port_test: parseInt($('#t_cnt_port_test').val()),
63
+ t_cnt_isalive: parseInt($('#t_cnt_isalive').val()),
64
+ task_scan_ports: $('#task_scan_ports').is(':checked'),
65
+ task_scan_port_services: $('#task_scan_port_services').is(':checked'),
66
+ lookup_type: $('#lookup_type').val(),
67
+ ping_config: {
68
+ attempts: parseInt($('#ping_attempts').val()),
69
+ ping_count: parseInt($('#ping_ping_count').val()),
70
+ retry_delay: parseFloat($('#ping_retry_delay').val()),
71
+ timeout: parseFloat($('#ping_timeout').val())
72
+ },
73
+ arp_config: {
74
+ attempts: parseInt($('#arp_attempts').val()),
75
+ timeout: parseFloat($('#arp_timeout').val())
76
+ }
77
+ };
78
+ }
79
+
80
+ function getPortLists(callback=null) {
81
+ $.get('/api/port/list', function(data) {
82
+ const customSelectDropdown = $('#port_list');
83
+ customSelectDropdown.empty();
84
+
85
+ // Populate the dropdown with the options
86
+ data.forEach(function(portList) {
87
+ customSelectDropdown.append('<option>' + portList + '</option>');
88
+ });
89
+ if (callback) callback();
90
+ });
91
+ }
92
+
93
+ function updatePortTotals() {
94
+ const scan = parseInt($('#t_cnt_port_scan').val()) || 0;
95
+ const test = parseInt($('#t_cnt_port_test').val()) || 0;
96
+ $('#total-port-tests').val(scan * test);
97
+ }
98
+
99
+ function updatePingTotals() {
100
+ const attempts = parseInt($('#ping_attempts').val()) || 0;
101
+ const count = parseInt($('#ping_ping_count').val()) || 0;
102
+ $('#total-ping-attempts').val(attempts * count);
103
+ }
104
+
105
+ // expose functions globally
106
+ window.setScanConfig = setScanConfig;
107
+ window.getScanConfig = getScanConfig;
@@ -13,7 +13,8 @@
13
13
  "type": "image/png"
14
14
  }
15
15
  ],
16
- "theme_color": "#0856a9",
17
- "background_color": "#1e1e1e",
18
- "display": "standalone"
16
+ "theme_color": "#0a84ff",
17
+ "background_color": "#262626",
18
+ "display": "minimal-ui"
19
+
19
20
  }
@@ -3,52 +3,54 @@
3
3
  {% block content %}
4
4
  <div id="header">
5
5
  <!-- Header and Scan Submission Inline -->
6
- <div class="d-flex justify-content-between align-items-center flex-wrap">
6
+ <div class="d-flex justify-content-between align-items-center flex-nowrap">
7
7
  <a href="/" class="text-decoration-none" aria-label="Go to homepage">
8
8
  <h1 class="title">
9
9
  <span>LAN</span>scape
10
10
  </h1>
11
11
  </a>
12
- <!-- Form -->
13
- <form id="scan-form" class="d-flex align-items-end">
14
- <div class="form-group me-2">
15
- <div class="label-container">
16
- <label for="subnet">Subnet:</label>
17
- <div id="subnet-info"></div>
12
+ <!-- Right side: settings + form -->
13
+ <div class="d-flex align-items-center justify-content-end ms-auto">
14
+ <form id="scan-form" class="d-flex align-items-center">
15
+ <div class="form-group me-2">
16
+ <!-- Above subnet input -->
17
+ <div class="label-container">
18
+ <label for="subnet">Subnet:</label>
19
+ <div id="subnet-info"></div>
20
+ </div>
21
+ <!-- Subnet input with dropdown -->
22
+ <div class="input-group">
23
+ <button
24
+ type="button"
25
+ id="settings-btn"
26
+ class="btn btn-secondary start material-symbols-outlined"
27
+ data-bs-toggle="tooltip"
28
+ data-bs-placement="bottom"
29
+ title="Advanced scan settings"
30
+ >
31
+ settings
32
+ </button>
33
+ <input type="text" id="subnet" name="subnet" class="form-control" value="{{ subnet }}" placeholder="Enter subnet">
34
+ <button class="btn btn-secondary dropdown-toggle end" type="button" id="subnet-dropdown" data-bs-toggle="dropdown" aria-expanded="false"></button>
35
+ <ul class="dropdown-menu" aria-labelledby="subnet-dropdown" id="dropdown-list">
36
+ {% for subnet_option in alternate_subnets %}
37
+ <li><a class="dropdown-item" href="#">{{ subnet_option['subnet'] }}</a></li>
38
+ {% endfor %}
39
+ </ul>
40
+ </div>
18
41
  </div>
19
- <div class="input-group">
20
- <input type="text" id="subnet" name="subnet" class="form-control" value="{{ subnet }}" placeholder="Enter subnet">
21
- <button class="btn btn-secondary dropdown-toggle" type="button" id="subnet-dropdown" data-bs-toggle="dropdown" aria-expanded="false"></button>
22
- <ul class="dropdown-menu" aria-labelledby="subnet-dropdown" id="dropdown-list">
23
- {% for subnet_option in alternate_subnets %}
24
- <li><a class="dropdown-item" href="#">{{ subnet_option['subnet'] }}</a></li>
25
- {% endfor %}
26
- </ul>
27
- </div>
28
- </div>
29
- <button type="submit" id="scan-submit" class="btn btn-primary mb-3">Scan</button>
30
- </form>
42
+ <button type="submit" id="scan-submit" class="btn btn-primary">Scan</button>
43
+ </form>
44
+ </div>
31
45
  </div>
32
46
 
33
- <!-- Advanced Section -->
34
- <details onclick="rightSizeDocLayout()">
35
- <summary>Advanced</summary>
36
- <div class="form-group mt-2">
37
- <label for="port_list">Port List:</label>
38
- <div class="port-list-wrapper">
39
- <div id="port-list" class="port-list">{{port_list}}</div>
40
- <div id="port-list-dropdown" class="port-list-dropdown"></div>
41
- </div>
42
- </div>
43
-
44
- <div class="form-group mt-2">
45
- <label for="parallelism">Parallelism:</label>
46
- <input type="range" id="parallelism" name="parallelism" min="0.25" max="3" step="0.05" value="{{parallelism}}">
47
- <output id="parallelism-value">{{parallelism}}</output>
48
- </div>
49
- </details>
50
47
  <div id="scan-progress-bar"></div>
51
48
  </div>
49
+
50
+ <!-- Advanced Settings Modal -->
51
+ {% include 'scan/config.html' %}
52
+
53
+
52
54
  <div id="content">
53
55
  <div class="container-fluid my-4">
54
56
  <!-- ARP Error -->
@@ -92,6 +94,7 @@
92
94
  <script src="{{ url_for('static', filename='js/main.js') }}"></script>
93
95
  <script src="{{ url_for('static', filename='js/subnet-info.js') }}"></script>
94
96
  <script src="{{ url_for('static', filename='js/subnet-selector.js') }}"></script>
97
+ <script src="{{ url_for('static', filename='js/scan-config.js') }}"></script>
95
98
  {% endblock %}
96
99
 
97
100