mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-08-10 15:17:51 +02:00
Updated a lot of stuffs
+ Added comments for whitelist + Added automatic cert pick for multi-host certs (SNI) + Renamed .crt to .pem for cert store + Added best-fit selection for wildcard matching rules + Added x-proxy-by header + Added X-real-Ip header + Added Development Mode (Cache-Control: no-store) + Updated utm timeout to 10 seconds instead of 90
This commit is contained in:
@@ -615,8 +615,12 @@
|
||||
<p>Whitelist a certain IP or IP range</p>
|
||||
<div class="ui form">
|
||||
<div class="field">
|
||||
<label>IP Address</label>
|
||||
<input id="ipAddressInputWhitelist" type="text" placeholder="IP Address">
|
||||
<label>IP Address</label>
|
||||
<input id="ipAddressInputWhitelist" type="text" placeholder="IP Address">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Remarks (Optional)</label>
|
||||
<input id="ipAddressCommentsWhitelist" type="text" placeholder="Comments or remarks for this IP range">
|
||||
</div>
|
||||
<button id="addIpButton" onclick="addIpWhitelist();" class="ui basic green button">
|
||||
<i class="green add icon"></i> Whitelist IP
|
||||
@@ -634,6 +638,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>IP Address</th>
|
||||
<th>Remarks</th>
|
||||
<th>Remove</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -793,11 +798,12 @@
|
||||
if (data.length === 0) {
|
||||
$('#whitelistIpTable').append(`
|
||||
<tr>
|
||||
<td colspan="2"><i class="green check circle icon"></i>There are no whitelisted IP addresses</td>
|
||||
<td colspan="3"><i class="green check circle icon"></i>There are no whitelisted IP addresses</td>
|
||||
</tr>
|
||||
`);
|
||||
} else {
|
||||
$.each(data, function(index, ip) {
|
||||
$.each(data, function(index, ipEntry) {
|
||||
let ip = ipEntry.IP;
|
||||
let icon = "globe icon";
|
||||
if (isLAN(ip)){
|
||||
icon = "desktop icon";
|
||||
@@ -807,6 +813,7 @@
|
||||
$('#whitelistIpTable').append(`
|
||||
<tr class="whitelistItem" ip="${encodeURIComponent(ip)}">
|
||||
<td><i class="${icon}"></i> ${ip}</td>
|
||||
<td>${ipEntry.Comment}</td>
|
||||
<td><button class="ui icon basic mini red button" onclick="removeIpWhitelist('${ip}');"><i class="trash alternate icon"></i></button></td>
|
||||
</tr>
|
||||
`);
|
||||
@@ -1003,6 +1010,7 @@
|
||||
|
||||
function addIpWhitelist(){
|
||||
let targetIp = $("#ipAddressInputWhitelist").val().trim();
|
||||
let remarks = $("#ipAddressCommentsWhitelist").val().trim();
|
||||
if (targetIp == ""){
|
||||
alert("IP address is empty")
|
||||
return
|
||||
@@ -1016,7 +1024,7 @@
|
||||
$.ajax({
|
||||
url: "/api/whitelist/ip/add",
|
||||
type: "POST",
|
||||
data: {ip: targetIp.toLowerCase()},
|
||||
data: {ip: targetIp.toLowerCase(), "comment": remarks},
|
||||
success: function(response) {
|
||||
if (response.error !== undefined) {
|
||||
msgbox(response.error, false, 6000);
|
||||
@@ -1025,6 +1033,7 @@
|
||||
}
|
||||
|
||||
$("#ipAddressInputWhitelist").val("");
|
||||
$("#ipAddressCommentsWhitelist").val("");
|
||||
$("#ipAddressInputWhitelist").parent().remvoeClass("error");
|
||||
},
|
||||
error: function() {
|
||||
|
@@ -15,42 +15,19 @@
|
||||
</div>
|
||||
|
||||
<div class="ui divider"></div>
|
||||
<h4>Default Certificates</h4>
|
||||
<p>When there are no matching certificate for the requested server name, reverse proxy router will always fallback to this one.<br>Note that you need both of them uploaded for it to fallback properly</p>
|
||||
<table class="ui very basic unstackable celled table">
|
||||
<thead>
|
||||
<tr><th class="no-sort">Key Type</th>
|
||||
<th class="no-sort">Exists</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><i class="globe icon"></i> Default Public Key</td>
|
||||
<td id="pubkeyExists"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="lock icon"></i> Default Private Key</td>
|
||||
<td id="prikeyExists"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p style="margin-bottom: 0.4em;"><i class="ui upload icon"></i> Upload Default Keypairs</p>
|
||||
<div class="ui buttons">
|
||||
<button class="ui basic grey button" onclick="uploadPublicKey();"><i class="globe icon"></i> Public Key</button>
|
||||
<button class="ui basic black button" onclick="uploadPrivateKey();"><i class="black lock icon"></i> Private Key</button>
|
||||
</div>
|
||||
|
||||
<div class="ui divider"></div>
|
||||
<h4>Sub-domain Certificates</h4>
|
||||
<h3>Hosts Certificates</h3>
|
||||
<p>Provide certificates for multiple domains reverse proxy</p>
|
||||
<div class="ui fluid form">
|
||||
<div class="three fields">
|
||||
<div class="field">
|
||||
<label>Server Name (Domain)</label>
|
||||
<input type="text" id="certdomain" placeholder="example.com / blog.example.com">
|
||||
<small><i class="exclamation circle yellow icon"></i> Match the server name with your CN/DNS entry in certificate for faster resolve time</small>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Public Key (.pem)</label>
|
||||
<input type="file" id="pubkeySelector" onchange="handleFileSelect(event, 'pub')">
|
||||
<small>or .crt files in order systems</small>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Private Key (.key)</label>
|
||||
@@ -63,14 +40,33 @@
|
||||
<div id="certUploadSuccMsg" class="ui green message" style="display:none;">
|
||||
<i class="ui checkmark icon"></i> Certificate for domain <span id="certUploadingDomain"></span> uploaded.
|
||||
</div>
|
||||
<br>
|
||||
<div class="ui message">
|
||||
<h4>Tips about Server Names & SNI</h4>
|
||||
<div class="ui bulleted list">
|
||||
<div class="item">
|
||||
If you have two subdomains like <code>a.example.com</code> and <code>b.example.com</code> ,
|
||||
for faster response speed, you might want to setup them one by one (i.e. having two seperate certificate for
|
||||
<code>a.example.com</code> and <code>b.example.com</code>).
|
||||
</div>
|
||||
<div class="item">
|
||||
If you have a wildcard certificate that covers <code>*.example.com</code>,
|
||||
you can just enter <code>example.com</code> as server name to add a certificate.
|
||||
</div>
|
||||
<div class="item">
|
||||
If you have a certificate contain multiple host, you can enter the first domain in your certificate
|
||||
and Zoraxy will try to match the remaining CN/DNS for you.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p>Current list of loaded certificates</p>
|
||||
<div>
|
||||
<div style="width: 100%; overflow-x: auto; margin-bottom: 1em;">
|
||||
<table class="ui sortable unstackable celled table">
|
||||
<table class="ui sortable unstackable basic celled table">
|
||||
<thead>
|
||||
<tr><th>Domain</th>
|
||||
<th>Last Update</th>
|
||||
<th>Expire At</th>
|
||||
<th class="no-sort">Renew</th>
|
||||
<th class="no-sort">Remove</th>
|
||||
</tr></thead>
|
||||
<tbody id="certifiedDomainList">
|
||||
@@ -81,15 +77,34 @@
|
||||
|
||||
<button class="ui basic button" onclick="initManagedDomainCertificateList();"><i class="green refresh icon"></i> Refresh List</button>
|
||||
</div>
|
||||
<div class="ui message">
|
||||
<h4><i class="info circle icon"></i> Sub-domain Certificates</h4>
|
||||
If you have 3rd or even 4th level subdomains like <code>blog.example.com</code> or <code>en.blog.example.com</code> ,
|
||||
depending on your certificates coverage, you might need to setup them one by one (i.e. having two seperate certificate for <code>a.example.com</code> and <code>b.example.com</code>).<br>
|
||||
If you have a wildcard certificate that covers <code>*.example.com</code>, you can just enter <code>example.com</code> as server name in the form below to add a certificate.
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
<h4>Certificate Authority (CA) and Auto Renew (ACME)</h4>
|
||||
<h3>Fallback Certificate</h3>
|
||||
<p>When there are no matching certificate for the requested server name, reverse proxy router will always fallback to this one.<br>Note that you need both of them uploaded for it to fallback properly</p>
|
||||
<table class="ui very basic unstackable celled table">
|
||||
<thead>
|
||||
<tr><th class="no-sort">Key Type</th>
|
||||
<th class="no-sort">Found</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><i class="globe icon"></i> Fallback Public Key</td>
|
||||
<td id="pubkeyExists"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="lock icon"></i> Fallback Private Key</td>
|
||||
<td id="prikeyExists"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p style="margin-bottom: 0.4em;"><i class="ui upload icon"></i> Upload Default Keypairs</p>
|
||||
<div class="ui buttons">
|
||||
<button class="ui basic grey button" onclick="uploadPublicKey();"><i class="globe icon"></i> Public Key</button>
|
||||
<button class="ui basic black button" onclick="uploadPrivateKey();"><i class="black lock icon"></i> Private Key</button>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
<h3>Certificate Authority (CA) and Auto Renew (ACME)</h3>
|
||||
<p>Management features regarding CA and ACME</p>
|
||||
<h4>Prefered Certificate Authority</h4>
|
||||
<p>The default CA to use when create a new subdomain proxy endpoint with TLS certificate</p>
|
||||
<div class="ui fluid form">
|
||||
<div class="field">
|
||||
@@ -112,12 +127,12 @@
|
||||
<button class="ui basic icon button" onclick="saveDefaultCA();"><i class="ui blue save icon"></i> Save Settings</button>
|
||||
</div><br>
|
||||
<h5>Certificate Renew / Generation (ACME) Settings</h5>
|
||||
<div class="ui basic segment">
|
||||
<div class="ui basic segment acmeRenewStateWrapper">
|
||||
<h4 class="ui header" id="acmeAutoRenewer">
|
||||
<i class="red circle icon"></i>
|
||||
<i class="white remove icon"></i>
|
||||
<div class="content">
|
||||
<span id="acmeAutoRenewerStatus">Disabled</span>
|
||||
<div class="sub header">Auto-Renewer Status</div>
|
||||
<div class="sub header">ACME Auto-Renewer</div>
|
||||
</div>
|
||||
</h4>
|
||||
</div>
|
||||
@@ -130,6 +145,110 @@
|
||||
|
||||
$("#defaultCA").dropdown();
|
||||
|
||||
|
||||
//Renew certificate by button press
|
||||
function renewCertificate(domain, btn=undefined){
|
||||
let defaultCA = $("#defaultCA").dropdown("get value");
|
||||
if (defaultCA.trim() == ""){
|
||||
defaultCA = "Let's Encrypt";
|
||||
}
|
||||
//Get a new cert using ACME
|
||||
msgbox("Requesting certificate via " + defaultCA +"...");
|
||||
|
||||
//Request ACME for certificate
|
||||
if (btn != undefined){
|
||||
$(btn).addClass('disabled');
|
||||
$(btn).html(`<i class="ui loading spinner icon"></i>`);
|
||||
}
|
||||
obtainCertificate(domain, defaultCA.trim(), function(succ){
|
||||
if (btn != undefined){
|
||||
$(btn).removeClass('disabled');
|
||||
if (succ){
|
||||
$(btn).html(`<i class="ui green check icon"></i>`);
|
||||
}else{
|
||||
$(btn).html(`<i class="ui red times icon"></i>`);
|
||||
}
|
||||
|
||||
setTimeout(function(){
|
||||
initManagedDomainCertificateList();
|
||||
}, 3000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
Obtain Certificate via ACME
|
||||
*/
|
||||
|
||||
// Obtain certificate from API, only support one domain
|
||||
function obtainCertificate(domains, usingCa = "Let's Encrypt", callback=undefined) {
|
||||
//Load the ACME email from server side
|
||||
let acmeEmail = "";
|
||||
$.get("/api/acme/autoRenew/email", function(data){
|
||||
if (data != "" && data != undefined && data != null){
|
||||
acmeEmail = data;
|
||||
}
|
||||
|
||||
let filename = "";
|
||||
let email = acmeEmail;
|
||||
if (acmeEmail == ""){
|
||||
msgbox("Unable to obtain certificate: ACME email not set", false, 8000);
|
||||
if (callback != undefined){
|
||||
callback(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (filename.trim() == "" && !domains.includes(",")){
|
||||
//Zoraxy filename are the matching name for domains.
|
||||
//Use the same as domains
|
||||
filename = domains;
|
||||
}else if (filename != "" && !domains.includes(",")){
|
||||
//Invalid settings. Force the filename to be same as domain
|
||||
//if there are only 1 domain
|
||||
filename = domains;
|
||||
}else{
|
||||
msgbox("Filename cannot be empty for certs containing multiple domains.")
|
||||
if (callback != undefined){
|
||||
callback(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: "/api/acme/obtainCert",
|
||||
method: "GET",
|
||||
data: {
|
||||
domains: domains,
|
||||
filename: filename,
|
||||
email: email,
|
||||
ca: usingCa,
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.error) {
|
||||
console.log("Error:", response.error);
|
||||
// Show error message
|
||||
msgbox(response.error, false, 12000);
|
||||
if (callback != undefined){
|
||||
callback(false);
|
||||
}
|
||||
} else {
|
||||
console.log("Certificate installed successfully");
|
||||
// Show success message
|
||||
msgbox("Certificate installed successfully");
|
||||
|
||||
if (callback != undefined){
|
||||
callback(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
error: function(error) {
|
||||
console.log("Failed to install certificate:", error);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//Delete the certificate by its domain
|
||||
function deleteCertificate(domain){
|
||||
if (confirm("Confirm delete certificate for " + domain + " ?")){
|
||||
@@ -154,6 +273,12 @@
|
||||
//Initialize the current default CA options
|
||||
$.get("/api/acme/autoRenew/email", function(data){
|
||||
$("#prefACMEEmail").val(data);
|
||||
if (data.trim() == ""){
|
||||
//acme email is not yet set
|
||||
$(".renewButton").addClass('disabled');
|
||||
}else{
|
||||
$(".renewButton").removeClass('disabled');
|
||||
}
|
||||
});
|
||||
|
||||
$.get("/api/acme/autoRenew/ca", function(data){
|
||||
@@ -167,7 +292,13 @@
|
||||
//Set the status of the acme enable icon
|
||||
function setACMEEnableStates(enabled){
|
||||
$("#acmeAutoRenewerStatus").text(enabled?"Enabled":"Disabled");
|
||||
$("#acmeAutoRenewer").find("i").attr("class", enabled?"green circle icon":"red circle icon");
|
||||
if (enabled){
|
||||
$(".acmeRenewStateWrapper").addClass("enabled");
|
||||
}else{
|
||||
$(".acmeRenewStateWrapper").removeClass("enabled");
|
||||
}
|
||||
|
||||
$("#acmeAutoRenewer").find("i").attr("class", enabled?"white circle check icon":"white circle times icon");
|
||||
}
|
||||
initAcmeStatus();
|
||||
|
||||
@@ -187,6 +318,9 @@
|
||||
success: function(data){
|
||||
if (data.error != undefined){
|
||||
msgbox(data.error, false);
|
||||
}else{
|
||||
//Update the renew button states
|
||||
$(".renewButton").removeClass('disabled');
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -223,13 +357,14 @@
|
||||
<td>${entry.Domain}</td>
|
||||
<td>${entry.LastModifiedDate}</td>
|
||||
<td class="${isExpired?"expired":"valid"} certdate">${entry.ExpireDate} (${!isExpired?entry.RemainingDays+" days left":"Expired"})</td>
|
||||
<td><button title="Renew Certificate" class="ui mini basic icon button renewButton" onclick="renewCertificate('${entry.Domain}', this);"><i class="ui green refresh icon"></i></button></td>
|
||||
<td><button title="Delete key-pair" class="ui mini basic red icon button" onclick="deleteCertificate('${entry.Domain}');"><i class="ui red trash icon"></i></button></td>
|
||||
</tr>`);
|
||||
});
|
||||
|
||||
if (data.length == 0){
|
||||
$("#certifiedDomainList").append(`<tr>
|
||||
<td colspan="4"><i class="ui times circle icon"></i> No valid keypairs found</td>
|
||||
<td colspan="4"><i class="ui times red circle icon"></i> No valid keypairs found</td>
|
||||
</tr>`);
|
||||
}
|
||||
}
|
||||
|
@@ -3,15 +3,15 @@
|
||||
<h2>HTTP Proxy</h2>
|
||||
<p>Proxy HTTP server with HTTP or HTTPS for multiple hosts. If you are only proxying for one host / domain, use Default Site instead.</p>
|
||||
</div>
|
||||
<div style="width: 100%; overflow-x: auto; margin-bottom: 1em; min-width: 400px;">
|
||||
<table class="ui celled sortable unstackable basic compact table">
|
||||
<div style="width: 100%; overflow-x: auto; margin-bottom: 1em;">
|
||||
<table class="ui celled sortable unstackable compact table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Host</th>
|
||||
<th>Destination</th>
|
||||
<!-- <th>Virtual Directory</th> -->
|
||||
<th>Basic Auth</th>
|
||||
<th class="no-sort" style="min-width: 7.2em;">Actions</th>
|
||||
<th class="no-sort" style="min-width:100px;">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="httpProxyList">
|
||||
@@ -19,6 +19,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<button class="ui icon right floated basic button" onclick="listProxyEndpoints();"><i class="green refresh icon"></i> Refresh</button>
|
||||
<br><br>
|
||||
</div>
|
||||
|
@@ -110,6 +110,7 @@
|
||||
$("#ruleAddSucc").stop().finish().slideDown("fast").delay(3000).slideUp("fast");
|
||||
}
|
||||
initRedirectionRuleList();
|
||||
resetForm();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -141,7 +142,7 @@
|
||||
$.get("/api/redirect/list", function(data){
|
||||
data.forEach(function(entry){
|
||||
$("#redirectionRuleList").append(`<tr>
|
||||
<td>${entry.RedirectURL} </td>
|
||||
<td><a href="${entry.RedirectURL}" target="_blank">${entry.RedirectURL}</a></td>
|
||||
<td>${entry.TargetURL}</td>
|
||||
<td>${entry.ForwardChildpath?"<i class='ui green checkmark icon'></i>":"<i class='ui red remove icon'></i>"}</td>
|
||||
<td>${entry.StatusCode==307?"Temporary Redirect (307)":"Moved Permanently (301)"}</td>
|
||||
|
@@ -198,19 +198,20 @@
|
||||
|
||||
//Set the new proxy root option
|
||||
function setProxyRoot(btn=undefined){
|
||||
if (btn != undefined){
|
||||
$(btn).addClass("disabled");
|
||||
}
|
||||
var newpr = $("#proxyRoot").val();
|
||||
if (newpr.trim() == ""){
|
||||
$("#proxyRoot").parent().addClass('error');
|
||||
return
|
||||
}else{
|
||||
$("#proxyRoot").parent().removeClass('error');
|
||||
if (newpr.trim() == "" && currentDefaultSiteOption == 0){
|
||||
//Fill in the web server info
|
||||
newpr = "127.0.0.1:" + $("#webserv_listenPort").val();
|
||||
$("#proxyRoot").val(newpr);
|
||||
|
||||
}
|
||||
|
||||
var rootReqTls = $("#rootReqTLS")[0].checked;
|
||||
|
||||
if (btn != undefined){
|
||||
$(btn).addClass("disabled");
|
||||
}
|
||||
|
||||
//proxy mode or redirect mode, check for input values
|
||||
var defaultSiteValue = "";
|
||||
if (currentDefaultSiteOption == 1){
|
||||
|
@@ -117,7 +117,6 @@
|
||||
<script>
|
||||
$("#advanceProxyRules").accordion();
|
||||
|
||||
|
||||
|
||||
//New Proxy Endpoint
|
||||
function newProxyEndpoint(){
|
||||
@@ -164,7 +163,7 @@
|
||||
$("#proxyDomain").val("");
|
||||
credentials = [];
|
||||
updateTable();
|
||||
|
||||
reloadUptimeList();
|
||||
//Check if it is a new subdomain and TLS enabled
|
||||
if ($("#tls").checkbox("is checked")){
|
||||
confirmBox("Request new SSL Cert for this subdomain?", function(choice){
|
||||
@@ -177,7 +176,12 @@
|
||||
//Get a new cert using ACME
|
||||
msgbox("Requesting certificate via " + defaultCA +"...");
|
||||
console.log("Trying to get a new certificate via ACME");
|
||||
obtainCertificate(rootname, defaultCA.trim());
|
||||
|
||||
//Request ACME for certificate, see cert.html component
|
||||
obtainCertificate(rootname, defaultCA.trim(), function(){
|
||||
// Renew the parent certificate list
|
||||
initManagedDomainCertificateList();
|
||||
});
|
||||
}else{
|
||||
msgbox("Proxy Endpoint Added");
|
||||
}
|
||||
@@ -193,7 +197,7 @@
|
||||
|
||||
//Generic functions for delete rp endpoints
|
||||
function deleteEndpoint(epoint){
|
||||
epoint = decodeURIComponent(epoint);
|
||||
epoint = decodeURIComponent(epoint).hexDecode();
|
||||
if (confirm("Confirm remove proxy for :" + epoint + "?")){
|
||||
$.ajax({
|
||||
url: "/api/proxy/del",
|
||||
@@ -201,6 +205,7 @@
|
||||
success: function(){
|
||||
listProxyEndpoints();
|
||||
msgbox("Proxy Rule Deleted", true);
|
||||
reloadUptimeList();
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -300,67 +305,7 @@
|
||||
updateTable();
|
||||
}
|
||||
|
||||
/*
|
||||
Obtain Certificate via ACME
|
||||
*/
|
||||
|
||||
//Load the ACME email from server side
|
||||
let acmeEmail = "";
|
||||
$.get("/api/acme/autoRenew/email", function(data){
|
||||
if (data != "" && data != undefined && data != null){
|
||||
acmeEmail = data;
|
||||
}
|
||||
});
|
||||
|
||||
// Obtain certificate from API, only support one domain
|
||||
function obtainCertificate(domains, usingCa = "Let's Encrypt") {
|
||||
let filename = "";
|
||||
let email = acmeEmail;
|
||||
if (acmeEmail == ""){
|
||||
let rootDomain = domains.split(".").pop();
|
||||
email = "admin@" + rootDomain;
|
||||
}
|
||||
if (filename.trim() == "" && !domains.includes(",")){
|
||||
//Zoraxy filename are the matching name for domains.
|
||||
//Use the same as domains
|
||||
filename = domains;
|
||||
}else if (filename != "" && !domains.includes(",")){
|
||||
//Invalid settings. Force the filename to be same as domain
|
||||
//if there are only 1 domain
|
||||
filename = domains;
|
||||
}else{
|
||||
parent.msgbox("Filename cannot be empty for certs containing multiple domains.")
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: "/api/acme/obtainCert",
|
||||
method: "GET",
|
||||
data: {
|
||||
domains: domains,
|
||||
filename: filename,
|
||||
email: email,
|
||||
ca: usingCa,
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.error) {
|
||||
console.log("Error:", response.error);
|
||||
// Show error message
|
||||
msgbox(response.error, false, 12000);
|
||||
} else {
|
||||
console.log("Certificate installed successfully");
|
||||
// Show success message
|
||||
msgbox("Certificate installed successfully");
|
||||
|
||||
// Renew the parent certificate list
|
||||
initManagedDomainCertificateList();
|
||||
}
|
||||
},
|
||||
error: function(error) {
|
||||
console.log("Failed to install certificate:", error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//Update v3.0.0
|
||||
//Since some proxy rules now contains wildcard characters
|
||||
|
@@ -44,7 +44,7 @@
|
||||
<div class="content">
|
||||
<span id="country"></span>
|
||||
<div class="sub header" id="countryList">
|
||||
|
||||
<i class="ui loading circle notch icon"></i> Resolving GeoIP
|
||||
</div>
|
||||
</div>
|
||||
</h5>
|
||||
@@ -96,13 +96,18 @@
|
||||
Advance Settings
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>If you have no idea what are these, you can leave them as default :)</p>
|
||||
<div id="tlsMinVer" class="ui toggle notloopbackOnly tlsEnabledOnly checkbox" style="margin-top: 0.6em;">
|
||||
<input type="checkbox">
|
||||
<label>Force TLS v1.2 or above<br>
|
||||
<small>(Enhance security, but not compatible with legacy browsers)</small></label>
|
||||
</div>
|
||||
<br>
|
||||
<div id="developmentMode" class="ui toggle checkbox" style="margin-top: 0.6em;">
|
||||
<input type="checkbox">
|
||||
<label>Development Mode<br>
|
||||
<small>(Set Cache-Control to no-store so browser will always fetch new contents from your sites)</small></label>
|
||||
</div>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -436,6 +441,30 @@
|
||||
}
|
||||
initTlsVersionSetting();
|
||||
|
||||
function initDevelopmentMode(){
|
||||
$.get("/api/proxy/developmentMode", function(data){
|
||||
if (data === true){
|
||||
$("#developmentMode").checkbox("set checked")
|
||||
}else{
|
||||
$("#developmentMode").checkbox("set unchecked")
|
||||
}
|
||||
|
||||
//Bind change events
|
||||
$("#developmentMode").off("change").on("change", function(data){
|
||||
let enableDevMode = ($(this).find("input[type='checkbox']")[0].checked);
|
||||
$.get("/api/proxy/developmentMode?enable=" + enableDevMode, function(data){
|
||||
if (enableDevMode){
|
||||
msgbox("Development mode enabled");
|
||||
}else{
|
||||
msgbox("Development mode disabled");
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
initDevelopmentMode();
|
||||
|
||||
function initTlsSetting(){
|
||||
$.get("/api/cert/tls", function(data){
|
||||
if (data == true){
|
||||
|
@@ -3,11 +3,33 @@
|
||||
<h2>TCP Proxy</h2>
|
||||
<p>Proxy traffic flow on layer 3 via TCP/IP</p>
|
||||
</div>
|
||||
<button class="ui basic orange button" id="addProxyConfigButton"><i class="ui add icon"></i> Add Proxy Config</button>
|
||||
<button class="ui basic circular right floated icon button" onclick="initProxyConfigList();" title="Refresh List"><i class="ui green refresh icon"></i></button>
|
||||
<div class="ui divider"></div>
|
||||
<div class="ui basic segment" id="addproxyConfig" style="display:none;">
|
||||
<h3>TCP Proxy Config</h3>
|
||||
<div class="ui basic segment" style="margin-top: 0;">
|
||||
<h4>TCP Proxy Rules</h4>
|
||||
<p>A list of TCP proxy rules created on this host. To enable them, use the toggle button on the right.</p>
|
||||
<div style="overflow-x: auto; min-height: 400px;">
|
||||
<table id="proxyTable" class="ui celled unstackable table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Port/Addr A</th>
|
||||
<th>Port/Addr B</th>
|
||||
<th>Mode</th>
|
||||
<th>Timeout (s)</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<button class="ui basic right floated button" onclick="initProxyConfigList();" title="Refresh List"><i class="ui green refresh icon"></i>Refresh</button>
|
||||
<br><br>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
<div class="ui basic segment" id="addproxyConfig">
|
||||
<h4>Add or Edit TCP Proxy</h4>
|
||||
<p>Create or edit a new proxy instance</p>
|
||||
<form id="tcpProxyForm" class="ui form">
|
||||
<div class="field" style="display:none;">
|
||||
@@ -39,11 +61,10 @@
|
||||
<option value="starter">Starter</option>
|
||||
</select>
|
||||
</div>
|
||||
<button id="addTcpProxyButton" class="ui basic button" type="submit"><i class="ui blue add icon"></i> Create</button>
|
||||
<button id="editTcpProxyButton" class="ui basic button" onclick="confirmEditTCPProxyConfig(event);"><i class="ui blue save icon"></i> Update</button>
|
||||
<button id="addTcpProxyButton" class="ui basic button" type="submit"><i class="ui green add icon"></i> Create</button>
|
||||
<button id="editTcpProxyButton" class="ui basic button" onclick="confirmEditTCPProxyConfig(event);" style="display:none;"><i class="ui green check icon"></i> Update</button>
|
||||
<button class="ui basic red button" onclick="event.preventDefault(); cancelTCPProxyEdit(event);"><i class="ui red remove icon"></i> Cancel</button>
|
||||
<div class="ui basic inverted segment" style="background-color: #414141; border-radius: 0.6em;">
|
||||
<h3>Proxy Mode Instructions</h3>
|
||||
<div class="ui basic inverted segment" style="background: var(--theme_background_inverted); border-radius: 0.6em;">
|
||||
<p>TCP Proxy support the following TCP sockets proxy modes</p>
|
||||
<table class="ui celled padded inverted basic table">
|
||||
<thead>
|
||||
@@ -108,28 +129,6 @@
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
<div class="ui divider"></div>
|
||||
</div>
|
||||
<div class="ui basic segment" style="margin-top: 0;">
|
||||
<h3>TCP Proxy Configs</h3>
|
||||
<p>A list of TCP proxy configs created on this host. To enable them, use the toggle button on the right.</p>
|
||||
<div style="overflow-x: auto; min-height: 400px;">
|
||||
<table id="proxyTable" class="ui celled unstackable table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Port/Addr A</th>
|
||||
<th>Port/Addr B</th>
|
||||
<th>Mode</th>
|
||||
<th>Timeout (s)</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
@@ -138,6 +137,13 @@
|
||||
$("#tcpProxyForm .dropdown").dropdown();
|
||||
$('#tcpProxyForm').on('submit', function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
//Check if update mode
|
||||
if ($("#editTcpProxyButton").is(":visible")){
|
||||
confirmEditTCPProxyConfig(event);
|
||||
return;
|
||||
}
|
||||
|
||||
var form = $(this);
|
||||
|
||||
var formValid = validateTCPProxyConfig(form);
|
||||
@@ -165,23 +171,16 @@
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//Add proxy button pressed. Show add TCP proxy menu
|
||||
$("#addProxyConfigButton").on("click", function(){
|
||||
$('#addproxyConfig').slideToggle('fast');
|
||||
$("#addTcpProxyButton").show();
|
||||
$("#editTcpProxyButton").hide();
|
||||
});
|
||||
|
||||
|
||||
function clearTCPProxyAddEditForm(){
|
||||
$('#tcpProxyForm input, #tcpProxyForm select').val('');
|
||||
$('#tcpProxyForm select').dropdown('clear');
|
||||
}
|
||||
|
||||
function cancelTCPProxyEdit(event) {
|
||||
function cancelTCPProxyEdit(event=undefined) {
|
||||
clearTCPProxyAddEditForm();
|
||||
$('#addproxyConfig').slideUp('fast');
|
||||
$("#addTcpProxyButton").show();
|
||||
$("#editTcpProxyButton").hide();
|
||||
}
|
||||
|
||||
function validateTCPProxyConfig(form){
|
||||
@@ -231,7 +230,7 @@
|
||||
proxyConfigs.forEach(function(config) {
|
||||
var runningLogo = 'Stopped';
|
||||
var runningClass = "stopped";
|
||||
var startButton = `<button onclick="startTcpProx('${config.UUID}');" class="ui button" title="Start Proxy"><i class="play icon"></i> Start Proxy</button>`;
|
||||
var startButton = `<button onclick="startTcpProx('${config.UUID}');" class="ui button" title="Start Proxy"><i class="green play icon"></i> Start Proxy</button>`;
|
||||
if (config.Running){
|
||||
runningLogo = 'Running';
|
||||
startButton = `<button onclick="stopTcpProx('${config.UUID}');" class="ui button" title="Start Proxy"><i class="red stop icon"></i> Stop Proxy</button>`;
|
||||
@@ -354,8 +353,8 @@
|
||||
msgbox("Config Updated");
|
||||
}
|
||||
initProxyConfigList();
|
||||
clearTCPProxyAddEditForm();
|
||||
$("#addproxyConfig").slideUp("fast");
|
||||
cancelTCPProxyEdit();
|
||||
|
||||
},
|
||||
error: function() {
|
||||
msgbox('An error occurred while processing the request', false);
|
||||
|
@@ -3,166 +3,179 @@
|
||||
<h2>Utilities</h2>
|
||||
<p>You might find these tools or information helpful when setting up your gateway server</p>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
|
||||
|
||||
<div class="selfauthOnly">
|
||||
<h3>Account Management</h3>
|
||||
<p>Functions to help management the current account</p>
|
||||
<div class="ui basic segment">
|
||||
<h5><i class="chevron down icon"></i> Change Password</h5>
|
||||
<div class="ui form">
|
||||
<div class="field">
|
||||
<label>Current Password</label>
|
||||
<input type="password" name="oldPassword" placeholder="Current Password">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>New Password</label>
|
||||
<input type="password" name="newPassword" placeholder="New Password">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Confirm New Password</label>
|
||||
<input type="password" name="confirmNewPassword" placeholder="Confirm New Password">
|
||||
</div>
|
||||
<button class="ui basic button" onclick="changePassword()"><i class="ui teal key icon"></i> Change Password</button>
|
||||
</div>
|
||||
<div class="ui top attached tabular menu">
|
||||
<a class="nettools item active" data-tab="tab1"><i class="ui user circle blue icon"></i> Accounts</a>
|
||||
<a class="nettools item" data-tab="tab2">Toolbox</a>
|
||||
<a class="nettools item" data-tab="tab3">System</a>
|
||||
</div>
|
||||
|
||||
<div id="passwordChangeSuccMsg" class="ui green message" style="display:none;">
|
||||
<i class="ui circle checkmark green icon "></i> Password Updated
|
||||
<div class="ui bottom attached tab segment nettoolstab active" data-tab="tab1">
|
||||
<div class="extAuthOnly" style="display:none;">
|
||||
<div class="ui basic segment">
|
||||
<i class="ui green circle check icon"></i> Account options are not available due to -noauth flag is set to true.
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
<h3>Forget Password Email</h3>
|
||||
<p>The following SMTP settings help you to reset your password in case you have lost your management account.</p>
|
||||
<form id="email-form" class="ui form">
|
||||
<div class="field">
|
||||
<label>Sender Address</label>
|
||||
<input type="text" name="senderAddr" placeholder="E.g. noreply@zoraxy.arozos.com">
|
||||
</div>
|
||||
<div class="field">
|
||||
<p><i class="caret down icon"></i> Connection setup for email service provider</p>
|
||||
<div class="fields">
|
||||
<div class="twelve wide field">
|
||||
<label>SMTP Provider Hostname</label>
|
||||
<input type="text" name="hostname" placeholder="E.g. mail.gandi.net">
|
||||
<div class="selfauthOnly">
|
||||
<h3>Change Password</h3>
|
||||
<p>Update the current account credentials</p>
|
||||
<div class="ui basic segment">
|
||||
<h5><i class="chevron down icon"></i> Change Password</h5>
|
||||
<div class="ui form">
|
||||
<div class="field">
|
||||
<label>Current Password</label>
|
||||
<input type="password" name="oldPassword" placeholder="Current Password">
|
||||
</div>
|
||||
|
||||
<div class="four wide field">
|
||||
<label>Port</label>
|
||||
<input type="number" name="port" placeholder="E.g. 587" value="587">
|
||||
<div class="field">
|
||||
<label>New Password</label>
|
||||
<input type="password" name="newPassword" placeholder="New Password">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Confirm New Password</label>
|
||||
<input type="password" name="confirmNewPassword" placeholder="Confirm New Password">
|
||||
</div>
|
||||
<button class="ui basic button" onclick="changePassword()"><i class="ui teal key icon"></i> Change Password</button>
|
||||
</div>
|
||||
|
||||
<div id="passwordChangeSuccMsg" class="ui green message" style="display:none;">
|
||||
<i class="ui circle checkmark green icon "></i> Password Updated
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p><i class="caret down icon"></i> Credentials for SMTP server authentications</p>
|
||||
<div class="two fields">
|
||||
<div class="field">
|
||||
<label>Sender Username</label>
|
||||
<input type="text" name="username" placeholder="E.g. admin">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Sender Domain</label>
|
||||
<div class="ui labeled input">
|
||||
<div class="ui basic label">
|
||||
@
|
||||
</div>
|
||||
<input type="text" name="domain" min="1" max="65534" placeholder="E.g. arozos.com">
|
||||
<div class="ui divider"></div>
|
||||
<h3>Forget Password Email</h3>
|
||||
<p>The following SMTP settings help you to reset your password in case you have lost your management account.</p>
|
||||
<form id="email-form" class="ui form">
|
||||
<div class="field">
|
||||
<label>Sender Address</label>
|
||||
<input type="text" name="senderAddr" placeholder="E.g. noreply@zoraxy.arozos.com">
|
||||
</div>
|
||||
<div class="field">
|
||||
<p><i class="caret down icon"></i> Connection setup for email service provider</p>
|
||||
<div class="fields">
|
||||
<div class="twelve wide field">
|
||||
<label>SMTP Provider Hostname</label>
|
||||
<input type="text" name="hostname" placeholder="E.g. mail.gandi.net">
|
||||
</div>
|
||||
|
||||
<div class="four wide field">
|
||||
<label>Port</label>
|
||||
<input type="number" name="port" placeholder="E.g. 587" value="587">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Sender Password</label>
|
||||
<input type="password" name="password" placeholder="Password of the email account">
|
||||
<small>Leave empty to use the old password</small>
|
||||
</div>
|
||||
|
||||
<p> <i class="caret down icon"></i> Email for sending account reset link</p>
|
||||
<div class="field">
|
||||
<label>Admin / Receiver Address</label>
|
||||
<input type="text" name="recvAddr" placeholder="E.g. personalEmail@gmail.com">
|
||||
</div>
|
||||
|
||||
<button class="ui basic button" type="submit"><i class="blue save icon"></i> Set SMTP Configs</button>
|
||||
<button class="ui basic button" onclick="event.preventDefault(); sendTestEmail(this);"><i class="teal mail icon"></i> Send Test Email</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
<h3> IP Address to CIDR</h3>
|
||||
<p>No experience with CIDR notations? Here are some tools you can use to make setting up easier.</p>
|
||||
<div class="ui basic segment">
|
||||
<h5><i class="chevron down icon"></i> IP Range to CIDR Conversion</h5>
|
||||
<div class="ui message">
|
||||
<i class="info circle icon"></i> Note that the CIDR generated here covers additional IP address before or after the given range. If you need more details settings, please use CIDR with a smaller range and add additional IPs for detail range adjustment.
|
||||
</div>
|
||||
<div class="ui input">
|
||||
<input type="text" placeholder="Start IP" id="startIpInput">
|
||||
</div>
|
||||
<div class="ui input">
|
||||
<input type="text" placeholder="End IP" id="endIpInput">
|
||||
</div>
|
||||
<br>
|
||||
<button style="margin-top: 0.6em;" class="ui basic button" onclick="convertToCIDR()">Convert</button>
|
||||
<p>Results: <div id="cidrOutput">N/A</div></p>
|
||||
</div>
|
||||
|
||||
<div class="ui basic segment">
|
||||
<h5><i class="chevron down icon"></i> CIDR to IP Range Conversion</h5>
|
||||
<div class="ui action input">
|
||||
<input type="text" placeholder="CIDR" id="cidrInput">
|
||||
<button class="ui basic button" onclick="convertToIPRange()">Convert</button>
|
||||
</div>
|
||||
<p>Results: <div id="ipRangeOutput">N/A</div></p>
|
||||
</div>
|
||||
<!-- Config Tools -->
|
||||
<div class="ui divider"></div>
|
||||
<h3>System Backup & Restore</h3>
|
||||
<p>Options related to system backup, migrate and restore.</p>
|
||||
<button class="ui basic button" onclick="showSideWrapper('snippet/configTools.html');">Open Config Tools</button>
|
||||
<!-- System Information -->
|
||||
<div class="ui divider"></div>
|
||||
<div id="zoraxyinfo">
|
||||
<h3 class="ui header">
|
||||
System Information
|
||||
</h3>
|
||||
<p>Basic information about this zoraxy host</p>
|
||||
<table class="ui very basic collapsing celled table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Host UUID</td>
|
||||
<td class="uuid"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td class="version"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Build</td>
|
||||
<td class="development"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Running Since</td>
|
||||
<td class="boottime"></td>
|
||||
</tr>
|
||||
|
||||
<div class="field">
|
||||
<p><i class="caret down icon"></i> Credentials for SMTP server authentications</p>
|
||||
<div class="two fields">
|
||||
<div class="field">
|
||||
<label>Sender Username</label>
|
||||
<input type="text" name="username" placeholder="E.g. admin">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Sender Domain</label>
|
||||
<div class="ui labeled input">
|
||||
<div class="ui basic label">
|
||||
@
|
||||
</div>
|
||||
<input type="text" name="domain" min="1" max="65534" placeholder="E.g. arozos.com">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Sender Password</label>
|
||||
<input type="password" name="password" placeholder="Password of the email account">
|
||||
<small>Leave empty to use the old password</small>
|
||||
</div>
|
||||
|
||||
<p> <i class="caret down icon"></i> Email for sending account reset link</p>
|
||||
<div class="field">
|
||||
<label>Admin / Receiver Address</label>
|
||||
<input type="text" name="recvAddr" placeholder="E.g. personalEmail@gmail.com">
|
||||
</div>
|
||||
|
||||
<tr>
|
||||
<td>ZeroTier Linked</td>
|
||||
<td class="zt"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Enable SSH Loopback</td>
|
||||
<td class="sshlb"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Zoraxy is developed by tobychui for <a href="//imuslab.com" target="_blank">imuslab</a> and open source under <a href="https://www.gnu.org/licenses/agpl-3.0.txt">AGPL</a></p>
|
||||
<button class="ui basic button" type="submit"><i class="blue save icon"></i> Set SMTP Configs</button>
|
||||
<button class="ui basic button" onclick="event.preventDefault(); sendTestEmail(this);"><i class="teal mail icon"></i> Send Test Email</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui bottom attached tab segment nettoolstab" data-tab="tab2">
|
||||
<h3> IP Address to CIDR</h3>
|
||||
<p>No experience with CIDR notations? Here are some tools you can use to make setting up easier.</p>
|
||||
<div class="ui basic segment">
|
||||
<h5><i class="chevron down icon"></i> IP Range to CIDR Conversion</h5>
|
||||
<div class="ui message">
|
||||
<i class="info circle icon"></i> Note that the CIDR generated here covers additional IP address before or after the given range. If you need more details settings, please use CIDR with a smaller range and add additional IPs for detail range adjustment.
|
||||
</div>
|
||||
<div class="ui input">
|
||||
<input type="text" placeholder="Start IP" id="startIpInput">
|
||||
</div>
|
||||
<div class="ui input">
|
||||
<input type="text" placeholder="End IP" id="endIpInput">
|
||||
</div>
|
||||
<br>
|
||||
<button style="margin-top: 0.6em;" class="ui basic button" onclick="convertToCIDR()">Convert</button>
|
||||
<p>Results: <div id="cidrOutput">N/A</div></p>
|
||||
</div>
|
||||
|
||||
<div class="ui basic segment">
|
||||
<h5><i class="chevron down icon"></i> CIDR to IP Range Conversion</h5>
|
||||
<div class="ui action input">
|
||||
<input type="text" placeholder="CIDR" id="cidrInput">
|
||||
<button class="ui basic button" onclick="convertToIPRange()">Convert</button>
|
||||
</div>
|
||||
<p>Results: <div id="ipRangeOutput">N/A</div></p>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
</div>
|
||||
<div class="ui bottom attached tab segment nettoolstab" data-tab="tab3">
|
||||
<!-- Config Tools -->
|
||||
<h3>System Backup & Restore</h3>
|
||||
<p>Options related to system backup, migrate and restore.</p>
|
||||
<button class="ui basic button" onclick="showSideWrapper('snippet/configTools.html');">Open Config Tools</button>
|
||||
<div class="ui divider"></div>
|
||||
<!-- System Information -->
|
||||
<div id="zoraxyinfo">
|
||||
<h3 class="ui header">
|
||||
System Information
|
||||
</h3>
|
||||
<p>Basic information about this zoraxy host</p>
|
||||
<table class="ui very basic collapsing celled table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Host UUID</td>
|
||||
<td class="uuid"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td class="version"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Build</td>
|
||||
<td class="development"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Running Since</td>
|
||||
<td class="boottime"></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>ZeroTier Linked</td>
|
||||
<td class="zt"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Enable SSH Loopback</td>
|
||||
<td class="sshlb"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Zoraxy is developed by tobychui for <a href="//imuslab.com" target="_blank">imuslab</a> and open source under <a href="https://www.gnu.org/licenses/agpl-3.0.txt">AGPL</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
</div>
|
||||
<script>
|
||||
|
||||
$('.menu .nettools.item').tab();
|
||||
/*
|
||||
Account Password utilities
|
||||
*/
|
||||
@@ -171,6 +184,7 @@
|
||||
if (data == 0){
|
||||
//Using external auth manager. Hide options
|
||||
$(".selfauthOnly").hide();
|
||||
$(".extAuthOnly").show();
|
||||
}
|
||||
});
|
||||
|
||||
|
@@ -30,7 +30,7 @@
|
||||
<h4>Edit Virtual Directory Routing Rules</h4>
|
||||
<p>The following are the list of Virtual Directories currently handled by the host router above</p>
|
||||
<div style="width: 100%; overflow-x: auto; margin-bottom: 1em;">
|
||||
<table class="ui celled sortable basic unstackable compact table">
|
||||
<table class="ui celled sortable unstackable compact table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Virtual Directory</th>
|
||||
@@ -162,6 +162,7 @@
|
||||
//List the vdirs
|
||||
console.log(data);
|
||||
data.forEach(vdir => {
|
||||
var tlsIcon = "";
|
||||
if (vdir.RequireTLS){
|
||||
tlsIcon = `<i class="green lock icon" title="TLS Mode"></i>`;
|
||||
if (vdir.SkipCertValidations){
|
||||
|
@@ -4,7 +4,7 @@
|
||||
<p>A simple static web server that serve html css and js files</p>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
<div class="ui basic segment">
|
||||
<div class="ui basic segment webservRunningStateWrapper">
|
||||
<h4 class="ui header" id="webservRunningState">
|
||||
<i class="green circle icon"></i>
|
||||
<div class="content">
|
||||
@@ -102,12 +102,14 @@
|
||||
function setWebServerRunningState(running){
|
||||
if (running){
|
||||
$("#webserv_enable").parent().checkbox("set checked");
|
||||
$("#webservRunningState").find("i").attr("class", "green circle icon");
|
||||
$("#webservRunningState").find("i").attr("class", "white circle check icon");
|
||||
$("#webservRunningState").find(".webserv_status").text("Running");
|
||||
$(".webservRunningStateWrapper").addClass("enabled")
|
||||
}else{
|
||||
$("#webserv_enable").parent().checkbox("set unchecked");
|
||||
$("#webservRunningState").find("i").attr("class", "red circle icon");
|
||||
$("#webservRunningState").find("i").attr("class", "white circle times icon");
|
||||
$("#webservRunningState").find(".webserv_status").text("Stopped");
|
||||
$(".webservRunningStateWrapper").removeClass("enabled")
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user