From 1e5e1ff0b9264ef2cc2e6660ab5a605e624f1a1d Mon Sep 17 00:00:00 2001 From: kr-ilya Date: Sun, 30 Nov 2025 23:46:07 +0300 Subject: [PATCH 1/4] Fix panel redirect logic --- web/html/settings.html | 51 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/web/html/settings.html b/web/html/settings.html index e664e6ec..54c68d1c 100644 --- a/web/html/settings.html +++ b/web/html/settings.html @@ -120,6 +120,10 @@ oldAllSetting: new AllSetting(), allSetting: new AllSetting(), saveBtnDisable: true, + entryHost: null, + entryPort: null, + entryProtocol: null, + entryIsIP: false, user: {}, lang: LanguageManager.getLanguage(), inboundOptions: [], @@ -233,6 +237,9 @@ loading(spinning = true) { this.loadingStates.spinning = spinning; }, + _isIp(h) { + return /^[0-9.]+$/.test(h) || /^[0-9a-fA-F:]+$/.test(h); + }, async getAllSetting() { const msg = await HttpUtil.post("/panel/setting/all"); @@ -307,16 +314,38 @@ this.loading(true); const msg = await HttpUtil.post("/panel/setting/restartPanel"); this.loading(false); - if (msg.success) { - this.loading(true); - await PromiseUtil.sleep(5000); - var { webCertFile, webKeyFile, webDomain: host, webPort: port, webBasePath: base } = this.allSetting; - if (host == this.oldAllSetting.webDomain) host = null; - if (port == this.oldAllSetting.webPort) port = null; - const isTLS = webCertFile !== "" || webKeyFile !== ""; - const url = URLBuilder.buildURL({ host, port, isTLS, base, path: "panel/settings" }); - window.location.replace(url); + if (!msg.success) return; + + this.loading(true); + await PromiseUtil.sleep(5000); + + const { webDomain, webPort, webBasePath, webCertFile, webKeyFile } = this.allSetting; + const newProtocol = (webCertFile || webKeyFile) ? "https:" : "http:"; + + if (!this.entryIsIP) { + const url = new URL(window.location.href); + window.location.replace(url.toString()); + return; } + + let finalHost = this.entryHost; + let finalPort = this.entryPort || ""; + + if (webDomain && this._isIp(webDomain)) { + finalHost = webDomain; + } + + if (webPort && Number(webPort) !== Number(this.entryPort)) { + finalPort = String(webPort); + } + + const base = webBasePath ? webBasePath.replace(/^\//, "") : ""; + + const url = new URL(`${newProtocol}//${finalHost}`); + if (finalPort) url.port = finalPort; + url.pathname = `/${base}panel/settings`; + + window.location.replace(url.toString()); }, toggleTwoFactor(newValue) { if (newValue) { @@ -568,6 +597,10 @@ } }, async mounted() { + this.entryHost = window.location.hostname; + this.entryPort = window.location.port; + this.entryProtocol = window.location.protocol; + this.entryIsIP = this._isIp(this.entryHost); await this.getAllSetting(); await this.loadInboundTags(); while (true) { From 5d84ed255d0c88bcaeb805fd687e70e99a1865da Mon Sep 17 00:00:00 2001 From: kr-ilya Date: Mon, 1 Dec 2025 00:01:05 +0300 Subject: [PATCH 2/4] Fix panel redirect logic --- web/html/settings.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/html/settings.html b/web/html/settings.html index 54c68d1c..722dc64f 100644 --- a/web/html/settings.html +++ b/web/html/settings.html @@ -323,7 +323,9 @@ const newProtocol = (webCertFile || webKeyFile) ? "https:" : "http:"; if (!this.entryIsIP) { + const base = webBasePath ? webBasePath.replace(/^\//, "") : ""; const url = new URL(window.location.href); + url.pathname = `/${base}panel/settings`; window.location.replace(url.toString()); return; } From 5df9b4f5c2fc50ab491a48a0a0383858bb676b23 Mon Sep 17 00:00:00 2001 From: kr-ilya Date: Wed, 3 Dec 2025 23:12:03 +0300 Subject: [PATCH 3/4] remove duplicate code --- web/html/settings.html | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/web/html/settings.html b/web/html/settings.html index 722dc64f..20fa238e 100644 --- a/web/html/settings.html +++ b/web/html/settings.html @@ -322,8 +322,9 @@ const { webDomain, webPort, webBasePath, webCertFile, webKeyFile } = this.allSetting; const newProtocol = (webCertFile || webKeyFile) ? "https:" : "http:"; + const base = webBasePath ? webBasePath.replace(/^\//, "") : ""; + if (!this.entryIsIP) { - const base = webBasePath ? webBasePath.replace(/^\//, "") : ""; const url = new URL(window.location.href); url.pathname = `/${base}panel/settings`; window.location.replace(url.toString()); @@ -341,8 +342,6 @@ finalPort = String(webPort); } - const base = webBasePath ? webBasePath.replace(/^\//, "") : ""; - const url = new URL(`${newProtocol}//${finalHost}`); if (finalPort) url.port = finalPort; url.pathname = `/${base}panel/settings`; From 65a6401251f202cbea1c55aedbf5035fea549b40 Mon Sep 17 00:00:00 2001 From: kr-ilya Date: Thu, 11 Dec 2025 01:09:11 +0300 Subject: [PATCH 4/4] Cr fixes --- web/html/settings.html | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/web/html/settings.html b/web/html/settings.html index 20fa238e..21294da7 100644 --- a/web/html/settings.html +++ b/web/html/settings.html @@ -238,7 +238,29 @@ this.loadingStates.spinning = spinning; }, _isIp(h) { - return /^[0-9.]+$/.test(h) || /^[0-9a-fA-F:]+$/.test(h); + if (typeof h !== "string") return false; + + // IPv4: four dot-separated octets 0-255 + const v4 = h.split("."); + if ( + v4.length === 4 && + v4.every(p => /^\d{1,3}$/.test(p) && Number(p) <= 255) + ) return true; + + // IPv6: hex groups, optional single :: compression + if (!h.includes(":") || h.includes(":::")) return false; + const parts = h.split("::"); + if (parts.length > 2) return false; + + const splitGroups = s => (s ? s.split(":").filter(Boolean) : []); + const head = splitGroups(parts[0]); + const tail = splitGroups(parts[1]); + const validGroup = seg => /^[0-9a-fA-F]{1,4}$/.test(seg); + + if (![...head, ...tail].every(validGroup)) return false; + const groups = head.length + tail.length; + + return parts.length === 2 ? groups < 8 : groups === 8; }, async getAllSetting() { const msg = await HttpUtil.post("/panel/setting/all"); @@ -322,11 +344,13 @@ const { webDomain, webPort, webBasePath, webCertFile, webKeyFile } = this.allSetting; const newProtocol = (webCertFile || webKeyFile) ? "https:" : "http:"; - const base = webBasePath ? webBasePath.replace(/^\//, "") : ""; + let base = webBasePath ? webBasePath.replace(/^\//, "") : ""; + if (base && !base.endsWith("/")) base += "/"; if (!this.entryIsIP) { const url = new URL(window.location.href); url.pathname = `/${base}panel/settings`; + url.protocol = newProtocol; window.location.replace(url.toString()); return; }