Optimized docker detection structure

- Merged #202 and optimized UI elements
- Added HSTS headers toggle
- Added permission policy injector in dynamicproxy
- Fixed slow search LAN ip detection
- Optimized UI for HTTP reverse proxy rules
- Added wip permission policy and load balancer
This commit is contained in:
Toby Chui
2024-06-16 12:46:29 +08:00
parent b604c66a2f
commit dfb81513b1
13 changed files with 598 additions and 164 deletions

View File

@@ -5,6 +5,18 @@
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
<script src="../script/jquery-3.6.0.min.js"></script>
<script src="../script/semantic/semantic.min.js"></script>
<style>
.ui.tabular.menu .item.narrowpadding{
padding: 0.6em !important;
margin: 0.15em !important;
}
#permissionPolicyEditor.disabled{
opacity: 0.4;
pointer-events: none;
user-select: none;
}
</style>
</head>
<body>
<br>
@@ -16,52 +28,95 @@
</div>
</div>
<div class="ui divider"></div>
<p>You can define custom headers to be sent
together with the client request to the backend server in
this reverse proxy endpoint / host.</p>
<table class="ui very basic compacted unstackable celled table">
<thead>
<tr>
<th>Key</th>
<th>Value</th>
<th>Remove</th>
</tr></thead>
<tbody id="headerTable">
<tr>
<td colspan="3"><i class="ui green circle check icon"></i> No Additonal Header</td>
</tr>
</tbody>
</table>
<div class="ui divider"></div>
<h4>Edit Custom Header</h4>
<p>Add or remove custom header(s) over this proxy target</p>
<div class="scrolling content ui form">
<div class="five small fields credentialEntry">
<div class="field" align="center">
<button id="toOriginButton" title="Downstream to Upstream" class="ui circular basic active button">Zoraxy <i class="angle double right blue icon" style="margin-right: 0.4em;"></i> Origin</button>
<button id="toClientButton" title="Upstream to Downstream" class="ui circular basic button">Client <i class="angle double left orange icon" style="margin-left: 0.4em;"></i> Zoraxy</button>
<div class="ui small pointing secondary menu">
<a class="item active narrowpadding" data-tab="customheaders">Custom Headers</a>
<a class="item narrowpadding" data-tab="security">Security Headers</a>
</div>
<div class="ui tab basic segment active" data-tab="customheaders">
<table class="ui very basic compacted unstackable celled table">
<thead>
<tr>
<th>Key</th>
<th>Value</th>
<th>Remove</th>
</tr></thead>
<tbody id="headerTable">
<tr>
<td colspan="3"><i class="ui green circle check icon"></i> No Additonal Header</td>
</tr>
</tbody>
</table>
<p>
<i class="angle double right blue icon"></i> Sent additional custom headers to origin server <br>
<i class="angle double left orange icon"></i> Inject custom headers into origin server responses
</p>
<div class="ui divider"></div>
<h4>Edit Custom Header</h4>
<p>Add or remove custom header(s) over this proxy target</p>
<div class="scrolling content ui form">
<div class="five small fields credentialEntry">
<div class="field" align="center">
<button id="toOriginButton" style="margin-top: 0.6em;" title="Downstream to Upstream" class="ui circular basic active button">Zoraxy <i class="angle double right blue icon" style="margin-right: 0.4em;"></i> Origin</button>
<button id="toClientButton" style="margin-top: 0.6em;" title="Upstream to Downstream" class="ui circular basic button">Client <i class="angle double left orange icon" style="margin-left: 0.4em;"></i> Zoraxy</button>
</div>
<div class="field" align="center">
<button id="headerModeAdd" style="margin-top: 0.6em;" class="ui circular basic active button"><i class="ui green circle add icon"></i> Add Header</button>
<button id="headerModeRemove" style="margin-top: 0.6em;" class="ui circular basic button"><i class="ui red circle times icon"></i> Remove Header</button>
</div>
<div class="field">
<label>Header Key</label>
<input id="headerName" type="text" placeholder="X-Custom-Header" autocomplete="off">
<small>The header key is <b>NOT</b> case sensitive</small>
</div>
<div class="field">
<label>Header Value</label>
<input id="headerValue" type="text" placeholder="value1,value2,value3" autocomplete="off">
</div>
<div class="field" >
<button class="ui basic button" onclick="addCustomHeader();"><i class="green add icon"></i> Add Header Rewrite Rule</button>
</div>
<div class="ui divider"></div>
</div>
<div class="field" align="center">
<button id="headerModeAdd" class="ui circular basic active button"><i class="ui green circle add icon"></i> Add Header</button>
<button id="headerModeRemove" class="ui circular basic button"><i class="ui red circle times icon"></i> Remove Header</button>
</div>
<div class="field">
<label>Header Key</label>
<input id="headerName" type="text" placeholder="X-Custom-Header" autocomplete="off">
<small>The header key is <b>NOT</b> case sensitive</small>
</div>
<div class="field">
<label>Header Value</label>
<input id="headerValue" type="text" placeholder="value1,value2,value3" autocomplete="off">
</div>
<div class="field" >
<button class="ui basic button" onclick="addCustomHeader();"><i class="green add icon"></i> Add Header Rewrite Rule</button>
</div>
<div class="ui divider"></div>
</div>
</div>
<div class="ui divider"></div>
<div class="ui tab basic segment" data-tab="security">
<h4>HTTP Strict Transport Security</h4>
<p>Force future attempts to access this site to only use HTTPS</p>
<div class="ui toggle checkbox">
<input type="checkbox" id="enableHSTS" name="enableHSTS">
<label>Enable HSTS<br>
<small>HSTS header will be automatically ignored if the site is accessed using HTTP</small></label>
</div>
<div class="ui divider"></div>
<h4>Permission Policy</h4>
<p>Explicitly declare what functionality can and cannot be used on this website. </p>
<div class="ui toggle checkbox" style="margin-top: 0.6em;">
<input type="checkbox" id="enablePP" name="enablePP">
<label>Enable Permission Policy<br>
<small>Enable Permission-Policy header with all allowed state.</small></label>
</div>
<div style="margin-top: 1em;" id="permissionPolicyEditor">
<table class="ui celled unstackable very compact table">
<thead>
<tr><th>Feature</th>
<th>Enabled</th>
<th>Allow All (*)</th>
<th>Self Only (self)</th>
</tr></thead>
<tbody id="permissionPolicyEditTable">
<tr>
<td>James</td>
<td>24</td>
<td>Engineer</td>
<td>Engineer</td>
</tr>
</tbody>
</table>
</div>
<br>
<button class="ui basic button"><i class="green save icon"></i> Save</button>
</div>
<div class="field" >
<button class="ui basic button" style="float: right;" onclick="closeThisWrapper();">Close</button>
</div>
@@ -70,6 +125,8 @@
<br><br><br><br>
<script>
$('.menu .item').tab();
let editingEndpoint = {};
if (window.location.hash.length > 1){
let payloadHash = window.location.hash.substr(1);
@@ -239,6 +296,99 @@
});
}
listCustomHeaders();
//Start HSTS state
function initHSTSState(){
$.get("/api/proxy/header/handleHSTS?domain=" + editingEndpoint.ep, function(data){
if (data == 0){
//HSTS disabled
$("#enableHSTS").parent().checkbox("set unchecked");
}else{
//HSTS enabled
$("#enableHSTS").parent().checkbox("set checked");
}
/* Bind events to toggles */
$("#enableHSTS").on("change", function(){
let HSTSEnabled = $("#enableHSTS")[0].checked;
$.ajax({
url: "/api/proxy/header/handleHSTS",
method: "POST",
data: {
"domain": editingEndpoint.ep,
"maxage": 31536000
},
success: function(data){
if (data.error != undefined){
parent.msgbox(data.error, false);
}else{
parent.msgbox(`HSTS ${HSTSEnabled?"Enabled":"Disabled"}`);
}
}
})
});
});
}
initHSTSState();
/* List permission policy header from server */
function initPermissionPolicy(){
$.get("/api/proxy/header/handlePermissionPolicy?domain=" + editingEndpoint.ep, function(data){
if (data.error != undefined){
console.log(data.error);
$("#enablePP").parent().addClass('disabled');
return;
}
//Set checkbox state
if (data.PPEnabled){
$("#enablePP").parent().checkbox("set checked");
$("#permissionPolicyEditor").removeClass("disabled");
}else{
$("#enablePP").parent().checkbox("set unchecked");
$("#permissionPolicyEditor").addClass("disabled");
}
//Render the table to list
$("#permissionPolicyEditTable").html("");
for (const [key, value] of Object.entries(data.CurrentPolicy)) {
let allowall = "";
let allowself = "";
let enabled = "checked";
if (value.length == 1 && value[0] == "*"){
allowall = "checked";
}else if (value.length == 1 && value[0] == "self"){
allowself = "checked";
}
if (value.length == 0){
enabled = ""
}
$("#permissionPolicyEditTable").append(`<tr>
<td>${key}</td>
<td>
<div class="ui checkbox">
<input class="enabled" type="checkbox" name="${key}" ${enabled}>
<label></label>
</div>
</td>
<td>
<div class="ui radio checkbox">
<input type="radio" value="all" name="${key}-target" ${allowall}>
<label></label>
</div>
</td>
<td>
<div class="ui radio checkbox">
<input type="radio" value="self" name="${key}-target" ${allowself}>
<label></label>
</div>
</td>
</tr>`);
}
});
}
initPermissionPolicy();
</script>
</body>
</html>