new options

This commit is contained in:
Mateusz Gruszczyński
2025-11-03 09:25:56 +01:00
parent 80a0d22d4e
commit 8683af493f
2 changed files with 46 additions and 188 deletions

View File

@@ -1,38 +1,44 @@
(() => { (() => {
'use strict'; 'use strict';
// Toggle health check fields based on protocol // Helper functions (shared)
const $ = (sel, root = document) => root.querySelector(sel);
const $$ = (sel, root = document) => Array.from(root.querySelectorAll(sel));
// ===== HEALTH CHECK FIELDS (Protocol-dependent) =====
const protocolSelect = document.getElementById('protocol'); const protocolSelect = document.getElementById('protocol');
const healthCheckFields = document.getElementById('health_check_fields'); const healthCheckFields = document.getElementById('health_check_fields');
const tcpHealthCheck = document.getElementById('tcp_health_check'); const tcpHealthCheck = document.getElementById('tcp_health_check');
const onProtocolChange = () => { const onProtocolChange = () => {
if (protocolSelect?.value === 'http') { if (protocolSelect?.value === 'http') {
document.getElementById('health_check')?.parentElement.parentElement.style.display = 'block'; const healthCheckParent = document.getElementById('health_check')?.parentElement.parentElement;
tcpHealthCheck.style.display = 'none'; if (healthCheckParent) healthCheckParent.style.display = 'block';
if (tcpHealthCheck) tcpHealthCheck.style.display = 'none';
} else { } else {
document.getElementById('health_check')?.parentElement.parentElement.style.display = 'none'; const healthCheckParent = document.getElementById('health_check')?.parentElement.parentElement;
tcpHealthCheck.style.display = 'flex'; if (healthCheckParent) healthCheckParent.style.display = 'none';
if (tcpHealthCheck) tcpHealthCheck.style.display = 'flex';
} }
}; };
protocolSelect?.addEventListener('change', onProtocolChange); protocolSelect?.addEventListener('change', onProtocolChange);
// Toggle sticky session fields // ===== STICKY SESSION FIELDS =====
const stickyCheckbox = document.getElementById('sticky_session'); const stickyCheckbox = document.getElementById('sticky_session');
const stickyFields = document.getElementById('sticky_fields'); const stickyFields = document.getElementById('sticky_fields');
stickyCheckbox?.addEventListener('change', function() { stickyCheckbox?.addEventListener('change', function() {
stickyFields.classList.toggle('d-none', !this.checked); stickyFields?.classList.toggle('d-none', !this.checked);
}); });
// Toggle health check link field // ===== HEALTH CHECK LINK FIELD =====
const healthCheckbox = document.getElementById('health_check'); const healthCheckbox = document.getElementById('health_check');
healthCheckbox?.addEventListener('change', function() { healthCheckbox?.addEventListener('change', function() {
document.getElementById('health_check_fields')?.classList.toggle('d-none', !this.checked); document.getElementById('health_check_fields')?.classList.toggle('d-none', !this.checked);
}); });
// Toggle header fields // ===== CUSTOM HEADER FIELDS =====
const headerCheckbox = document.getElementById('add_header'); const headerCheckbox = document.getElementById('add_header');
const headerFields = document.querySelectorAll('#header_fields'); const headerFields = document.querySelectorAll('#header_fields');
@@ -40,80 +46,7 @@
headerFields.forEach(field => field.classList.toggle('d-none', !this.checked)); headerFields.forEach(field => field.classList.toggle('d-none', !this.checked));
}); });
// Helper functions // ===== NO-LB MODE HANDLING =====
const $ = (sel, root = document) => root.querySelector(sel);
const $$ = (sel, root = document) => Array.from(root.querySelectorAll(sel));
const toggle = (on, el) => el.classList.toggle('d-none', !on);
// SSL fields
const sslCheckbox = $('#ssl_checkbox');
const sslFields = $('#ssl_fields');
sslCheckbox?.addEventListener('change', () => toggle(sslCheckbox.checked, sslFields));
// DOS
const dosCheckbox = $('#add_dos');
const dosFields = $('#dos_fields');
dosCheckbox?.addEventListener('change', () => toggle(dosCheckbox.checked, dosFields));
// HTTP only groups
const httpGroups = $$('.http-only, #forbidden_acl_container');
const httpToggles = [
$('#sql_injection_check'),
$('#xss_check'),
$('#remote_uploads_check'),
$('#webshells_check'),
$('#forward_for_check'),
$('#add_acl_path'),
$('#add_path_based'),
];
const forbiddenFields = $('#forbidden_fields');
const pathFields = $('#base_redirect_fields');
const onProtocolChangeExtended = () => {
const isHttp = protocolSelect?.value === 'http';
httpGroups.forEach(el => toggle(isHttp, el));
if (!isHttp) {
[forbiddenFields, pathFields].forEach(el => el && toggle(false, el));
httpToggles.forEach(input => {
if (input) input.checked = false;
});
}
};
protocolSelect?.addEventListener('change', onProtocolChangeExtended);
onProtocolChangeExtended();
// ACL
const aclCheckbox = $('#add_acl');
const aclFields = $('#acl_fields');
aclCheckbox?.addEventListener('change', () => toggle(aclCheckbox.checked, aclFields));
// toggles that reveal their fields
const bindToggle = (checkboxSel, targetSel) => {
const cb = $(checkboxSel);
const target = $(targetSel);
cb?.addEventListener('change', () => toggle(cb.checked, target));
if (cb && target) toggle(cb.checked, target);
};
bindToggle('#add_path_based', '#base_redirect_fields');
bindToggle('#add_acl_path', '#forbidden_fields');
// Backend SSL redirect
const backendSslCheckbox = $('#backend_ssl_redirect');
const backendSslFields = $('#backend_ssl_fields');
backendSslCheckbox?.addEventListener('change', function() {
toggle(this.checked, backendSslFields);
if (this.checked) {
// Show frontend port field
document.getElementById('ssl_redirect_port')?.parentElement.classList.remove('d-none');
}
});
// LB Method - obsługa trybu no-lb
const lbMethodSelect = $('#lb_method'); const lbMethodSelect = $('#lb_method');
const backendServersContainer = $('#backend_servers_container'); const backendServersContainer = $('#backend_servers_container');
const addServerBtn = $('#add_backend_btn'); const addServerBtn = $('#add_backend_btn');
@@ -153,7 +86,7 @@
lbMethodSelect?.addEventListener('change', onLbMethodChange); lbMethodSelect?.addEventListener('change', onLbMethodChange);
if (lbMethodSelect) onLbMethodChange(); if (lbMethodSelect) onLbMethodChange();
// Backend rows // ===== BACKEND SERVER ROWS (Dynamic Add/Remove) =====
let serverCount = 1; let serverCount = 1;
const container = $('#backend_servers_container'); const container = $('#backend_servers_container');
const addBtn = $('#add_backend_btn'); const addBtn = $('#add_backend_btn');
@@ -200,4 +133,5 @@
e.target.closest('.backend-server-row').remove(); e.target.closest('.backend-server-row').remove();
} }
}); });
})(); })();

View File

@@ -1,22 +1,22 @@
(() => { (() => {
'use strict'; 'use strict';
const $ = (sel, root=document) => root.querySelector(sel); // ===== HELPER FUNCTIONS =====
const $$ = (sel, root=document) => Array.from(root.querySelectorAll(sel)); const $ = (sel, root = document) => root.querySelector(sel);
const $$ = (sel, root = document) => Array.from(root.querySelectorAll(sel));
const toggle = (on, el) => el && el.classList.toggle('d-none', !on);
// SSL fields // ===== SSL FIELDS =====
const sslCheckbox = $('#ssl_checkbox'); const sslCheckbox = $('#ssl_checkbox');
const sslFields = $('#ssl_fields'); const sslFields = $('#ssl_fields');
const toggle = (on, el) => el.classList.toggle('d-none', !on);
sslCheckbox?.addEventListener('change', () => toggle(sslCheckbox.checked, sslFields)); sslCheckbox?.addEventListener('change', () => toggle(sslCheckbox.checked, sslFields));
// DOS // ===== DOS PROTECTION =====
const dosCheckbox = $('#add_dos'); const dosCheckbox = $('#add_dos');
const dosFields = $('#dos_fields'); const dosFields = $('#dos_fields');
dosCheckbox?.addEventListener('change', () => toggle(dosCheckbox.checked, dosFields)); dosCheckbox?.addEventListener('change', () => toggle(dosCheckbox.checked, dosFields));
// HTTP only groups // ===== PROTOCOL CHANGE (HTTP/TCP) =====
const protocolSelect = $('#protocol'); const protocolSelect = $('#protocol');
const httpGroups = $$('.http-only, #forbidden_acl_container'); const httpGroups = $$('.http-only, #forbidden_acl_container');
const httpToggles = [ const httpToggles = [
@@ -37,8 +37,7 @@
httpGroups.forEach(el => toggle(isHttp, el)); httpGroups.forEach(el => toggle(isHttp, el));
if (!isHttp) { if (!isHttp) {
// hide optional groups if protocol != http [forbiddenFields, pathFields].forEach(el => toggle(false, el));
[forbiddenFields, pathFields].forEach(el => el && toggle(false, el));
httpToggles.forEach(input => { httpToggles.forEach(input => {
if (input) input.checked = false; if (input) input.checked = false;
}); });
@@ -48,103 +47,28 @@
protocolSelect?.addEventListener('change', onProtocolChange); protocolSelect?.addEventListener('change', onProtocolChange);
onProtocolChange(); onProtocolChange();
// ACL // ===== ACL FIELDS =====
const aclCheckbox = $('#add_acl'); const aclCheckbox = $('#add_acl');
const aclFields = $('#acl_fields'); const aclFields = $('#acl_fields');
aclCheckbox?.addEventListener('change', () => toggle(aclCheckbox.checked, aclFields)); aclCheckbox?.addEventListener('change', () => toggle(aclCheckbox.checked, aclFields));
// toggles that reveal their fields // ===== GENERIC TOGGLE BINDER =====
const bindToggle = (checkboxSel, targetSel) => { const bindToggle = (checkboxSel, targetSel) => {
const cb = $(checkboxSel); const cb = $(checkboxSel);
const target = $(targetSel); const target = $(targetSel);
cb?.addEventListener('change', () => toggle(cb.checked, target)); cb?.addEventListener('change', () => toggle(cb.checked, target));
// initial
if (cb && target) toggle(cb.checked, target); if (cb && target) toggle(cb.checked, target);
}; };
bindToggle('#add_path_based', '#base_redirect_fields'); bindToggle('#add_path_based', '#base_redirect_fields');
bindToggle('#add_acl_path', '#forbidden_fields'); bindToggle('#add_acl_path', '#forbidden_fields');
const lbMethodSelect = $('#lb_method'); // ===== BACKEND SSL REDIRECT =====
const backendServersContainer = $('#backend_servers_container'); const backendSslCheckbox = $('#backend_ssl_redirect');
const addServerBtn = $('#add_backend_btn'); const backendSslFields = $('#backend_ssl_fields');
const onLbMethodChange = () => { backendSslCheckbox?.addEventListener('change', function() {
const isNoLb = lbMethodSelect?.value === 'no-lb'; toggle(this.checked, backendSslFields);
if (isNoLb) {
if (addServerBtn) addServerBtn.classList.add('d-none');
const serverRows = $$('.backend-server-row', backendServersContainer);
serverRows.forEach((row, idx) => {
if (idx > 0) row.remove();
});
if (!$('.no-lb-info')) {
const info = document.createElement('div');
info.className = 'alert alert-info alert-sm no-lb-info mt-2';
info.innerHTML = '<i class="bi bi-info-circle me-2"></i><small>Tryb <strong>no-lb</strong>: frontend → backend → pojedynczy serwer. Możesz włączyć XSS, DOS, SQL injection protection itp.</small>';
if (backendServersContainer?.parentElement) {
backendServersContainer.parentElement.appendChild(info);
}
}
} else {
if (addServerBtn) addServerBtn.classList.remove('d-none');
const info = $('.no-lb-info');
if (info) info.remove();
}
};
lbMethodSelect?.addEventListener('change', onLbMethodChange);
// Wywołaj na starcie
if (lbMethodSelect) onLbMethodChange();
// Backend rows
let serverCount = 1;
const container = $('#backend_servers_container');
const addBtn = $('#add_backend_btn');
const createRow = () => {
serverCount++;
const row = document.createElement('div');
row.className = 'row g-3 backend-server-row mt-1';
row.innerHTML = `
<div class="col-md-3">
<input type="text" class="form-control" name="backend_server_names[]" placeholder="server${serverCount}" required>
</div>
<div class="col-md-4">
<input type="text" class="form-control" name="backend_server_ips[]" placeholder="192.168.1.${serverCount}" required>
</div>
<div class="col-md-2">
<input type="number" class="form-control" name="backend_server_ports[]" placeholder="80" min="1" max="65535" required>
</div>
<div class="col-md-2">
<input type="number" class="form-control" name="backend_server_maxconns[]" placeholder="100">
</div>
<div class="col-md-1">
<button type="button" class="btn btn-danger btn-sm w-100 remove-server">
<i class="bi bi-trash"></i>
</button>
</div>
`;
const removeBtn = row.querySelector('.remove-server');
removeBtn.addEventListener('click', () => row.remove());
return row;
};
addBtn?.addEventListener('click', () => {
if (container) {
container.appendChild(createRow());
}
}); });
// Remove button for dynamically added rows
container?.addEventListener('click', (e) => {
if (e.target.closest('.remove-server')) {
e.target.closest('.backend-server-row').remove();
}
});
})(); })();