diff --git a/install.sh b/install.sh index 42de8590..96e28caa 100644 --- a/install.sh +++ b/install.sh @@ -871,21 +871,60 @@ config_after_install() { ${xui_folder}/x-ui migrate } +get_releases() { + local releases_json + releases_json=$(curl -Ls "https://api.github.com/repos/Sora39831/3x-ui/releases") + if [[ -z "$releases_json" ]]; then + echo -e "${yellow}正在尝试通过 IPv4 获取版本...${plain}" + releases_json=$(curl -4 -Ls "https://api.github.com/repos/Sora39831/3x-ui/releases") + if [[ -z "$releases_json" ]]; then + echo -e "${red}获取 x-ui 版本失败,可能是 GitHub API 限制,请稍后重试${plain}" + exit 1 + fi + fi + + # Parse first non-prerelease tag_name + latest_stable=$(echo "$releases_json" | tr '{' '\n' | grep '"prerelease":false' | head -1 | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') + + # Parse first prerelease tag_name + latest_prerelease=$(echo "$releases_json" | tr '{' '\n' | grep '"prerelease":true' | head -1 | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') + + if [[ -z "$latest_stable" && -z "$latest_prerelease" ]]; then + echo -e "${red}获取 x-ui 版本失败${plain}" + exit 1 + fi +} + +select_version() { + if [[ -n "$latest_stable" && -n "$latest_prerelease" ]]; then + echo "" + echo -e "${green}请选择要安装的版本:${plain}" + echo -e "${green}1)${plain} 最新稳定版: ${latest_stable}" + echo -e "${green}2)${plain} 最新预发布版: ${latest_prerelease}" + read -rp "请输入选择 [1-2]: " version_choice + while [[ "$version_choice" != "1" && "$version_choice" != "2" ]]; do + read -rp "无效输入,请重新输入 [1-2]: " version_choice + done + if [[ "$version_choice" == "1" ]]; then + tag_version="$latest_stable" + else + tag_version="$latest_prerelease" + fi + elif [[ -n "$latest_stable" ]]; then + tag_version="$latest_stable" + else + tag_version="$latest_prerelease" + fi +} + install_x-ui() { cd ${xui_folder%/x-ui}/ # 下载资源 if [ $# == 0 ]; then - tag_version=$(curl -Ls "https://api.github.com/repos/Sora39831/3x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') - if [[ ! -n "$tag_version" ]]; then - echo -e "${yellow}正在尝试通过 IPv4 获取版本...${plain}" - tag_version=$(curl -4 -Ls "https://api.github.com/repos/Sora39831/3x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') - if [[ ! -n "$tag_version" ]]; then - echo -e "${red}获取 x-ui 版本失败,可能是 GitHub API 限制,请稍后重试${plain}" - exit 1 - fi - fi - echo -e "获取到 x-ui 最新版本:${tag_version},开始安装..." + get_releases + select_version + echo -e "获取到 x-ui 版本:${tag_version},开始安装..." curl -4fLRo ${xui_folder}-linux-$(arch).tar.gz https://github.com/Sora39831/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz if [[ $? -ne 0 ]]; then echo -e "${red}下载 x-ui 失败,请确保服务器可以访问 GitHub${plain}" diff --git a/update.sh b/update.sh index 9d890e60..eac108f7 100755 --- a/update.sh +++ b/update.sh @@ -745,6 +745,47 @@ config_after_update() { fi } +get_releases() { + local releases_json + releases_json=$(${curl_bin} -Ls "https://api.github.com/repos/Sora39831/3x-ui/releases" 2>/dev/null) + if [[ -z "$releases_json" ]]; then + echo -e "${yellow}Trying to fetch version with IPv4...${plain}" + releases_json=$(${curl_bin} -4 -Ls "https://api.github.com/repos/Sora39831/3x-ui/releases" 2>/dev/null) + if [[ -z "$releases_json" ]]; then + _fail "ERROR: Failed to fetch x-ui version, it may be due to GitHub API restrictions, please try it later" + fi + fi + + latest_stable=$(echo "$releases_json" | tr '{' '\n' | grep '"prerelease":false' | head -1 | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') + latest_prerelease=$(echo "$releases_json" | tr '{' '\n' | grep '"prerelease":true' | head -1 | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') + + if [[ -z "$latest_stable" && -z "$latest_prerelease" ]]; then + _fail "ERROR: Failed to fetch x-ui version" + fi +} + +select_version() { + if [[ -n "$latest_stable" && -n "$latest_prerelease" ]]; then + echo "" + echo -e "${green}Which version do you want to update to?${plain}" + echo -e "${green}1)${plain} Latest Stable: ${latest_stable}" + echo -e "${green}2)${plain} Latest Pre-release: ${latest_prerelease}" + read -rp "Please enter your choice [1-2]: " version_choice + while [[ "$version_choice" != "1" && "$version_choice" != "2" ]]; do + read -rp "Invalid input, please re-enter [1-2]: " version_choice + done + if [[ "$version_choice" == "1" ]]; then + tag_version="$latest_stable" + else + tag_version="$latest_prerelease" + fi + elif [[ -n "$latest_stable" ]]; then + tag_version="$latest_stable" + else + tag_version="$latest_prerelease" + fi +} + update_x-ui() { cd ${xui_folder%/x-ui}/ @@ -757,15 +798,9 @@ update_x-ui() { echo -e "${green}Downloading new x-ui version...${plain}" - tag_version=$(${curl_bin} -Ls "https://api.github.com/repos/Sora39831/3x-ui/releases/latest" 2>/dev/null | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') - if [[ ! -n "$tag_version" ]]; then - echo -e "${yellow}Trying to fetch version with IPv4...${plain}" - tag_version=$(${curl_bin} -4 -Ls "https://api.github.com/repos/Sora39831/3x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') - if [[ ! -n "$tag_version" ]]; then - _fail "ERROR: Failed to fetch x-ui version, it may be due to GitHub API restrictions, please try it later" - fi - fi - echo -e "Got x-ui latest version: ${tag_version}, beginning the installation..." + get_releases + select_version + echo -e "Got x-ui version: ${tag_version}, beginning the installation..." ${curl_bin} -fLRo ${xui_folder}-linux-$(arch).tar.gz https://github.com/Sora39831/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz 2>/dev/null if [[ $? -ne 0 ]]; then echo -e "${yellow}Trying to fetch version with IPv4...${plain}" diff --git a/web/controller/index.go b/web/controller/index.go index dd58e5e5..be289a68 100644 --- a/web/controller/index.go +++ b/web/controller/index.go @@ -44,6 +44,7 @@ func (a *IndexController) initRouter(g *gin.RouterGroup) { g.POST("/login", a.login) g.POST("/getTwoFactorEnable", a.getTwoFactorEnable) + g.POST("/getTurnstileSiteKey", a.getTurnstileSiteKey) } // index handles the root route, redirecting logged-in users to the panel or showing the login page. @@ -131,3 +132,11 @@ func (a *IndexController) getTwoFactorEnable(c *gin.Context) { jsonObj(c, status, nil) } } + +// getTurnstileSiteKey returns the Cloudflare Turnstile site key for the registration form. +func (a *IndexController) getTurnstileSiteKey(c *gin.Context) { + siteKey, err := a.settingService.GetTurnstileSiteKey() + if err == nil { + jsonObj(c, siteKey, nil) + } +} diff --git a/web/entity/entity.go b/web/entity/entity.go index 40294925..90710f88 100644 --- a/web/entity/entity.go +++ b/web/entity/entity.go @@ -103,7 +103,9 @@ type AllSetting struct { LdapDefaultTotalGB int `json:"ldapDefaultTotalGB" form:"ldapDefaultTotalGB"` LdapDefaultExpiryDays int `json:"ldapDefaultExpiryDays" form:"ldapDefaultExpiryDays"` LdapDefaultLimitIP int `json:"ldapDefaultLimitIP" form:"ldapDefaultLimitIP"` - // JSON subscription routing rules + + // Registration settings + TurnstileSiteKey string `json:"turnstileSiteKey" form:"turnstileSiteKey"` } // CheckValid validates all settings in the AllSetting struct, checking IP addresses, ports, SSL certificates, and other configuration values. diff --git a/web/html/login.html b/web/html/login.html index 6d98e6b1..69bc2142 100644 --- a/web/html/login.html +++ b/web/html/login.html @@ -59,39 +59,83 @@ - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + +
+
+
+
+ + +
+ +
+
+
+
+
+
+
@@ -103,23 +147,39 @@ {{template "page/body_scripts" .}} {{template "component/aThemeSwitch" .}}