From 5103d57879f9b16ad9b5418066b530b1c33e7276 Mon Sep 17 00:00:00 2001
From: Sora39831 <540587985@qq.com>
Date: Thu, 2 Apr 2026 20:18:48 +0800
Subject: [PATCH] feat: add registration tab with Cloudflare Turnstile support
Add a register tab on the login page with username, password, confirm
password fields and Cloudflare Turnstile widget. The site key is
configurable via x-ui.json and exposed through a public endpoint.
---
web/controller/index.go | 9 ++
web/entity/entity.go | 4 +-
web/html/login.html | 173 +++++++++++++++++++++------
web/service/setting.go | 7 ++
web/translation/translate.en_US.toml | 6 +
web/translation/translate.zh_CN.toml | 6 +
6 files changed, 168 insertions(+), 37 deletions(-)
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 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [[ loadingStates.spinning ? '' : '{{ i18n "login" }}' ]]
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [[ loadingStates.spinning ? '' : '{{ i18n "login" }}' ]]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [[ loadingStates.registerSpinning ? '' : '{{ i18n "pages.login.registerTab" }}' ]]
+
+
+
+
+
+
+
+
@@ -103,23 +147,39 @@
{{template "page/body_scripts" .}}
{{template "component/aThemeSwitch" .}}