new_functions_and_fixes #1
@@ -1,136 +1,69 @@
|
|||||||
(() => {
|
(() => {
|
||||||
'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');
|
||||||
|
|
||||||
headerCheckbox?.addEventListener('change', function() {
|
headerCheckbox?.addEventListener('change', function() {
|
||||||
headerFields.forEach(field => field.classList.toggle('d-none', !this.checked));
|
headerFields.forEach(field => field.classList.toggle('d-none', !this.checked));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Helper functions
|
|
||||||
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() {
|
// ===== NO-LB MODE HANDLING =====
|
||||||
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');
|
||||||
|
|
||||||
const onLbMethodChange = () => {
|
const onLbMethodChange = () => {
|
||||||
const isNoLb = lbMethodSelect?.value === 'no-lb';
|
const isNoLb = lbMethodSelect?.value === 'no-lb';
|
||||||
|
|
||||||
if (isNoLb) {
|
if (isNoLb) {
|
||||||
// Hide add server button
|
// Hide add server button
|
||||||
if (addServerBtn) addServerBtn.classList.add('d-none');
|
if (addServerBtn) addServerBtn.classList.add('d-none');
|
||||||
|
|
||||||
// Keep only first server and remove others
|
// Keep only first server and remove others
|
||||||
const serverRows = $$('.backend-server-row', backendServersContainer);
|
const serverRows = $$('.backend-server-row', backendServersContainer);
|
||||||
serverRows.forEach((row, idx) => {
|
serverRows.forEach((row, idx) => {
|
||||||
if (idx > 0) row.remove();
|
if (idx > 0) row.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add info about no-lb mode if it doesn't exist
|
// Add info about no-lb mode if it doesn't exist
|
||||||
if (!$('.no-lb-info')) {
|
if (!$('.no-lb-info')) {
|
||||||
const info = document.createElement('div');
|
const info = document.createElement('div');
|
||||||
@@ -143,21 +76,21 @@
|
|||||||
} else {
|
} else {
|
||||||
// Show add server button
|
// Show add server button
|
||||||
if (addServerBtn) addServerBtn.classList.remove('d-none');
|
if (addServerBtn) addServerBtn.classList.remove('d-none');
|
||||||
|
|
||||||
// Remove no-lb info
|
// Remove no-lb info
|
||||||
const info = $('.no-lb-info');
|
const info = $('.no-lb-info');
|
||||||
if (info) info.remove();
|
if (info) info.remove();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
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');
|
||||||
|
|
||||||
const createRow = () => {
|
const createRow = () => {
|
||||||
serverCount++;
|
serverCount++;
|
||||||
const row = document.createElement('div');
|
const row = document.createElement('div');
|
||||||
@@ -181,23 +114,24 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const removeBtn = row.querySelector('.remove-server');
|
const removeBtn = row.querySelector('.remove-server');
|
||||||
removeBtn.addEventListener('click', () => row.remove());
|
removeBtn.addEventListener('click', () => row.remove());
|
||||||
|
|
||||||
return row;
|
return row;
|
||||||
};
|
};
|
||||||
|
|
||||||
addBtn?.addEventListener('click', () => {
|
addBtn?.addEventListener('click', () => {
|
||||||
if (container) {
|
if (container) {
|
||||||
container.appendChild(createRow());
|
container.appendChild(createRow());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove button for dynamically added rows
|
// Remove button for dynamically added rows
|
||||||
container?.addEventListener('click', (e) => {
|
container?.addEventListener('click', (e) => {
|
||||||
if (e.target.closest('.remove-server')) {
|
if (e.target.closest('.remove-server')) {
|
||||||
e.target.closest('.backend-server-row').remove();
|
e.target.closest('.backend-server-row').remove();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
Reference in New Issue
Block a user