From 634e9c985589e06a04e1af3073054c3cdee31113 Mon Sep 17 00:00:00 2001 From: Toby Chui Date: Fri, 8 Nov 2024 22:24:07 +0800 Subject: [PATCH] v3.1.3 init commit - Fixed #378 - Added wip dark theme - Fixed in code typo - Fixed int conversion bug in some DNS challenge supplier --- src/accesslist.go | 48 +++- src/main.go | 4 +- src/mod/acme/ca.go | 4 +- src/mod/update/v308/typedef307.go | 2 +- src/mod/update/v308/typedef308.go | 2 +- src/reverseproxy.go | 2 +- src/web/components/access.html | 223 ++++++++++++------- src/web/components/redirection.html | 2 +- src/web/components/rules.html | 2 +- src/web/components/status.html | 8 +- src/web/components/vdir.html | 2 +- src/web/darktheme.css | 330 ++++++++++++++++++++++++++++ src/web/index.html | 12 +- src/web/main.css | 39 ++-- src/web/script/darktheme.js | 51 +++++ src/web/snippet/acme.html | 16 +- src/web/snippet/customHeaders.html | 2 +- src/web/tools/fs.css | 2 +- 18 files changed, 629 insertions(+), 122 deletions(-) create mode 100644 src/web/darktheme.css create mode 100644 src/web/script/darktheme.js diff --git a/src/accesslist.go b/src/accesslist.go index 46155dd..2df35d7 100644 --- a/src/accesslist.go +++ b/src/accesslist.go @@ -230,7 +230,17 @@ func handleCountryBlacklistAdd(w http.ResponseWriter, r *http.Request) { return } - rule.AddCountryCodeToBlackList(countryCode, comment) + //Check if the country code contains comma, if yes, split it + if strings.Contains(countryCode, ",") { + codes := strings.Split(countryCode, ",") + for _, code := range codes { + code = strings.TrimSpace(code) + rule.AddCountryCodeToBlackList(code, comment) + } + } else { + countryCode = strings.TrimSpace(countryCode) + rule.AddCountryCodeToBlackList(countryCode, comment) + } utils.SendOK(w) } @@ -254,7 +264,17 @@ func handleCountryBlacklistRemove(w http.ResponseWriter, r *http.Request) { return } - rule.RemoveCountryCodeFromBlackList(countryCode) + //Check if the country code contains comma, if yes, split it + if strings.Contains(countryCode, ",") { + codes := strings.Split(countryCode, ",") + for _, code := range codes { + code = strings.TrimSpace(code) + rule.RemoveCountryCodeFromBlackList(code) + } + } else { + countryCode = strings.TrimSpace(countryCode) + rule.RemoveCountryCodeFromBlackList(countryCode) + } utils.SendOK(w) } @@ -397,7 +417,17 @@ func handleCountryWhitelistAdd(w http.ResponseWriter, r *http.Request) { p := bluemonday.StrictPolicy() comment = p.Sanitize(comment) - rule.AddCountryCodeToWhitelist(countryCode, comment) + //Check if the country code contains comma, if yes, split it + if strings.Contains(countryCode, ",") { + codes := strings.Split(countryCode, ",") + for _, code := range codes { + code = strings.TrimSpace(code) + rule.AddCountryCodeToWhitelist(code, comment) + } + } else { + countryCode = strings.TrimSpace(countryCode) + rule.AddCountryCodeToWhitelist(countryCode, comment) + } utils.SendOK(w) } @@ -420,7 +450,17 @@ func handleCountryWhitelistRemove(w http.ResponseWriter, r *http.Request) { return } - rule.RemoveCountryCodeFromWhitelist(countryCode) + //Check if the country code contains comma, if yes, split it + if strings.Contains(countryCode, ",") { + codes := strings.Split(countryCode, ",") + for _, code := range codes { + code = strings.TrimSpace(code) + rule.RemoveCountryCodeFromWhitelist(code) + } + } else { + countryCode = strings.TrimSpace(countryCode) + rule.RemoveCountryCodeFromWhitelist(countryCode) + } utils.SendOK(w) } diff --git a/src/main.go b/src/main.go index 630cadf..2b54f5e 100644 --- a/src/main.go +++ b/src/main.go @@ -60,9 +60,9 @@ var enableAutoUpdate = flag.Bool("cfgupgrade", true, "Enable auto config upgrade var ( name = "Zoraxy" - version = "3.1.2" + version = "3.1.3" nodeUUID = "generic" //System uuid, in uuidv4 format - development = false //Set this to false to use embedded web fs + development = true //Set this to false to use embedded web fs bootTime = time.Now().Unix() /* diff --git a/src/mod/acme/ca.go b/src/mod/acme/ca.go index b673170..fb62b8e 100644 --- a/src/mod/acme/ca.go +++ b/src/mod/acme/ca.go @@ -3,7 +3,7 @@ package acme /* CA.go - This script load CA defination from embedded ca.json + This script load CA definition from embedded ca.json */ import ( _ "embed" @@ -13,7 +13,7 @@ import ( "strings" ) -// CA Defination, load from embeded json when startup +// CA definition, load from embeded json when startup type CaDef struct { Production map[string]string Test map[string]string diff --git a/src/mod/update/v308/typedef307.go b/src/mod/update/v308/typedef307.go index 17c6d18..980f8e5 100644 --- a/src/mod/update/v308/typedef307.go +++ b/src/mod/update/v308/typedef307.go @@ -1,7 +1,7 @@ package v308 /* - v307 type definations + v307 type definitions This file wrap up the self-contained data structure for v3.0.7 structure and allow automatic updates diff --git a/src/mod/update/v308/typedef308.go b/src/mod/update/v308/typedef308.go index 02a592e..f5364cb 100644 --- a/src/mod/update/v308/typedef308.go +++ b/src/mod/update/v308/typedef308.go @@ -1,7 +1,7 @@ package v308 /* - v308 type definations + v308 type definition This file wrap up the self-contained data structure for v3.0.8 structure and allow automatic updates diff --git a/src/reverseproxy.go b/src/reverseproxy.go index 4ef44f9..3a1d3da 100644 --- a/src/reverseproxy.go +++ b/src/reverseproxy.go @@ -1173,7 +1173,7 @@ func HandleCustomHeaderAdd(w http.ResponseWriter, r *http.Request) { return } - //Create a Custom Header Defination type + //Create a Custom Header Definition type var rewriteDirection rewrite.HeaderDirection if direction == "toOrigin" { rewriteDirection = rewrite.HeaderDirection_ZoraxyToUpstream diff --git a/src/web/components/access.html b/src/web/components/access.html index 462369b..10f5437 100644 --- a/src/web/components/access.html +++ b/src/web/components/access.html @@ -841,6 +841,25 @@ function initBannedCountryList(){ $.get("/api/blacklist/list?type=country&id=" + currentEditingAccessRule, function(data) { let bannedListHtml = ''; + + //Check if the country code list contains all eu countries. If yes, replace it with "EU" + let allEu = true; + let euCountries = getEUCCs(); + for (var i = 0; i < euCountries.length; i++){ + if (!data.includes(euCountries[i])){ + allEu = false; + break; + } + } + + if (allEu){ + //Remove EU countries from the list and replace it with EU + data = data.filter(function(value, index, arr){ + return !euCountries.includes(value); + }); + data.push("eu"); + } + data.forEach((countryCode) => { bannedListHtml += ` @@ -919,18 +938,48 @@ //Whitelist country table function initWhitelistCountryList(){ $.get("/api/whitelist/list?type=country&id=" + currentEditingAccessRule, function(data) { - let bannedListHtml = ''; + let whiteListHTML = ''; + + //Check if the country code list contains all eu countries. If yes, replace it with "EU" + let allEu = true; + let euCountries = getEUCCs(); + let countryCodesIndata = data.map(function(item){ + //data[n].CC is the country code + return item.CC; + }); + for (var i = 0; i < euCountries.length; i++){ + if (!countryCodesIndata.includes(euCountries[i])){ + allEu = false; + break; + } + } + + if (allEu){ + //Remove EU countries from the list and replace it with EU + data = data.filter(function(value, index, arr){ + return !euCountries.includes(value.CC); + }); + data.push({ + CC: "eu" + }); + } + data.forEach((countryWhitelistEntry) => { let countryCode = countryWhitelistEntry.CC; - bannedListHtml += ` + whiteListHTML += ` ${getCountryName(countryCode)} (${countryCode.toUpperCase()}) `; }); - $('#whitelistCountryList').html(bannedListHtml); - filterCountries(data, "#countrySelectorWhitelist .menu .item"); + $('#whitelistCountryList').html(whiteListHTML); + + //Map the data.CC to the country code + let countryCodes = data.map(function(item){ + return item.CC; + }); + filterCountries(countryCodes, "#countrySelectorWhitelist .menu .item"); if (data.length === 0) { $('#whitelistCountryList').append(` @@ -1016,6 +1065,10 @@ }); } + function getEUCCs(){ + return ["at","be","bg","cy","cz","de","dk","ee","es","fi","fr","gr","hr","hu","ie","it","lt","lu","lv","mt","nl","pl","pt","se","si","sk"]; + } + function addCountryToBlacklist() { var countryCode = $("#countrySelector").dropdown("get value").toLowerCase(); let ccs = [countryCode]; @@ -1025,48 +1078,50 @@ ccs = countryCode.split(","); } - let counter = 0; - for(var i = 0; i < ccs.length; i++){ - let thisCountryCode = ccs[i]; - $.cjax({ - type: "POST", - url: "/api/blacklist/country/add", - method: "POST", - data: { cc: thisCountryCode, id: currentEditingAccessRule}, - success: function(response) { - if (response.error != undefined){ - msgbox(response.error, false); - } - - if (counter == (ccs.length - 1)){ - //Last item - setTimeout(function(){ - initBannedCountryList(); - if (ccs.length == 1){ - //Single country - msgbox(`Added ${getCountryName(ccs[0])} to blacklist`); - }else{ - msgbox(ccs.length + " countries added to blacklist"); - } - - }, (ccs.length==1)?0:100); - } - counter++; - }, - error: function(xhr, status, error) { - // handle error response - } + //If the ccs includes "eu", remove the "eu" and add all eu country code to the list + if (ccs.includes("eu")){ + ccs = ccs.concat(getEUCCs()); + ccs = ccs.filter(function(item){ + return item != "eu"; }); } - - + + let counter = ccs.length; + $.cjax({ + type: "POST", + url: "/api/blacklist/country/add", + method: "POST", + data: { cc: ccs.join(","), id: currentEditingAccessRule}, + success: function(response) { + if (response.error != undefined){ + msgbox(response.error, false); + } + initBannedCountryList(); + if (ccs.length == 1){ + //Single country + msgbox(`Added ${getCountryName(ccs[0])} to blacklist`); + }else{ + msgbox(ccs.length + " countries added to blacklist"); + } + }, + error: function(xhr, status, error) { + // handle error response + } + }); $('#countrySelector').dropdown('clear'); - } function removeFromBannedList(countryCode){ - countryCode = countryCode.toLowerCase(); let countryName = getCountryName(countryCode); + if (countryCode == "eu"){ + let euCountries = getEUCCs(); + countryCode = euCountries.join(","); + countryName = "European Union"; + }else{ + countryCode = countryCode.toLowerCase(); + } + + $.cjax({ url: "/api/blacklist/country/remove", method: "POST", @@ -1162,44 +1217,53 @@ //Usually just a few countries a for loop will get the job done ccs = countryCode.split(","); } - - let counter = 0; - for(var i = 0; i < ccs.length; i++){ - let thisCountryCode = ccs[i]; - $.cjax({ - type: "POST", - url: "/api/whitelist/country/add", - data: { cc: thisCountryCode , id: currentEditingAccessRule}, - success: function(response) { - if (response.error != undefined){ - msgbox(response.error, false); - } - if (counter == (ccs.length - 1)){ - setTimeout(function(){ - initWhitelistCountryList(); - if (ccs.length == 1){ - //Single country - msgbox(`Added ${getCountryName(ccs[0])} to whitelist`); - }else{ - msgbox(ccs.length + " countries added to whitelist"); - } - }, (ccs.length==1)?0:100); - } - counter++; - }, - error: function(xhr, status, error) { - // handle error response - } + //If the ccs includes "eu", remove the "eu" and add all eu country code to the list + if (ccs.includes("eu")){ + ccs = ccs.filter(function(item){ + return item != "eu"; }); + ccs = ccs.concat(getEUCCs()); } + let counter = ccs.length; + $.cjax({ + type: "POST", + url: "/api/whitelist/country/add", + data: { cc: ccs.join(",") , id: currentEditingAccessRule}, + success: function(response) { + if (response.error != undefined){ + msgbox(response.error, false); + } + + initWhitelistCountryList(); + if (ccs.length == 1){ + //Single country + msgbox(`Added ${getCountryName(ccs[0])} to whitelist`); + }else{ + msgbox(ccs.length + " countries added to whitelist"); + } + }, + error: function(xhr, status, error) { + // handle error response + } + }); + + $('#countrySelectorWhitelist').dropdown('clear'); } - function removeFromWhiteList(countryCode){ - if (confirm("Confirm removing " + getCountryName(countryCode) + " from whitelist?")){ + //Remove from whitelist, accepts a country code or "eu" for all EU countries + function removeFromWhiteList(countryCode, skipConfirm = true){ + let countryName = getCountryName(countryCode); + if (countryCode == "eu"){ + let euCountries = getEUCCs(); + countryCode = euCountries.join(","); + countryName = "European Union"; + }else{ countryCode = countryCode.toLowerCase(); + } + if (skipConfirm || confirm("Confirm removing " + getCountryName(countryCode) + " from whitelist?")){ $.cjax({ url: "/api/whitelist/country/remove", method: "POST", @@ -1208,6 +1272,7 @@ if (response.error != undefined){ msgbox(response.error, false); } + msgbox(countryName + " removed from whitelist"); initWhitelistCountryList(); }, error: function(xhr, status, error) { @@ -1276,19 +1341,27 @@ /* Common Utilities */ - function filterCountries(codesToShow, selector="#countrySelector .menu .item") { + function filterCountries(alreadySelectedCCs, selector="#countrySelector .menu .item") { // get all items in the dropdown const items = document.querySelectorAll(selector); + const euCountries = getEUCCs(); + //Replce "eu" in alreadySelectedCCs with all EU countries + if (alreadySelectedCCs.includes("eu")){ + alreadySelectedCCs = alreadySelectedCCs.filter(function(item){ + return item != "eu"; + }); + alreadySelectedCCs = alreadySelectedCCs.concat(euCountries); + } + // loop through all items items.forEach(item => { // get the value of the item (i.e. the country code) const code = item.dataset.value; - // if the code is in the array of codes to show, show the item - if (codesToShow.includes(code)) { + if (alreadySelectedCCs.includes(code)) { + //This country code already selected. Hide it item.style.display = 'none'; - } - // otherwise, hide the item - else { + } else { + // otherwise, show the item item.style.display = 'block'; } }); diff --git a/src/web/components/redirection.html b/src/web/components/redirection.html index 40bbeb4..4ef40f2 100644 --- a/src/web/components/redirection.html +++ b/src/web/components/redirection.html @@ -30,7 +30,7 @@ Redirection Rule Deleted -
+
diff --git a/src/web/components/rules.html b/src/web/components/rules.html index fa4b078..6ce8ead 100644 --- a/src/web/components/rules.html +++ b/src/web/components/rules.html @@ -50,7 +50,7 @@
-
+
diff --git a/src/web/components/status.html b/src/web/components/status.html index 5ab73c5..abef39e 100644 --- a/src/web/components/status.html +++ b/src/web/components/status.html @@ -94,7 +94,7 @@
-
+
@@ -579,7 +579,7 @@ let timestamps = []; for(var i = 0; i < dataCount; i++){ - timestamps.push(parseInt(Date.now() / 1000) + i); + timestamps.push(new Date(Date.now() + i * 1000).toLocaleString().replace(',', '')); } function fetchData() { @@ -600,10 +600,8 @@ txValues.shift(); } - - timestamps.push(parseInt(Date.now() / 1000)); + timestamps.push(new Date(Date.now()).toLocaleString().replace(',', '')); timestamps.shift(); - updateChart(); } }) diff --git a/src/web/components/vdir.html b/src/web/components/vdir.html index 8d8d7b2..2553fd3 100644 --- a/src/web/components/vdir.html +++ b/src/web/components/vdir.html @@ -69,7 +69,7 @@
-
+
diff --git a/src/web/darktheme.css b/src/web/darktheme.css new file mode 100644 index 0000000..6018b63 --- /dev/null +++ b/src/web/darktheme.css @@ -0,0 +1,330 @@ +/* + Darktheme CSS + + This file contains the CSS for the dark theme. + This will override the default CSS (white theme) for semantic UI +*/ + +body.darkTheme { + background-color: var(--theme_bg); + color: var(--text_color); +} + +body.darkTheme h1, +body.darkTheme h2, +body.darkTheme h3, +body.darkTheme h4, +body.darkTheme h5, +body.darkTheme h6, +body.darkTheme a { + color: var(--text_color); +} + +body.darkTheme .ui.header { + color: var(--text_color) !important; +} + +body.darkTheme p, +body.darkTheme span{ + color: var(--text_color_secondary); +} + +body.darkTheme .ui.secondary.menu .dropdown.item:hover, +body.darkTheme .ui.secondary.menu .link.item:hover, +body.darkTheme .ui.secondary.menu a.item:hover { + color: var(--text_color) !important; +} + +body.darkTheme .ui.basic.white.icon.button { + background-color: transparent !important; + border: none !important; +} + +body.darkTheme .ui.basic.white.icon.button:hover { + border: none !important; + opacity: 0.8; +} + +body.darkTheme .ui.basic.white.icon.button:disabled { + border: none !important; + opacity: 0.5; +} + +body.darkTheme .ui.basic.buttons .button i.icon { + color: #ffffff !important; +} + +body.darkTheme .ui.basic.button:not(.red) { + color: #ffffff !important; + border: 1px solid var(--button_border_color) !important; +} + +body.darkTheme .ui.basic.button:not(.red):hover { + border: 1px solid var(--button_border_color) !important; + background-color: var(--theme_bg) !important; + opacity: 0.8; +} + +body.darkTheme .ui.basic.button.red:hover { + background-color: #380a0a !important; + opacity: 0.8; +} + +body.darkTheme .ui.basic.button:disabled { + border: none !important; + background-color: transparent !important; + opacity: 0.5; +} + +body.darkTheme .ui.basic.button:focus, +body.darkTheme .ui.basic.buttons .button:focus { + background: transparent !important; + background-color: transparent !important; + border: none !important; +} + + +body.darkTheme .ui.table thead th, +body.darkTheme .ui.table tbody td, +body.darkTheme .ui.table tfoot td { + color: #ffffff !important; +} + +body.darkTheme .ui.input input, +body.darkTheme .ui.input input::placeholder, +body.darkTheme .ui.input input:focus, +body.darkTheme .ui.input input:active { + color: #ffffff !important; + border-color: #ffffff !important; +} + +body.darkTheme .ui.input input { + background-color: var(--theme_bg_active) !important; + border: 1px solid transparent !important; +} + +body.darkTheme .ui.input input:focus, +body.darkTheme .ui.input input:active { + border-color: var(--theme_highlight) !important; +} + +body.darkTheme .ui.input input::placeholder { + opacity: 0.7; +} + +body.darkTheme .ui.label, +body.darkTheme .ui.label .detail, +body.darkTheme .ui.label .icon { + color: #ffffff !important; +} + +body.darkTheme .advanceoptions .title { + color: var(--text_color_secondary) !important; +} + +body.darkTheme .ui.toggle.checkbox input ~ .box, +body.darkTheme .ui.toggle.checkbox input ~ label, +body.darkTheme .ui.toggle.checkbox input ~ label:focus { + color: var(--text_color_secondary) !important; +} + + +body.darkTheme .ui.toggle.checkbox input ~ label::before{ + background-color: var(--theme_bg_secondary) !important; +} +body.darkTheme .ui.toggle.checkbox input:checked ~ label::before{ + background-color: var(--theme_highlight) !important; +} + + + +body.darkTheme .ui.segment:not(.basic) { + background-color: var(--theme_bg) !important; + color: var(--text_color) !important; + border: 1px solid transparent !important; +} + +body.darkTheme .sub.header { + color: var(--text_color) !important; +} + +body.darkTheme .ui.radio.defaultsite.checkbox label { + color: var(--text_color) !important; +} + +body.darkTheme .ui.radio.defaultsite.checkbox label small { + color: var(--text_color_secondary) !important; +} + +body.darkTheme .ui.form .field input, +body.darkTheme .ui.form .field input::placeholder, +body.darkTheme .ui.form .field input:focus, +body.darkTheme .ui.form .field input:active { + color: var(--text_color) !important; + border-color: 1px solid transparent !important; + background-color: var(--theme_bg_active) !important; +} + +body.darkTheme .ui.form .field input::placeholder { + opacity: 0.7; +} + +body.darkTheme .ui.form .field label, +body.darkTheme .ui.form .field .ui.checkbox input:checked ~ label { + color: var(--text_color) !important; +} + +body.darkTheme .ui.basic.label { + background-color: var(--theme_bg_secondary) !important; + color: var(--text_color) !important; +} + +/* + HTTP Proxy Table +*/ +body.darkTheme .ui.table{ + background-color: transparent !important; +} +body.darkTheme .ui.celled.sortable.unstackable.compact.table thead th, +body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td, +body.darkTheme .ui.celled.sortable.unstackable.compact.table tfoot td { + background-color: var(--theme_bg) !important; + color: var(--text_color) !important; + border-color: var(--divider_color) !important; +} + +body.darkTheme .ui.celled.sortable.unstackable.compact.table thead th { + background-color: var(--theme_bg_secondary) !important; +} + +body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody tr:hover { + background-color: var(--theme_bg_hover) !important; +} + +body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td a { + color: var(--link_color) !important; +} + +body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td a:hover { + color: var(--link_hover_color) !important; +} + +body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td small { + color: var(--text_color_secondary) !important; +} + +body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.toggle.checkbox input ~ .box, +body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.toggle.checkbox input ~ label, +body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.toggle.checkbox input ~ label:focus { + color: var(--text_color_secondary) !important; +} + +body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.toggle.checkbox input ~ label::before { + background-color: var(--theme_bg_secondary) !important; +} + +body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.toggle.checkbox input:checked ~ label::before { + background-color: var(--theme_highlight) !important; +} + +body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.circular.mini.basic.icon.button { + color: var(--button_color) !important; + border: 1px solid var(--button_border_color) !important; +} + +body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.circular.mini.basic.icon.button:hover { + background-color: var(--button_hover_bg) !important; + color: var(--button_hover_color) !important; + border: 1px solid var(--button_border_color) !important; +} + +body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.circular.mini.red.basic.icon.button { + color: var(--button_red_color) !important; + border: 1px solid var(--button_red_border_color) !important; +} + +body.darkTheme .ui.celled.sortable.unstackable.compact.table tbody td .ui.circular.mini.red.basic.icon.button:hover { + background-color: #380a0a !important; + color: var(--button_red_hover_color) !important; + +} + +body.darkTheme .ui.basic.small.icon.circular.button { + color: var(--button_color) !important; + border: 1px solid var(--button_border_color) !important; +} + +body.darkTheme .ui.basic.small.icon.circular.button:hover { + background-color: var(--button_hover_bg) !important; + color: var(--button_hover_color) !important; + border: 1px solid var(--button_border_color) !important; + opacity: 0.8; +} + +body.darkTheme .ui.checkbox input ~ .box, +body.darkTheme .ui.checkbox input ~ label, +body.darkTheme .ui.checkbox input ~ label:focus { + color: var(--text_color_secondary) !important; +} + +body.darkTheme .ui.basic.advance.segment { + background-color: var(--theme_bg) !important; + color: var(--text_color) !important; + border: 1px solid var(--divider_color) !important; +} + +body.darkTheme .ui.endpointAdvanceConfig.accordion .title { + color: var(--text_color) !important; +} + +/* + Virtual Directorie Table + +*/ + +body.darkTheme .ui.fluid.search.selection.dropdown { + background-color: var(--theme_bg) !important; + color: var(--text_color) !important; + border-color: transparent !important; +} + +body.darkTheme .ui.fluid.search.selection.dropdown .menu { + background-color: var(--theme_bg) !important; + color: var(--text_color) !important; +} + +body.darkTheme .ui.fluid.search.selection.dropdown .menu .item { + color: var(--text_color) !important; +} + +body.darkTheme .ui.selection.dropdown .menu > .item { + border-top: 1px solid var(--divider_color) !important; +} + +body.darkTheme .ui.selection.active.dropdown .menu { + border-color: var(--divider_color) !important; +} + +body.darkTheme .ui.fluid.search.selection.dropdown .menu .item:hover { + background-color: var(--theme_bg_hover) !important; + color: var(--text_color) !important; +} + +body.darkTheme .ui.fluid.search.selection.dropdown .menu .item.active.selected { + background-color: var(--theme_highlight) !important; + color: var(--text_color) !important; +} + +body.darkTheme .ui.fluid.search.selection.dropdown .search { + background-color: var(--theme_bg) !important; + color: var(--text_color) !important; + border-color: transparent !important; +} + +body.darkTheme .ui.fluid.search.selection.dropdown .text { + color: var(--text_color) !important; +} + +body.darkTheme .ui.fluid.search.selection.dropdown .dropdown.icon { + color: var(--text_color) !important; +} \ No newline at end of file diff --git a/src/web/index.html b/src/web/index.html index a767e32..c025184 100644 --- a/src/web/index.html +++ b/src/web/index.html @@ -16,8 +16,10 @@ + +
@@ -269,11 +271,9 @@ function toggleTheme(){ if ($("body").hasClass("darkTheme")){ - $("body").removeClass("darkTheme") - $("#themeColorButton").html(``); + setDarkTheme(false); }else{ - $("body").addClass("darkTheme"); - $("#themeColorButton").html(``); + setDarkTheme(true); } } diff --git a/src/web/main.css b/src/web/main.css index f7e5861..1ce8364 100644 --- a/src/web/main.css +++ b/src/web/main.css @@ -2,13 +2,10 @@ index.html style overwrite */ :root{ - --theme_background: linear-gradient(60deg, rgb(84, 58, 183) 0%, rgb(0, 172, 193) 100%); - --theme_background_inverted: linear-gradient(215deg, rgba(38,60,71,1) 13%, rgba(2,3,42,1) 84%); - --theme_green: linear-gradient(270deg, #27e7ff, #00ca52); - --theme_red: linear-gradient(203deg, rgba(250,172,38,1) 17%, rgba(202,0,37,1) 78%); + } -/* Theme Color Definations */ +/* Theme Color Definition */ body:not(.darkTheme){ --theme_bg: #f6f6f6; --theme_bg_primary: #ffffff; @@ -16,7 +13,7 @@ body:not(.darkTheme){ --theme_bg_active: #ececec; --theme_highlight: #a9d1f3; --theme_bg_inverted: #27292d; - --theme_advance: #f8f8f9; + --theme_advance: #f7f7f7; --item_color: #5e5d5d; --item_color_select: rgba(0,0,0,.87); --text_color: #414141; @@ -25,25 +22,35 @@ body:not(.darkTheme){ --text_color_inverted: #fcfcfc; --button_text_color: #878787; --button_border_color: #dedede; + + --theme_background: linear-gradient(60deg, rgb(84, 58, 183) 0%, rgb(0, 172, 193) 100%); + --theme_background_inverted: linear-gradient(215deg, rgba(38,60,71,1) 13%, rgba(2,3,42,1) 84%); + --theme_green: linear-gradient(270deg, #27e7ff, #00ca52); + --theme_red: linear-gradient(203deg, rgba(250,172,38,1) 17%, rgba(202,0,37,1) 78%); } body.darkTheme{ - --theme_bg: #27292d; - --theme_bg_primary: #3d3f47; - --theme_bg_secondary: #373a42; - --theme_highlight: #6682c4; - --theme_bg_active: #292929; + --theme_bg: #000000; + --theme_bg_primary: #141414; + --theme_bg_secondary:#230046; + --theme_highlight: #320064; + --theme_bg_active: #020101; --theme_bg_inverted: #f8f8f9; - --theme_advance: #333333; + --theme_advance: #000000; --item_color: #cacaca; - --text_color: #fcfcfc; - --text_color_secondary: #dfdfdf; + --text_color: #eef1f3; + --text_color_secondary: #b5c0c7; --input_color: black; - --divider_color: #3b3b3b; + --divider_color: #282828; --item_color_select: rgba(255, 255, 255, 0.87); --text_color_inverted: #414141; --button_text_color: #e9e9e9; --button_border_color: #646464; + + --theme_background: linear-gradient(214deg, rgba(3,1,70,1) 17%, rgba(60,1,80,1) 78%); + --theme_background_inverted: linear-gradient(215deg, rgba(38,60,71,1) 13%, rgba(2,3,42,1) 84%); + --theme_green: linear-gradient(214deg, rgba(25,128,94,1) 17%, rgba(62,76,111,1) 78%); + --theme_red: linear-gradient(203deg, rgba(250,172,38,1) 17%, rgba(202,0,37,1) 78%); } /* Theme Toggle CSS */ @@ -368,7 +375,7 @@ body{ } .basic.segment.advanceoptions{ - background-color: #f7f7f7; + background-color: var(--theme_advance); border-radius: 1em; } diff --git a/src/web/script/darktheme.js b/src/web/script/darktheme.js new file mode 100644 index 0000000..8a01b82 --- /dev/null +++ b/src/web/script/darktheme.js @@ -0,0 +1,51 @@ +/* + Dark Theme Toggle Manager + + This script is used to manage the dark theme toggle button in the header of the website. + It will change the theme of the website to dark mode when the toggle is clicked and back to light mode when clicked again. + + Must be included just after the start of body tag in the HTML file. +*/ + +function _whiteThemeHandleApplyChange(){ + $(".menubar .logo").attr("src", "img/logo.svg"); +} + +function _darkThemeHandleApplyChange(){ + $(".menubar .logo").attr("src", "img/logo_white.svg"); +} + + + //Check if the theme is dark, must be done before the body is loaded to prevent flickering + function setDarkTheme(isDarkTheme = false){ + if (isDarkTheme){ + $("body").addClass("darkTheme"); + $("#themeColorButton").html(``); + localStorage.setItem("theme", "dark"); + + //Check if the page is still loading, if not change the logo + if (document.readyState == "complete"){ + _darkThemeHandleApplyChange(); + }else{ + //Wait for the page to load and then change the logo + $(document).ready(function(){ + _darkThemeHandleApplyChange(); + }); + } + }else{ + $("body").removeClass("darkTheme") + $("#themeColorButton").html(``); + localStorage.setItem("theme", "light"); + //By default the page is white theme. So no need to change the logo if page is still loading + if (document.readyState == "complete"){ + //Switching back to light theme + _whiteThemeHandleApplyChange(); + } + } +} + +if (localStorage.getItem("theme") == "dark"){ + setDarkTheme(true); +}else{ + setDarkTheme(false); +} \ No newline at end of file diff --git a/src/web/snippet/acme.html b/src/web/snippet/acme.html index 6dd80b7..e4a5b24 100644 --- a/src/web/snippet/acme.html +++ b/src/web/snippet/acme.html @@ -50,7 +50,7 @@
If you don't want to share your private email address, you can also fill in an email address that point to a mailbox not exists on your domain.
-
+
@@ -437,11 +437,15 @@ let optionalFieldsHTML = ""; for (const [key, datatype] of Object.entries(data)) { if (datatype == "int"){ - $("#dnsProviderAPIFields").append(`
+ let defaultValue = 10; + if (key == "HTTPTimeout"){ + defaultValue = 300; + } + $("#dnsProviderAPIFields").append(`
${key}
- +
`); }else if (datatype == "bool"){ booleanFieldsHTML += (`
@@ -600,8 +604,12 @@ //Boolean option let checked = $(this).find("input")[0].checked; dnsCredentials[thisKey] = checked; + }else if ($(this).hasClass("typeint")){ + //Int options + let value = $(this).find("input").val(); + dnsCredentials[thisKey] = parseInt(value); }else{ - //String or int options + //String options let value = $(this).find("input").val().trim(); dnsCredentials[thisKey] = value; } diff --git a/src/web/snippet/customHeaders.html b/src/web/snippet/customHeaders.html index 3167e64..36ee37b 100644 --- a/src/web/snippet/customHeaders.html +++ b/src/web/snippet/customHeaders.html @@ -86,7 +86,7 @@
-
+
diff --git a/src/web/tools/fs.css b/src/web/tools/fs.css index 2e785b1..5345604 100644 --- a/src/web/tools/fs.css +++ b/src/web/tools/fs.css @@ -6,7 +6,7 @@ */ /* - Color definations + Color definition */ :root{ --dark_theme_toggle: #333333;