Browse Source

Merge pull request #644 from 0xJacky/refactor/migrate-cosy

Refactor/migrate-cosy
Jacky 8 months ago
parent
commit
4747c6916e
100 changed files with 3458 additions and 1774 deletions
  1. 1 1
      .github/workflows/documents.yml
  2. 3 0
      .gitignore
  3. 1 1
      api/analytic/analytic.go
  4. 1 1
      api/analytic/nodes.go
  5. 1 1
      api/api.go
  6. 3 3
      api/certificate/acme_user.go
  7. 1 1
      api/certificate/certificate.go
  8. 1 1
      api/certificate/dns_credential.go
  9. 1 1
      api/certificate/issue.go
  10. 1 1
      api/cluster/environment.go
  11. 1 1
      api/cluster/node.go
  12. 1 1
      api/config/list.go
  13. 1 1
      api/config/rename.go
  14. 1 1
      api/nginx/nginx_log.go
  15. 1 1
      api/notification/notification.go
  16. 45 12
      api/settings/settings.go
  17. 41 0
      api/sites/category.go
  18. 1 62
      api/sites/domain.go
  19. 70 0
      api/sites/list.go
  20. 9 0
      api/sites/router.go
  21. 6 5
      api/system/install.go
  22. 2 2
      api/system/upgrade.go
  23. 1 1
      api/terminal/pty.go
  24. 1 1
      api/upstream/upstream.go
  25. 1 1
      api/user/auth.go
  26. 2 2
      api/user/otp.go
  27. 8 6
      api/user/passkey.go
  28. 2 2
      api/user/user.go
  29. 3 3
      app/package.json
  30. 63 63
      app/pnpm-lock.yaml
  31. 100 2
      app/src/api/settings.ts
  32. 0 1
      app/src/components/StdDesign/types.d.ts
  33. 1 1
      app/src/components/TwoFA/Authorization.vue
  34. 2 7
      app/src/components/TwoFA/use2FAModal.ts
  35. 129 82
      app/src/language/en/app.po
  36. 141 85
      app/src/language/es/app.po
  37. 132 85
      app/src/language/fr_FR/app.po
  38. 132 85
      app/src/language/ko_KR/app.po
  39. 118 79
      app/src/language/messages.pot
  40. 141 85
      app/src/language/ru_RU/app.po
  41. 334 144
      app/src/language/tr_TR/app.po
  42. 131 85
      app/src/language/vi_VN/app.po
  43. BIN
      app/src/language/zh_CN/app.mo
  44. 130 83
      app/src/language/zh_CN/app.po
  45. 137 83
      app/src/language/zh_TW/app.po
  46. 1 3
      app/src/lib/http/index.ts
  47. 60 30
      app/src/pinia/moudule/user.ts
  48. 5 5
      app/src/views/certificate/ACMEUser.vue
  49. 4 4
      app/src/views/certificate/CertificateList/certColumns.tsx
  50. 3 3
      app/src/views/certificate/DNSCredential.vue
  51. 6 6
      app/src/views/environment/envColumns.tsx
  52. 2 2
      app/src/views/notification/notificationColumns.tsx
  53. 3 5
      app/src/views/other/Login.vue
  54. 43 9
      app/src/views/preference/AuthSettings.vue
  55. 15 90
      app/src/views/preference/BasicSettings.vue
  56. 90 0
      app/src/views/preference/CertSettings.vue
  57. 1 1
      app/src/views/preference/LogrotateSettings.vue
  58. 24 16
      app/src/views/preference/NginxSettings.vue
  59. 1 1
      app/src/views/preference/OpenAISettings.vue
  60. 57 20
      app/src/views/preference/Preference.vue
  61. 0 41
      app/src/views/preference/typedef.ts
  62. 3 3
      app/src/views/site/SiteList.vue
  63. 3 3
      app/src/views/stream/StreamList.vue
  64. 5 5
      app/src/views/user/userColumns.tsx
  65. 8 8
      cmd/generate/generate.go
  66. 21 14
      docker-compose-demo.yml
  67. 10 4
      docs/.vitepress/config/en.ts
  68. 13 7
      docs/.vitepress/config/zh_CN.ts
  69. 13 7
      docs/.vitepress/config/zh_TW.ts
  70. 20 0
      docs/guide/config-app.md
  71. 43 0
      docs/guide/config-cert.md
  72. 8 0
      docs/guide/config-database.md
  73. 18 0
      docs/guide/config-http.md
  74. 16 0
      docs/guide/config-node.md
  75. 98 11
      docs/guide/config-server.md
  76. 15 0
      docs/guide/config-terminal.md
  77. 75 44
      docs/guide/env.md
  78. 19 0
      docs/zh_CN/guide/config-app.md
  79. 2 2
      docs/zh_CN/guide/config-auth.md
  80. 37 0
      docs/zh_CN/guide/config-cert.md
  81. 1 1
      docs/zh_CN/guide/config-crypto.md
  82. 8 0
      docs/zh_CN/guide/config-database.md
  83. 15 0
      docs/zh_CN/guide/config-http.md
  84. 16 0
      docs/zh_CN/guide/config-node.md
  85. 101 17
      docs/zh_CN/guide/config-server.md
  86. 14 0
      docs/zh_CN/guide/config-terminal.md
  87. 105 61
      docs/zh_CN/guide/env.md
  88. 1 1
      docs/zh_CN/guide/nginx-ui-template.md
  89. 20 0
      docs/zh_TW/guide/config-app.md
  90. 35 0
      docs/zh_TW/guide/config-cert.md
  91. 8 0
      docs/zh_TW/guide/config-database.md
  92. 20 0
      docs/zh_TW/guide/config-http.md
  93. 16 0
      docs/zh_TW/guide/config-node.md
  94. 141 61
      docs/zh_TW/guide/config-server.md
  95. 14 0
      docs/zh_TW/guide/config-terminal.md
  96. 107 63
      docs/zh_TW/guide/env.md
  97. 25 15
      go.mod
  98. 157 127
      go.sum
  99. BIN
      img.png
  100. 10 1
      install.sh

+ 1 - 1
.github/workflows/documents.yml

@@ -58,4 +58,4 @@ jobs:
         with:
           apiToken: ${{ secrets.CF_API_TOKEN }}
           accountId: ${{ secrets.CF_ACCOUNT_ID }}
-          command: pages deploy "docs/.vitepress/dist/" --branch=main --commit-dirty=true --project-name=nginxui
+          command: pages deploy "docs/.vitepress/dist/" --commit-dirty=true --project-name=nginxui

+ 3 - 0
.gitignore

@@ -4,6 +4,7 @@ tmp
 node_modules
 .pnpm-store
 app.ini
+app.*.ini
 dist
 *.exe
 *.po~
@@ -12,3 +13,5 @@ resources/development/nginx
 app/.env
 app/.status_hash
 casdoor.pub
+.idea/deployment.xml
+.idea/webServers.xml

+ 1 - 1
api/analytic/analytic.go

@@ -4,7 +4,7 @@ import (
 	"fmt"
 	"github.com/0xJacky/Nginx-UI/internal/analytic"
 	"github.com/0xJacky/Nginx-UI/internal/helper"
-	"github.com/0xJacky/Nginx-UI/internal/logger"
+	"github.com/uozi-tech/cosy/logger"
 	"github.com/shirou/gopsutil/v3/cpu"
 	"github.com/shirou/gopsutil/v3/host"
 	"github.com/shirou/gopsutil/v3/load"

+ 1 - 1
api/analytic/nodes.go

@@ -3,7 +3,7 @@ package analytic
 import (
 	"github.com/0xJacky/Nginx-UI/internal/analytic"
 	"github.com/0xJacky/Nginx-UI/internal/helper"
-	"github.com/0xJacky/Nginx-UI/internal/logger"
+	"github.com/uozi-tech/cosy/logger"
 	"github.com/gin-gonic/gin"
 	"github.com/gorilla/websocket"
 	"net/http"

+ 1 - 1
api/api.go

@@ -2,7 +2,7 @@ package api
 
 import (
 	"errors"
-	"github.com/0xJacky/Nginx-UI/internal/logger"
+	"github.com/uozi-tech/cosy/logger"
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/gin-gonic/gin"
 	"github.com/go-playground/validator/v10"

+ 3 - 3
api/certificate/acme_user.go

@@ -2,12 +2,12 @@ package certificate
 
 import (
 	"github.com/0xJacky/Nginx-UI/api"
-	"github.com/0xJacky/Nginx-UI/internal/cosy"
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/0xJacky/Nginx-UI/query"
 	"github.com/0xJacky/Nginx-UI/settings"
 	"github.com/gin-gonic/gin"
 	"github.com/spf13/cast"
+	"github.com/uozi-tech/cosy"
 	"net/http"
 )
 
@@ -31,7 +31,7 @@ func CreateAcmeUser(c *gin.Context) {
 		"register_on_startup": "omitempty",
 	}).BeforeExecuteHook(func(ctx *cosy.Ctx[model.AcmeUser]) {
 		if ctx.Model.CADir == "" {
-			ctx.Model.CADir = settings.ServerSettings.GetCADir()
+			ctx.Model.CADir = settings.CertSettings.GetCADir()
 		}
 		err := ctx.Model.Register()
 		if err != nil {
@@ -50,7 +50,7 @@ func ModifyAcmeUser(c *gin.Context) {
 		"register_on_startup": "omitempty",
 	}).BeforeExecuteHook(func(ctx *cosy.Ctx[model.AcmeUser]) {
 		if ctx.Model.CADir == "" {
-			ctx.Model.CADir = settings.ServerSettings.GetCADir()
+			ctx.Model.CADir = settings.CertSettings.GetCADir()
 		}
 
 		if ctx.OriginModel.Email != ctx.Model.Email ||

+ 1 - 1
api/certificate/certificate.go

@@ -3,7 +3,6 @@ package certificate
 import (
 	"github.com/0xJacky/Nginx-UI/api"
 	"github.com/0xJacky/Nginx-UI/internal/cert"
-	"github.com/0xJacky/Nginx-UI/internal/cosy"
 	"github.com/0xJacky/Nginx-UI/internal/helper"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/internal/notification"
@@ -12,6 +11,7 @@ import (
 	"github.com/gin-gonic/gin"
 	"github.com/go-acme/lego/v4/certcrypto"
 	"github.com/spf13/cast"
+	"github.com/uozi-tech/cosy"
 	"net/http"
 	"os"
 )

+ 1 - 1
api/certificate/dns_credential.go

@@ -3,11 +3,11 @@ package certificate
 import (
 	"github.com/0xJacky/Nginx-UI/api"
 	"github.com/0xJacky/Nginx-UI/internal/cert/dns"
-	"github.com/0xJacky/Nginx-UI/internal/cosy"
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/0xJacky/Nginx-UI/query"
 	"github.com/gin-gonic/gin"
 	"github.com/spf13/cast"
+	"github.com/uozi-tech/cosy"
 	"net/http"
 )
 

+ 1 - 1
api/certificate/issue.go

@@ -2,7 +2,7 @@ package certificate
 
 import (
 	"github.com/0xJacky/Nginx-UI/internal/cert"
-	"github.com/0xJacky/Nginx-UI/internal/logger"
+	"github.com/uozi-tech/cosy/logger"
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/gin-gonic/gin"
 	"github.com/go-acme/lego/v4/certcrypto"

+ 1 - 1
api/cluster/environment.go

@@ -4,12 +4,12 @@ import (
 	"github.com/0xJacky/Nginx-UI/api"
 	"github.com/0xJacky/Nginx-UI/internal/analytic"
 	"github.com/0xJacky/Nginx-UI/internal/cluster"
-	"github.com/0xJacky/Nginx-UI/internal/cosy"
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/0xJacky/Nginx-UI/query"
 	"github.com/0xJacky/Nginx-UI/settings"
 	"github.com/gin-gonic/gin"
 	"github.com/spf13/cast"
+	"github.com/uozi-tech/cosy"
 	"gorm.io/gorm"
 	"net/http"
 )

+ 1 - 1
api/cluster/node.go

@@ -12,7 +12,7 @@ import (
 )
 
 func GetCurrentNode(c *gin.Context) {
-	if _, ok := c.Get("NodeSecret"); !ok {
+	if _, ok := c.Get("Secret"); !ok {
 		c.JSON(http.StatusNotAcceptable, gin.H{
 			"message": "node secret not exist",
 		})

+ 1 - 1
api/config/list.go

@@ -3,7 +3,7 @@ package config
 import (
 	"github.com/0xJacky/Nginx-UI/api"
 	"github.com/0xJacky/Nginx-UI/internal/config"
-	"github.com/0xJacky/Nginx-UI/internal/logger"
+	"github.com/uozi-tech/cosy/logger"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/gin-gonic/gin"
 	"net/http"

+ 1 - 1
api/config/rename.go

@@ -4,7 +4,7 @@ import (
 	"github.com/0xJacky/Nginx-UI/api"
 	"github.com/0xJacky/Nginx-UI/internal/config"
 	"github.com/0xJacky/Nginx-UI/internal/helper"
-	"github.com/0xJacky/Nginx-UI/internal/logger"
+	"github.com/uozi-tech/cosy/logger"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/query"
 	"github.com/gin-gonic/gin"

+ 1 - 1
api/nginx/nginx_log.go

@@ -6,7 +6,7 @@ import (
 	"github.com/0xJacky/Nginx-UI/api"
 	"github.com/0xJacky/Nginx-UI/internal/cache"
 	"github.com/0xJacky/Nginx-UI/internal/helper"
-	"github.com/0xJacky/Nginx-UI/internal/logger"
+	"github.com/uozi-tech/cosy/logger"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/settings"
 	"github.com/gin-gonic/gin"

+ 1 - 1
api/notification/notification.go

@@ -2,11 +2,11 @@ package notification
 
 import (
 	"github.com/0xJacky/Nginx-UI/api"
-	"github.com/0xJacky/Nginx-UI/internal/cosy"
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/0xJacky/Nginx-UI/query"
 	"github.com/gin-gonic/gin"
 	"github.com/spf13/cast"
+	"github.com/uozi-tech/cosy"
 	"net/http"
 )
 

+ 45 - 12
api/settings/settings.go

@@ -1,39 +1,71 @@
 package settings
 
 import (
+	"fmt"
 	"github.com/0xJacky/Nginx-UI/api"
 	"github.com/0xJacky/Nginx-UI/internal/cron"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/settings"
 	"github.com/gin-gonic/gin"
+	cSettings "github.com/uozi-tech/cosy/settings"
 	"net/http"
 )
 
 func GetServerName(c *gin.Context) {
 	c.JSON(http.StatusOK, gin.H{
-		"name": settings.ServerSettings.Name,
+		"name": settings.NodeSettings.Name,
 	})
 }
 
 func GetSettings(c *gin.Context) {
 	settings.NginxSettings.AccessLogPath = nginx.GetAccessLogPath()
 	settings.NginxSettings.ErrorLogPath = nginx.GetErrorLogPath()
+	settings.NginxSettings.ConfigDir = nginx.GetConfPath()
+	settings.NginxSettings.PIDPath = nginx.GetPIDPath()
+
+	if settings.NginxSettings.ReloadCmd == "" {
+		settings.NginxSettings.ReloadCmd = "nginx -s reload"
+	}
+
+	if settings.NginxSettings.RestartCmd == "" {
+		pidPath := nginx.GetPIDPath()
+		daemon := nginx.GetSbinPath()
+		if daemon == "" {
+			settings.NginxSettings.RestartCmd =
+				fmt.Sprintf("start-stop-daemon --stop --quiet --oknodo --retry=TERM/30/KILL/5"+
+					" --pidfile %s && nginx", pidPath)
+			return
+		}
+
+		settings.NginxSettings.RestartCmd =
+			fmt.Sprintf("start-stop-daemon --start --quiet --pidfile %s --exec %s", pidPath, daemon)
+	}
+
 	c.JSON(http.StatusOK, gin.H{
-		"server":    settings.ServerSettings,
+		"app":       cSettings.AppSettings,
+		"server":    cSettings.ServerSettings,
+		"database":  settings.DatabaseSettings,
+		"auth":      settings.AuthSettings,
+		"casdoor":   settings.CasdoorSettings,
+		"cert":      settings.CertSettings,
+		"http":      settings.HTTPSettings,
+		"logrotate": settings.LogrotateSettings,
 		"nginx":     settings.NginxSettings,
+		"node":      settings.NodeSettings,
 		"openai":    settings.OpenAISettings,
-		"logrotate": settings.LogrotateSettings,
-		"auth":      settings.AuthSettings,
+		"terminal":  settings.TerminalSettings,
+		"webauthn":  settings.WebAuthnSettings,
 	})
 }
 
 func SaveSettings(c *gin.Context) {
 	var json struct {
-		Server    settings.Server    `json:"server"`
-		Nginx     settings.Nginx     `json:"nginx"`
+		Auth      settings.Auth      `json:"auth"`
+		Cert      settings.Cert      `json:"cert"`
+		Http      settings.HTTP      `json:"http"`
+		Node      settings.Node      `json:"node"`
 		Openai    settings.OpenAI    `json:"openai"`
 		Logrotate settings.Logrotate `json:"logrotate"`
-		Auth      settings.Auth      `json:"auth"`
 	}
 
 	if !api.BindAndValid(c, &json) {
@@ -45,11 +77,12 @@ func SaveSettings(c *gin.Context) {
 		go cron.RestartLogrotate()
 	}
 
-	settings.ProtectedFill(&settings.ServerSettings, &json.Server)
-	settings.ProtectedFill(&settings.NginxSettings, &json.Nginx)
-	settings.ProtectedFill(&settings.OpenAISettings, &json.Openai)
-	settings.ProtectedFill(&settings.LogrotateSettings, &json.Logrotate)
-	settings.ProtectedFill(&settings.AuthSettings, &json.Auth)
+	cSettings.ProtectedFill(settings.AuthSettings, &json.Auth)
+	cSettings.ProtectedFill(settings.CertSettings, &json.Cert)
+	cSettings.ProtectedFill(settings.HTTPSettings, &json.Http)
+	cSettings.ProtectedFill(settings.NodeSettings, &json.Node)
+	cSettings.ProtectedFill(settings.OpenAISettings, &json.Openai)
+	cSettings.ProtectedFill(settings.LogrotateSettings, &json.Logrotate)
 
 	err := settings.Save()
 	if err != nil {

+ 41 - 0
api/sites/category.go

@@ -0,0 +1,41 @@
+package sites
+
+import (
+	"github.com/0xJacky/Nginx-UI/model"
+	"github.com/gin-gonic/gin"
+	"github.com/uozi-tech/cosy"
+)
+
+func GetCategory(c *gin.Context) {
+
+}
+
+func GetCategoryList(c *gin.Context) {
+	cosy.Core[model.SiteCategory](c).PagingList()
+}
+
+func AddCategory(c *gin.Context) {
+	cosy.Core[model.SiteCategory](c).
+		SetValidRules(gin.H{
+			"name":          "required",
+			"sync_node_ids": "omitempty",
+		}).
+		Create()
+}
+
+func ModifyCategory(c *gin.Context) {
+	cosy.Core[model.SiteCategory](c).
+		SetValidRules(gin.H{
+			"name":          "required",
+			"sync_node_ids": "omitempty",
+		}).
+		Modify()
+}
+
+func DeleteCategory(c *gin.Context) {
+	cosy.Core[model.SiteCategory](c).Destroy()
+}
+
+func RecoverCategory(c *gin.Context) {
+	cosy.Core[model.SiteCategory](c).Recover()
+}

+ 1 - 62
api/sites/domain.go

@@ -3,9 +3,8 @@ package sites
 import (
 	"github.com/0xJacky/Nginx-UI/api"
 	"github.com/0xJacky/Nginx-UI/internal/cert"
-	"github.com/0xJacky/Nginx-UI/internal/config"
 	"github.com/0xJacky/Nginx-UI/internal/helper"
-	"github.com/0xJacky/Nginx-UI/internal/logger"
+	"github.com/uozi-tech/cosy/logger"
 	"github.com/0xJacky/Nginx-UI/internal/nginx"
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/0xJacky/Nginx-UI/query"
@@ -13,68 +12,8 @@ import (
 	"github.com/sashabaranov/go-openai"
 	"net/http"
 	"os"
-	"strings"
 )
 
-func GetSiteList(c *gin.Context) {
-	name := c.Query("name")
-	enabled := c.Query("enabled")
-	orderBy := c.Query("order_by")
-	sort := c.DefaultQuery("sort", "desc")
-
-	configFiles, err := os.ReadDir(nginx.GetConfPath("sites-available"))
-	if err != nil {
-		api.ErrHandler(c, err)
-		return
-	}
-
-	enabledConfig, err := os.ReadDir(nginx.GetConfPath("sites-enabled"))
-	if err != nil {
-		api.ErrHandler(c, err)
-		return
-	}
-
-	enabledConfigMap := make(map[string]bool)
-	for i := range enabledConfig {
-		enabledConfigMap[enabledConfig[i].Name()] = true
-	}
-
-	var configs []config.Config
-
-	for i := range configFiles {
-		file := configFiles[i]
-		fileInfo, _ := file.Info()
-		if !file.IsDir() {
-			// name filter
-			if name != "" && !strings.Contains(file.Name(), name) {
-				continue
-			}
-			// status filter
-			if enabled != "" {
-				if enabled == "true" && !enabledConfigMap[file.Name()] {
-					continue
-				}
-				if enabled == "false" && enabledConfigMap[file.Name()] {
-					continue
-				}
-			}
-			configs = append(configs, config.Config{
-				Name:       file.Name(),
-				ModifiedAt: fileInfo.ModTime(),
-				Size:       fileInfo.Size(),
-				IsDir:      fileInfo.IsDir(),
-				Enabled:    enabledConfigMap[file.Name()],
-			})
-		}
-	}
-
-	configs = config.Sort(orderBy, sort, configs)
-
-	c.JSON(http.StatusOK, gin.H{
-		"data": configs,
-	})
-}
-
 func GetSite(c *gin.Context) {
 	rewriteName, ok := c.Get("rewriteConfigFileName")
 	name := c.Param("name")

+ 70 - 0
api/sites/list.go

@@ -0,0 +1,70 @@
+package sites
+
+import (
+	"github.com/0xJacky/Nginx-UI/api"
+	"github.com/0xJacky/Nginx-UI/internal/config"
+	"github.com/0xJacky/Nginx-UI/internal/nginx"
+	"github.com/gin-gonic/gin"
+	"net/http"
+	"os"
+	"strings"
+)
+
+func GetSiteList(c *gin.Context) {
+	name := c.Query("name")
+	enabled := c.Query("enabled")
+	orderBy := c.Query("order_by")
+	sort := c.DefaultQuery("sort", "desc")
+
+	configFiles, err := os.ReadDir(nginx.GetConfPath("sites-available"))
+	if err != nil {
+		api.ErrHandler(c, err)
+		return
+	}
+
+	enabledConfig, err := os.ReadDir(nginx.GetConfPath("sites-enabled"))
+	if err != nil {
+		api.ErrHandler(c, err)
+		return
+	}
+
+	enabledConfigMap := make(map[string]bool)
+	for i := range enabledConfig {
+		enabledConfigMap[enabledConfig[i].Name()] = true
+	}
+
+	var configs []config.Config
+
+	for i := range configFiles {
+		file := configFiles[i]
+		fileInfo, _ := file.Info()
+		if !file.IsDir() {
+			// name filter
+			if name != "" && !strings.Contains(file.Name(), name) {
+				continue
+			}
+			// status filter
+			if enabled != "" {
+				if enabled == "true" && !enabledConfigMap[file.Name()] {
+					continue
+				}
+				if enabled == "false" && enabledConfigMap[file.Name()] {
+					continue
+				}
+			}
+			configs = append(configs, config.Config{
+				Name:       file.Name(),
+				ModifiedAt: fileInfo.ModTime(),
+				Size:       fileInfo.Size(),
+				IsDir:      fileInfo.IsDir(),
+				Enabled:    enabledConfigMap[file.Name()],
+			})
+		}
+	}
+
+	configs = config.Sort(orderBy, sort, configs)
+
+	c.JSON(http.StatusOK, gin.H{
+		"data": configs,
+	})
+}

+ 9 - 0
api/sites/router.go

@@ -14,3 +14,12 @@ func InitRouter(r *gin.RouterGroup) {
 	r.POST("auto_cert/:name", AddDomainToAutoCert)
 	r.DELETE("auto_cert/:name", RemoveDomainFromAutoCert)
 }
+
+func InitCategoryRouter(r *gin.RouterGroup) {
+	r.GET("site_categories", GetCategoryList)
+	r.GET("site_category/:id", GetCategory)
+	r.POST("site_category", AddCategory)
+	r.PUT("site_category/:id", ModifyCategory)
+	r.DELETE("site_category/:id", DeleteCategory)
+	r.POST("site_category/:id/recover", RecoverCategory)
+}

+ 6 - 5
api/system/install.go

@@ -8,12 +8,13 @@ import (
 	"github.com/0xJacky/Nginx-UI/settings"
 	"github.com/gin-gonic/gin"
 	"github.com/google/uuid"
+	cSettings "github.com/uozi-tech/cosy/settings"
 	"golang.org/x/crypto/bcrypt"
 	"net/http"
 )
 
 func installLockStatus() bool {
-	return settings.ServerSettings.SkipInstallation || "" != settings.ServerSettings.JwtSecret
+	return settings.NodeSettings.SkipInstallation || "" != cSettings.AppSettings.JwtSecret
 }
 
 func InstallLockCheck(c *gin.Context) {
@@ -43,11 +44,11 @@ func InstallNginxUI(c *gin.Context) {
 		return
 	}
 
-	settings.ServerSettings.JwtSecret = uuid.New().String()
-	settings.ServerSettings.NodeSecret = uuid.New().String()
-	settings.ServerSettings.Email = json.Email
+	cSettings.AppSettings.JwtSecret = uuid.New().String()
+	settings.NodeSettings.Secret = uuid.New().String()
+	settings.CertSettings.Email = json.Email
 	if "" != json.Database {
-		settings.ServerSettings.Database = json.Database
+		settings.DatabaseSettings.Name = json.Database
 	}
 
 	err := settings.Save()

+ 2 - 2
api/system/upgrade.go

@@ -2,11 +2,11 @@ package system
 
 import (
 	"github.com/0xJacky/Nginx-UI/api"
-	"github.com/0xJacky/Nginx-UI/internal/logger"
 	"github.com/0xJacky/Nginx-UI/internal/upgrader"
 	"github.com/0xJacky/Nginx-UI/settings"
 	"github.com/gin-gonic/gin"
 	"github.com/gorilla/websocket"
+	"github.com/uozi-tech/cosy/logger"
 	"net/http"
 	"os"
 )
@@ -135,7 +135,7 @@ func PerformCoreUpgrade(c *gin.Context) {
 		Message: "Performing core upgrade",
 	})
 	// dry run
-	if control.DryRun || settings.ServerSettings.Demo {
+	if control.DryRun || settings.NodeSettings.Demo {
 		return
 	}
 

+ 1 - 1
api/terminal/pty.go

@@ -1,7 +1,7 @@
 package terminal
 
 import (
-	"github.com/0xJacky/Nginx-UI/internal/logger"
+	"github.com/uozi-tech/cosy/logger"
 	"github.com/0xJacky/Nginx-UI/internal/pty"
 	"github.com/gin-gonic/gin"
 	"github.com/gorilla/websocket"

+ 1 - 1
api/upstream/upstream.go

@@ -2,7 +2,7 @@ package upstream
 
 import (
 	"github.com/0xJacky/Nginx-UI/internal/helper"
-	"github.com/0xJacky/Nginx-UI/internal/logger"
+	"github.com/uozi-tech/cosy/logger"
 	"github.com/0xJacky/Nginx-UI/internal/upstream"
 	"github.com/gin-gonic/gin"
 	"github.com/gorilla/websocket"

+ 1 - 1
api/user/auth.go

@@ -2,7 +2,7 @@ package user
 
 import (
 	"github.com/0xJacky/Nginx-UI/api"
-	"github.com/0xJacky/Nginx-UI/internal/logger"
+	"github.com/uozi-tech/cosy/logger"
 	"github.com/0xJacky/Nginx-UI/internal/user"
 	"github.com/0xJacky/Nginx-UI/query"
 	"github.com/0xJacky/Nginx-UI/settings"

+ 2 - 2
api/user/otp.go

@@ -21,7 +21,7 @@ import (
 func GenerateTOTP(c *gin.Context) {
 	u := api.CurrentUser(c)
 
-	issuer := fmt.Sprintf("Nginx UI %s", settings.ServerSettings.Name)
+	issuer := fmt.Sprintf("Nginx UI %s", settings.NodeSettings.Name)
 	issuer = strings.TrimSpace(issuer)
 
 	otpOpts := totp.GenerateOpts{
@@ -70,7 +70,7 @@ func EnrollTOTP(c *gin.Context) {
 		return
 	}
 
-	if settings.ServerSettings.Demo {
+	if settings.NodeSettings.Demo {
 		c.JSON(http.StatusBadRequest, gin.H{
 			"message": "This feature is disabled in demo mode",
 		})

+ 8 - 6
api/user/passkey.go

@@ -5,8 +5,6 @@ import (
 	"fmt"
 	"github.com/0xJacky/Nginx-UI/api"
 	"github.com/0xJacky/Nginx-UI/internal/cache"
-	"github.com/0xJacky/Nginx-UI/internal/cosy"
-	"github.com/0xJacky/Nginx-UI/internal/logger"
 	"github.com/0xJacky/Nginx-UI/internal/passkey"
 	"github.com/0xJacky/Nginx-UI/internal/user"
 	"github.com/0xJacky/Nginx-UI/model"
@@ -15,6 +13,8 @@ import (
 	"github.com/go-webauthn/webauthn/webauthn"
 	"github.com/google/uuid"
 	"github.com/spf13/cast"
+	"github.com/uozi-tech/cosy"
+	"github.com/uozi-tech/cosy/logger"
 	"gorm.io/gorm"
 	"net/http"
 	"strings"
@@ -152,11 +152,13 @@ func FinishPasskeyLogin(c *gin.Context) {
 		return
 	}
 
+	secureSessionID := user.SetSecureSessionID(outUser.ID)
+
 	c.JSON(http.StatusOK, LoginResponse{
-		Code:    LoginSuccess,
-		Message: "ok",
-		Token:   token,
-		// SecureSessionID: secureSessionID,
+		Code:            LoginSuccess,
+		Message:         "ok",
+		Token:           token,
+		SecureSessionID: secureSessionID,
 	})
 }
 

+ 2 - 2
api/user/user.go

@@ -2,12 +2,12 @@ package user
 
 import (
 	"github.com/0xJacky/Nginx-UI/api"
-	"github.com/0xJacky/Nginx-UI/internal/cosy"
 	"github.com/0xJacky/Nginx-UI/model"
 	"github.com/0xJacky/Nginx-UI/query"
 	"github.com/0xJacky/Nginx-UI/settings"
 	"github.com/gin-gonic/gin"
 	"github.com/spf13/cast"
+	"github.com/uozi-tech/cosy"
 	"golang.org/x/crypto/bcrypt"
 	"net/http"
 )
@@ -71,7 +71,7 @@ func AddUser(c *gin.Context) {
 func EditUser(c *gin.Context) {
 	userId := cast.ToInt(c.Param("id"))
 
-	if settings.ServerSettings.Demo && userId == 1 {
+	if settings.NodeSettings.Demo && userId == 1 {
 		c.JSON(http.StatusNotAcceptable, gin.H{
 			"message": "Changing user password is forbidden in demo mode",
 		})

+ 3 - 3
app/package.json

@@ -49,7 +49,7 @@
   "devDependencies": {
     "@antfu/eslint-config-vue": "^0.43.1",
     "@simplewebauthn/types": "^10.0.0",
-    "@types/lodash": "^4.17.11",
+    "@types/lodash": "^4.17.12",
     "@types/nprogress": "^0.2.3",
     "@types/sortablejs": "^1.15.8",
     "@typescript-eslint/eslint-plugin": "^6.21.0",
@@ -58,7 +58,7 @@
     "@vitejs/plugin-vue-jsx": "^4.0.1",
     "@vue/compiler-sfc": "^3.5.12",
     "@vue/tsconfig": "^0.5.1",
-    "ace-builds": "^1.36.2",
+    "ace-builds": "^1.36.3",
     "autoprefixer": "^10.4.20",
     "eslint": "^8.57.1",
     "eslint-import-resolver-alias": "^1.1.2",
@@ -66,7 +66,7 @@
     "eslint-plugin-import": "^2.31.0",
     "eslint-plugin-regex": "^1.10.0",
     "eslint-plugin-sonarjs": "^0.23.0",
-    "eslint-plugin-vue": "^9.29.0",
+    "eslint-plugin-vue": "^9.29.1",
     "less": "^4.2.0",
     "postcss": "^8.4.47",
     "tailwindcss": "^3.4.14",

+ 63 - 63
app/pnpm-lock.yaml

@@ -97,7 +97,7 @@ importers:
         version: 4.4.5(vue@3.5.12(typescript@5.3.3))
       vue3-ace-editor:
         specifier: 2.2.4
-        version: 2.2.4(ace-builds@1.36.2)(vue@3.5.12(typescript@5.3.3))
+        version: 2.2.4(ace-builds@1.36.3)(vue@3.5.12(typescript@5.3.3))
       vue3-apexcharts:
         specifier: 1.5.3
         version: 1.5.3(apexcharts@3.54.1)(vue@3.5.12(typescript@5.3.3))
@@ -113,13 +113,13 @@ importers:
     devDependencies:
       '@antfu/eslint-config-vue':
         specifier: ^0.43.1
-        version: 0.43.1(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3))(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)(typescript@5.3.3)
+        version: 0.43.1(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3))(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)(typescript@5.3.3)
       '@simplewebauthn/types':
         specifier: ^10.0.0
         version: 10.0.0
       '@types/lodash':
-        specifier: ^4.17.11
-        version: 4.17.11
+        specifier: ^4.17.12
+        version: 4.17.12
       '@types/nprogress':
         specifier: ^0.2.3
         version: 0.2.3
@@ -134,10 +134,10 @@ importers:
         version: 6.21.0(eslint@8.57.1)(typescript@5.3.3)
       '@vitejs/plugin-vue':
         specifier: ^5.1.4
-        version: 5.1.4(vite@5.4.9(@types/node@22.7.6)(less@4.2.0))(vue@3.5.12(typescript@5.3.3))
+        version: 5.1.4(vite@5.4.9(@types/node@22.7.8)(less@4.2.0))(vue@3.5.12(typescript@5.3.3))
       '@vitejs/plugin-vue-jsx':
         specifier: ^4.0.1
-        version: 4.0.1(vite@5.4.9(@types/node@22.7.6)(less@4.2.0))(vue@3.5.12(typescript@5.3.3))
+        version: 4.0.1(vite@5.4.9(@types/node@22.7.8)(less@4.2.0))(vue@3.5.12(typescript@5.3.3))
       '@vue/compiler-sfc':
         specifier: ^3.5.12
         version: 3.5.12
@@ -145,8 +145,8 @@ importers:
         specifier: ^0.5.1
         version: 0.5.1
       ace-builds:
-        specifier: ^1.36.2
-        version: 1.36.2
+        specifier: ^1.36.3
+        version: 1.36.3
       autoprefixer:
         specifier: ^10.4.20
         version: 10.4.20(postcss@8.4.47)
@@ -155,7 +155,7 @@ importers:
         version: 8.57.1
       eslint-import-resolver-alias:
         specifier: ^1.1.2
-        version: 1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1))
+        version: 1.1.2(eslint-plugin-import@2.31.0)
       eslint-import-resolver-typescript:
         specifier: ^3.6.3
         version: 3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1)
@@ -169,8 +169,8 @@ importers:
         specifier: ^0.23.0
         version: 0.23.0(eslint@8.57.1)
       eslint-plugin-vue:
-        specifier: ^9.29.0
-        version: 9.29.0(eslint@8.57.1)
+        specifier: ^9.29.1
+        version: 9.29.1(eslint@8.57.1)
       less:
         specifier: ^4.2.0
         version: 4.2.0
@@ -194,7 +194,7 @@ importers:
         version: 1.5.2(rollup@4.24.0)(vue@3.5.12(typescript@5.3.3))(webpack-sources@3.2.3)
       vite:
         specifier: ^5.4.9
-        version: 5.4.9(@types/node@22.7.6)(less@4.2.0)
+        version: 5.4.9(@types/node@22.7.8)(less@4.2.0)
       vite-svg-loader:
         specifier: ^5.1.0
         version: 5.1.0(vue@3.5.12(typescript@5.3.3))
@@ -746,8 +746,8 @@ packages:
   '@types/json5@0.0.29':
     resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
 
-  '@types/lodash@4.17.11':
-    resolution: {integrity: sha512-jzqWo/uQP/iqeGGTjhgFp2yaCrCYTauASQcpdzESNCkHjSprBJVcZP9KG9aQ0q+xcsXiKd/iuw/4dLjS3Odc7Q==}
+  '@types/lodash@4.17.12':
+    resolution: {integrity: sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==}
 
   '@types/mdast@3.0.15':
     resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==}
@@ -755,11 +755,11 @@ packages:
   '@types/minimatch@5.1.2':
     resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==}
 
-  '@types/node@20.16.12':
-    resolution: {integrity: sha512-LfPFB0zOeCeCNQV3i+67rcoVvoN5n0NVuR2vLG0O5ySQMgchuZlC4lgz546ZOJyDtj5KIgOxy+lacOimfqZAIA==}
+  '@types/node@20.16.14':
+    resolution: {integrity: sha512-vtgGzjxLF7QT88qRHtXMzCWpAAmwonE7fwgVjFtXosUva2oSpnIEc3gNO9P7uIfOxKnii2f79/xtOnfreYtDaA==}
 
-  '@types/node@22.7.6':
-    resolution: {integrity: sha512-/d7Rnj0/ExXDMcioS78/kf1lMzYk4BZV8MZGTBKzTGZ6/406ukkbYlIsZmMPhcR5KlkunDHQLrtAVmSq7r+mSw==}
+  '@types/node@22.7.8':
+    resolution: {integrity: sha512-a922jJy31vqR5sk+kAdIENJjHblqcZ4RmERviFsER4WJcEONqxKcjNOlk0q7OUfrF5sddT+vng070cdfMlrPLg==}
 
   '@types/normalize-package-data@2.4.4':
     resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
@@ -1033,8 +1033,8 @@ packages:
   '@yr/monotone-cubic-spline@1.0.3':
     resolution: {integrity: sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==}
 
-  ace-builds@1.36.2:
-    resolution: {integrity: sha512-eqqfbGwx/GKjM/EnFu4QtQ+d2NNBu84MGgxoG8R5iyFpcVeQ4p9YlTL+ZzdEJqhdkASqoqOxCSNNGyB6lvMm+A==}
+  ace-builds@1.36.3:
+    resolution: {integrity: sha512-YcdwV2IIaJSfjkWAR1NEYN5IxBiXefTgwXsJ//UlaFrjXDX5hQpvPFvEePHz2ZBUfvO54RjHeRUQGX8MS5HaMQ==}
 
   acorn-jsx@5.3.2:
     resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
@@ -1181,8 +1181,8 @@ packages:
     resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
     engines: {node: '>=8'}
 
-  browserslist@4.24.0:
-    resolution: {integrity: sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==}
+  browserslist@4.24.2:
+    resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==}
     engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
     hasBin: true
 
@@ -1478,8 +1478,8 @@ packages:
   eastasianwidth@0.2.0:
     resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
 
-  electron-to-chromium@1.5.41:
-    resolution: {integrity: sha512-dfdv/2xNjX0P8Vzme4cfzHqnPm5xsZXwsolTYr0eyW18IUmNyG08vL+fttvinTfhKfIKdRoqkDIC9e9iWQCNYQ==}
+  electron-to-chromium@1.5.42:
+    resolution: {integrity: sha512-gIfKavKDw1mhvic9nbzA5lZw8QSHpdMwLwXc0cWidQz9B15pDoDdDH4boIatuFfeoCatb3a/NGL6CYRVFxGZ9g==}
 
   emoji-regex@8.0.0:
     resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@@ -1712,8 +1712,8 @@ packages:
       '@typescript-eslint/eslint-plugin':
         optional: true
 
-  eslint-plugin-vue@9.29.0:
-    resolution: {integrity: sha512-hamyjrBhNH6Li6R1h1VF9KHfshJlKgKEg3ARbGTn72CMNDSMhWbgC7NdkRDEh25AFW+4SDATzyNM+3gWuZii8g==}
+  eslint-plugin-vue@9.29.1:
+    resolution: {integrity: sha512-MH/MbVae4HV/tM8gKAVWMPJbYgW04CK7SuzYRrlNERpxbO0P3+Zdsa2oAcFBW6xNu7W6lIkGOsFAMCRTYmrlWQ==}
     engines: {node: ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0
@@ -3403,14 +3403,14 @@ snapshots:
       '@ant-design/icons-svg': 4.4.2
       vue: 3.5.12(typescript@5.3.3)
 
-  '@antfu/eslint-config-basic@0.43.1(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3))(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)(typescript@5.3.3)':
+  '@antfu/eslint-config-basic@0.43.1(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3))(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)(typescript@5.3.3)':
     dependencies:
       '@stylistic/eslint-plugin-js': 0.0.4
       eslint: 8.57.1
       eslint-plugin-antfu: 0.43.1(eslint@8.57.1)(typescript@5.3.3)
       eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.1)
       eslint-plugin-html: 7.1.0
-      eslint-plugin-import: eslint-plugin-i@2.28.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
+      eslint-plugin-import: eslint-plugin-i@2.28.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
       eslint-plugin-jsdoc: 46.10.1(eslint@8.57.1)
       eslint-plugin-jsonc: 2.16.0(eslint@8.57.1)
       eslint-plugin-markdown: 3.0.1(eslint@8.57.1)
@@ -3430,9 +3430,9 @@ snapshots:
       - supports-color
       - typescript
 
-  '@antfu/eslint-config-ts@0.43.1(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)(typescript@5.3.3)':
+  '@antfu/eslint-config-ts@0.43.1(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)(typescript@5.3.3)':
     dependencies:
-      '@antfu/eslint-config-basic': 0.43.1(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3))(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)(typescript@5.3.3)
+      '@antfu/eslint-config-basic': 0.43.1(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3))(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)(typescript@5.3.3)
       '@stylistic/eslint-plugin-ts': 0.0.4(eslint@8.57.1)(typescript@5.3.3)
       '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3)
       '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.3.3)
@@ -3445,12 +3445,12 @@ snapshots:
       - jest
       - supports-color
 
-  '@antfu/eslint-config-vue@0.43.1(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3))(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)(typescript@5.3.3)':
+  '@antfu/eslint-config-vue@0.43.1(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3))(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)(typescript@5.3.3)':
     dependencies:
-      '@antfu/eslint-config-basic': 0.43.1(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3))(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)(typescript@5.3.3)
-      '@antfu/eslint-config-ts': 0.43.1(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)(typescript@5.3.3)
+      '@antfu/eslint-config-basic': 0.43.1(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3))(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)(typescript@5.3.3)
+      '@antfu/eslint-config-ts': 0.43.1(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)(typescript@5.3.3)
       eslint: 8.57.1
-      eslint-plugin-vue: 9.29.0(eslint@8.57.1)
+      eslint-plugin-vue: 9.29.1(eslint@8.57.1)
       local-pkg: 0.4.3
     transitivePeerDependencies:
       - '@typescript-eslint/eslint-plugin'
@@ -3505,7 +3505,7 @@ snapshots:
     dependencies:
       '@babel/compat-data': 7.25.8
       '@babel/helper-validator-option': 7.25.7
-      browserslist: 4.24.0
+      browserslist: 4.24.2
       lru-cache: 5.1.1
       semver: 6.3.1
 
@@ -3959,13 +3959,13 @@ snapshots:
   '@types/glob@7.2.0':
     dependencies:
       '@types/minimatch': 5.1.2
-      '@types/node': 22.7.6
+      '@types/node': 22.7.8
 
   '@types/json-schema@7.0.15': {}
 
   '@types/json5@0.0.29': {}
 
-  '@types/lodash@4.17.11': {}
+  '@types/lodash@4.17.12': {}
 
   '@types/mdast@3.0.15':
     dependencies:
@@ -3973,11 +3973,11 @@ snapshots:
 
   '@types/minimatch@5.1.2': {}
 
-  '@types/node@20.16.12':
+  '@types/node@20.16.14':
     dependencies:
       undici-types: 6.19.8
 
-  '@types/node@22.7.6':
+  '@types/node@22.7.8':
     dependencies:
       undici-types: 6.19.8
 
@@ -4124,19 +4124,19 @@ snapshots:
 
   '@ungap/structured-clone@1.2.0': {}
 
-  '@vitejs/plugin-vue-jsx@4.0.1(vite@5.4.9(@types/node@22.7.6)(less@4.2.0))(vue@3.5.12(typescript@5.3.3))':
+  '@vitejs/plugin-vue-jsx@4.0.1(vite@5.4.9(@types/node@22.7.8)(less@4.2.0))(vue@3.5.12(typescript@5.3.3))':
     dependencies:
       '@babel/core': 7.25.8
       '@babel/plugin-transform-typescript': 7.25.7(@babel/core@7.25.8)
       '@vue/babel-plugin-jsx': 1.2.5(@babel/core@7.25.8)
-      vite: 5.4.9(@types/node@22.7.6)(less@4.2.0)
+      vite: 5.4.9(@types/node@22.7.8)(less@4.2.0)
       vue: 3.5.12(typescript@5.3.3)
     transitivePeerDependencies:
       - supports-color
 
-  '@vitejs/plugin-vue@5.1.4(vite@5.4.9(@types/node@22.7.6)(less@4.2.0))(vue@3.5.12(typescript@5.3.3))':
+  '@vitejs/plugin-vue@5.1.4(vite@5.4.9(@types/node@22.7.8)(less@4.2.0))(vue@3.5.12(typescript@5.3.3))':
     dependencies:
-      vite: 5.4.9(@types/node@22.7.6)(less@4.2.0)
+      vite: 5.4.9(@types/node@22.7.8)(less@4.2.0)
       vue: 3.5.12(typescript@5.3.3)
 
   '@volar/language-core@2.4.6':
@@ -4325,7 +4325,7 @@ snapshots:
 
   '@yr/monotone-cubic-spline@1.0.3': {}
 
-  ace-builds@1.36.2: {}
+  ace-builds@1.36.3: {}
 
   acorn-jsx@5.3.2(acorn@8.13.0):
     dependencies:
@@ -4475,7 +4475,7 @@ snapshots:
 
   autoprefixer@10.4.20(postcss@8.4.47):
     dependencies:
-      browserslist: 4.24.0
+      browserslist: 4.24.2
       caniuse-lite: 1.0.30001669
       fraction.js: 4.3.7
       normalize-range: 0.1.2
@@ -4514,12 +4514,12 @@ snapshots:
     dependencies:
       fill-range: 7.1.1
 
-  browserslist@4.24.0:
+  browserslist@4.24.2:
     dependencies:
       caniuse-lite: 1.0.30001669
-      electron-to-chromium: 1.5.41
+      electron-to-chromium: 1.5.42
       node-releases: 2.0.18
-      update-browserslist-db: 1.1.1(browserslist@4.24.0)
+      update-browserslist-db: 1.1.1(browserslist@4.24.2)
 
   builtin-modules@3.3.0: {}
 
@@ -4797,7 +4797,7 @@ snapshots:
 
   eastasianwidth@0.2.0: {}
 
-  electron-to-chromium@1.5.41: {}
+  electron-to-chromium@1.5.42: {}
 
   emoji-regex@8.0.0: {}
 
@@ -4935,7 +4935,7 @@ snapshots:
       eslint: 8.57.1
       semver: 7.6.3
 
-  eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)):
+  eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.31.0):
     dependencies:
       eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
 
@@ -4953,7 +4953,7 @@ snapshots:
       debug: 4.3.7
       enhanced-resolve: 5.17.1
       eslint: 8.57.1
-      eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
+      eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
       fast-glob: 3.3.2
       get-tsconfig: 4.8.1
       is-bun-module: 1.2.1
@@ -4966,7 +4966,7 @@ snapshots:
       - eslint-import-resolver-webpack
       - supports-color
 
-  eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1):
+  eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
     dependencies:
       debug: 3.2.7
     optionalDependencies:
@@ -5002,13 +5002,13 @@ snapshots:
     dependencies:
       htmlparser2: 8.0.2
 
-  eslint-plugin-i@2.28.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1):
+  eslint-plugin-i@2.28.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
     dependencies:
       debug: 3.2.7
       doctrine: 2.1.0
       eslint: 8.57.1
       eslint-import-resolver-node: 0.3.9
-      eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
+      eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
       get-tsconfig: 4.8.1
       is-glob: 4.0.3
       minimatch: 3.1.2
@@ -5031,7 +5031,7 @@ snapshots:
       doctrine: 2.1.0
       eslint: 8.57.1
       eslint-import-resolver-node: 0.3.9
-      eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
+      eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
       hasown: 2.0.2
       is-core-module: 2.15.1
       is-glob: 4.0.3
@@ -5147,7 +5147,7 @@ snapshots:
     optionalDependencies:
       '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.3.3))(eslint@8.57.1)(typescript@5.3.3)
 
-  eslint-plugin-vue@9.29.0(eslint@8.57.1):
+  eslint-plugin-vue@9.29.1(eslint@8.57.1):
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1)
       eslint: 8.57.1
@@ -6734,9 +6734,9 @@ snapshots:
     transitivePeerDependencies:
       - supports-color
 
-  update-browserslist-db@1.1.1(browserslist@4.24.0):
+  update-browserslist-db@1.1.1(browserslist@4.24.2):
     dependencies:
-      browserslist: 4.24.0
+      browserslist: 4.24.2
       escalade: 3.2.0
       picocolors: 1.1.1
 
@@ -6753,7 +6753,7 @@ snapshots:
 
   vite-plugin-build-id@0.4.2:
     dependencies:
-      '@types/node': 20.16.12
+      '@types/node': 20.16.14
       isomorphic-git: 1.27.1
       node-object-hash: 3.0.0
       typescript: 5.6.3
@@ -6763,13 +6763,13 @@ snapshots:
       svgo: 3.3.2
       vue: 3.5.12(typescript@5.3.3)
 
-  vite@5.4.9(@types/node@22.7.6)(less@4.2.0):
+  vite@5.4.9(@types/node@22.7.8)(less@4.2.0):
     dependencies:
       esbuild: 0.21.5
       postcss: 8.4.47
       rollup: 4.24.0
     optionalDependencies:
-      '@types/node': 22.7.6
+      '@types/node': 22.7.8
       fsevents: 2.3.3
       less: 4.2.0
 
@@ -6809,9 +6809,9 @@ snapshots:
       is-plain-object: 3.0.1
       vue: 3.5.12(typescript@5.3.3)
 
-  vue3-ace-editor@2.2.4(ace-builds@1.36.2)(vue@3.5.12(typescript@5.3.3)):
+  vue3-ace-editor@2.2.4(ace-builds@1.36.3)(vue@3.5.12(typescript@5.3.3)):
     dependencies:
-      ace-builds: 1.36.2
+      ace-builds: 1.36.3
       resize-observer-polyfill: 1.5.1
       vue: 3.5.12(typescript@5.3.3)
 

+ 100 - 2
app/src/api/settings.ts

@@ -1,16 +1,114 @@
 import http from '@/lib/http'
 
+export interface AppSettings {
+  page_size: number
+  jwt_secret: string
+}
+
+export interface ServerSettings {
+  host: string
+  port: number
+  run_mode: 'debug' | 'release'
+}
+
+export interface DatabaseSettings {
+  name: string
+}
+
+export interface AuthSettings {
+  ip_white_list: string[]
+  ban_threshold_minutes: number
+  max_attempts: number
+}
+
+export interface CasdoorSettings {
+  endpoint: string
+  client_id: string
+  client_secret: string
+  certificate_path: string
+  organization: string
+  application: string
+  redirect_uri: string
+}
+
+export interface CertSettings {
+  email: string
+  ca_dir: string
+  renewal_interval: number
+  recursive_nameservers: string[]
+  http_challenge_port: string
+}
+
+export interface HTTPSettings {
+  github_proxy: string
+  insecure_skip_verify: boolean
+}
+
+export interface LogrotateSettings {
+  enabled: boolean
+  cmd: string
+  interval: number
+}
+
+export interface NginxSettings {
+  access_log_path: string
+  error_log_path: string
+  config_dir: string
+  log_dir_white_list: string[]
+  pid_path: string
+  reload_cmd: string
+  restart_cmd: string
+}
+
+export interface NodeSettings {
+  name: string
+  secret: string
+}
+
+export interface OpenaiSettings {
+  model: string
+  base_url: string
+  proxy: string
+  token: string
+}
+
+export interface TerminalSettings {
+  start_cmd: string
+}
+
+export interface WebauthnSettings {
+  rp_display_name: string
+  rpid: string
+  rp_origins: string[]
+}
+
 export interface BannedIP {
   ip: string
   attempts: number
   expired_at: string
 }
 
+export interface Settings {
+  app: AppSettings
+  server: ServerSettings
+  database: DatabaseSettings
+  auth: AuthSettings
+  casdoor: CasdoorSettings
+  cert: CertSettings
+  http: HTTPSettings
+  logrotate: LogrotateSettings
+  nginx: NginxSettings
+  node: NodeSettings
+  openai: OpenaiSettings
+  terminal: TerminalSettings
+  webauthn: WebauthnSettings
+}
+
 const settings = {
-  get<T>(): Promise<T> {
+  get(): Promise<Settings> {
     return http.get('/settings')
   },
-  save<T>(data: T) {
+  save(data: Settings) {
     return http.post('/settings', data)
   },
   get_server_name(): Promise<{ name: string }> {

+ 0 - 1
app/src/components/StdDesign/types.d.ts

@@ -77,7 +77,6 @@ export interface Column extends TableColumnType {
   extra?: string | (() => string)
   pithy?: boolean
   search?: boolean | StdDesignEdit
-  sortable?: boolean
   handle?: boolean
   hiddenInTable?: boolean
   hiddenInTrash?: boolean

+ 1 - 1
app/src/components/TwoFA/Authorization.vue

@@ -46,7 +46,7 @@ async function passkeyAuthenticate() {
   passkeyLoading.value = true
   try {
     const begin = await twoFA.begin_start_secure_session_by_passkey()
-    const asseResp = await startAuthentication(begin.options.publicKey)
+    const asseResp = await startAuthentication({ optionsJSON: begin.options.publicKey })
 
     const r = await twoFA.finish_start_secure_session_by_passkey({
       session_id: begin.session_id,

+ 2 - 7
app/src/components/TwoFA/use2FAModal.ts

@@ -1,6 +1,5 @@
 import { createVNode, render } from 'vue'
 import { Modal, message } from 'ant-design-vue'
-import { useCookies } from '@vueuse/integrations/useCookies'
 import Authorization from '@/components/TwoFA/Authorization.vue'
 import twoFA from '@/api/2fa'
 import { useUserStore } from '@/pinia'
@@ -32,11 +31,8 @@ const use2FAModal = () => {
         return
       }
 
-      const cookies = useCookies(['nginx-ui-2fa'])
-      const ssid = cookies.get('secure_session_id')
-      if (ssid && secureSessionStatus) {
-        resolve(ssid)
-        secureSessionId.value = ssid
+      if (secureSessionId.value && secureSessionStatus) {
+        resolve(secureSessionId.value)
 
         return
       }
@@ -51,7 +47,6 @@ const use2FAModal = () => {
       }
 
       const setSessionId = (sessionId: string) => {
-        cookies.set('secure_session_id', sessionId, { maxAge: 60 * 3 })
         close()
         secureSessionId.value = sessionId
         resolve(sessionId)

+ 129 - 82
app/src/language/en/app.po

@@ -13,7 +13,7 @@ msgstr ""
 msgid "2FA"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:58
+#: src/views/preference/AuthSettings.vue:57
 msgid "2FA Settings"
 msgstr ""
 
@@ -37,14 +37,14 @@ msgstr "Username"
 #: src/views/config/configColumns.ts:38
 #: src/views/environment/envColumns.tsx:131
 #: src/views/notification/notificationColumns.tsx:54
-#: src/views/preference/AuthSettings.vue:27 src/views/site/SiteList.vue:54
+#: src/views/preference/AuthSettings.vue:26 src/views/site/SiteList.vue:54
 #: src/views/stream/StreamList.vue:47 src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Action"
 
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:183
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:204
-#: src/views/preference/BasicSettings.vue:73
+#: src/views/preference/CertSettings.vue:42
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:162
 #: src/views/site/ngx_conf/NgxUpstream.vue:152
@@ -119,7 +119,7 @@ msgstr ""
 msgid "Arch"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:102
+#: src/views/preference/AuthSettings.vue:136
 #, fuzzy
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr "Are you sure you want to remove this directive?"
@@ -164,7 +164,7 @@ msgstr "Are you sure you want to remove this directive?"
 msgid "Are you sure you want to remove this directive?"
 msgstr "Are you sure you want to remove this directive?"
 
-#: src/views/preference/BasicSettings.vue:99
+#: src/views/preference/CertSettings.vue:68
 #, fuzzy
 msgid "Are you sure you want to remove this item?"
 msgstr "Are you sure you want to remove this directive?"
@@ -182,11 +182,11 @@ msgstr ""
 msgid "Assistant"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:18
+#: src/views/preference/AuthSettings.vue:17
 msgid "Attempts"
 msgstr ""
 
-#: src/views/preference/Preference.vue:122
+#: src/views/preference/Preference.vue:153
 msgid "Auth"
 msgstr ""
 
@@ -194,7 +194,7 @@ msgstr ""
 msgid "Authenticate with a passkey"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:63
+#: src/views/preference/AuthSettings.vue:62
 msgid "Authentication Settings"
 msgstr ""
 
@@ -231,15 +231,15 @@ msgstr "Back"
 msgid "Back to list"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:76
+#: src/views/preference/AuthSettings.vue:103
 msgid "Ban Threshold Minutes"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:90
+#: src/views/preference/AuthSettings.vue:124
 msgid "Banned IPs"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:21
+#: src/views/preference/AuthSettings.vue:20
 msgid "Banned Until"
 msgstr ""
 
@@ -248,7 +248,7 @@ msgid "Base information"
 msgstr "Base information"
 
 #: src/views/config/ConfigEditor.vue:241
-#: src/views/preference/Preference.vue:116
+#: src/views/preference/Preference.vue:147
 #: src/views/site/components/RightSettings.vue:75
 #: src/views/stream/components/RightSettings.vue:74
 #, fuzzy
@@ -277,7 +277,7 @@ msgstr "Build with"
 msgid "CA Dir"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:47
+#: src/views/preference/CertSettings.vue:16
 msgid "CADir"
 msgstr ""
 
@@ -301,7 +301,11 @@ msgstr ""
 msgid "Cancel"
 msgstr "Cancel"
 
-#: src/views/preference/BasicSettings.vue:55
+#: src/views/preference/Preference.vue:159
+msgid "Cert"
+msgstr ""
+
+#: src/views/preference/CertSettings.vue:24
 #, fuzzy
 msgid "Certificate Renewal Interval"
 msgstr "Certificate is valid"
@@ -497,9 +501,9 @@ msgstr ""
 msgid "Custom"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:121
+#: src/views/preference/BasicSettings.vue:46
 msgid ""
-"Customize the name of local server to be displayed in the environment "
+"Customize the name of local node to be displayed in the environment "
 "indicator."
 msgstr ""
 
@@ -512,7 +516,7 @@ msgstr "Dashboard"
 msgid "Database (Optional, default: database)"
 msgstr "Database (Optional, default: database)"
 
-#: src/views/preference/BasicSettings.vue:60
+#: src/views/preference/CertSettings.vue:29
 msgid "Days"
 msgstr ""
 
@@ -914,12 +918,6 @@ msgstr ""
 msgid "File exists"
 msgstr ""
 
-#: src/views/preference/NginxSettings.vue:14
-#: src/views/preference/NginxSettings.vue:23
-#, fuzzy
-msgid "File not found"
-msgstr "File Not Found"
-
 #: src/views/other/Error.vue:9
 msgid "File Not Found"
 msgstr "File Not Found"
@@ -938,7 +936,7 @@ msgid ""
 "process."
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:43
+#: src/views/preference/BasicSettings.vue:38
 msgid "For Chinese user: https://mirror.ghproxy.com/"
 msgstr ""
 
@@ -978,7 +976,7 @@ msgstr "Base information"
 msgid "Getting the certificate, please wait..."
 msgstr "Getting the certificate, please wait..."
 
-#: src/views/preference/BasicSettings.vue:35
+#: src/views/preference/BasicSettings.vue:30
 msgid "Github Proxy"
 msgstr ""
 
@@ -990,15 +988,15 @@ msgstr ""
 msgid "Home"
 msgstr "Home"
 
-#: src/views/preference/BasicSettings.vue:31
+#: src/views/preference/CertSettings.vue:12
 msgid "HTTP Challenge Port"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:13
+#: src/views/preference/BasicSettings.vue:11
 msgid "HTTP Host"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:16
+#: src/views/preference/BasicSettings.vue:14
 msgid "HTTP Port"
 msgstr ""
 
@@ -1010,7 +1008,7 @@ msgstr ""
 msgid "If left blank, the default CA Dir will be used."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:119
 msgid ""
 "If the number of login failed attempts from a ip reach the max attempts in "
 "ban threshold minutes, the ip will be banned for a period of time."
@@ -1041,7 +1039,7 @@ msgstr ""
 msgid "Import Certificate"
 msgstr "Certificate Status"
 
-#: src/views/other/Login.vue:79
+#: src/views/other/Login.vue:77
 msgid "Incorrect username or password"
 msgstr ""
 
@@ -1084,7 +1082,7 @@ msgstr ""
 msgid "Invalid"
 msgstr "Invalid E-mail!"
 
-#: src/views/other/Login.vue:89
+#: src/views/other/Login.vue:87
 msgid "Invalid 2FA or recovery code"
 msgstr ""
 
@@ -1098,11 +1096,11 @@ msgstr "Invalid E-mail!"
 msgid "Invalid folder name"
 msgstr ""
 
-#: src/components/TwoFA/use2FAModal.ts:65
+#: src/components/TwoFA/use2FAModal.ts:60
 msgid "Invalid passcode or recovery code"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:15
+#: src/views/preference/AuthSettings.vue:14
 msgid "IP"
 msgstr ""
 
@@ -1125,7 +1123,7 @@ msgstr "Enabled successfully"
 msgid "Issuer: %{issuer}"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:22
+#: src/views/preference/BasicSettings.vue:20
 msgid "Jwt Secret"
 msgstr ""
 
@@ -1213,11 +1211,11 @@ msgstr "Locations"
 msgid "Log"
 msgstr "Login"
 
-#: src/routes/index.ts:305 src/views/other/Login.vue:247
+#: src/routes/index.ts:305 src/views/other/Login.vue:245
 msgid "Login"
 msgstr "Login"
 
-#: src/views/other/Login.vue:133 src/views/other/Login.vue:66
+#: src/views/other/Login.vue:131 src/views/other/Login.vue:64
 msgid "Login successful"
 msgstr "Login successful"
 
@@ -1225,7 +1223,7 @@ msgstr "Login successful"
 msgid "Logout successful"
 msgstr "Logout successful"
 
-#: src/views/preference/Preference.vue:140
+#: src/views/preference/Preference.vue:177
 msgid "Logrotate"
 msgstr ""
 
@@ -1271,7 +1269,7 @@ msgstr "Manage Users"
 msgid "Managed Certificate"
 msgstr "Certificate is valid"
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:109
 msgid "Max Attempts"
 msgstr ""
 
@@ -1372,11 +1370,11 @@ msgstr ""
 msgid "Next"
 msgstr "Next"
 
-#: src/views/preference/Preference.vue:128
+#: src/views/preference/Preference.vue:165
 msgid "Nginx"
 msgstr ""
 
-#: src/views/preference/NginxSettings.vue:11
+#: src/views/preference/NginxSettings.vue:9
 msgid "Nginx Access Log Path"
 msgstr ""
 
@@ -1385,11 +1383,16 @@ msgstr ""
 msgid "Nginx Configuration Parse Error"
 msgstr "Configuration Name"
 
+#: src/views/preference/NginxSettings.vue:15
+#, fuzzy
+msgid "Nginx Configurations Directory"
+msgstr "Configuration Name"
+
 #: src/components/NginxControl/NginxControl.vue:68
 msgid "Nginx Control"
 msgstr ""
 
-#: src/views/preference/NginxSettings.vue:20
+#: src/views/preference/NginxSettings.vue:12
 msgid "Nginx Error Log Path"
 msgstr ""
 
@@ -1401,11 +1404,27 @@ msgstr ""
 msgid "Nginx Log"
 msgstr ""
 
+#: src/views/preference/NginxSettings.vue:18
+msgid "Nginx Log Directory Whitelist"
+msgstr ""
+
+#: src/views/preference/NginxSettings.vue:27
+msgid "Nginx PID Path"
+msgstr ""
+
+#: src/views/preference/NginxSettings.vue:30
+msgid "Nginx Reload Command"
+msgstr ""
+
 #: src/components/NginxControl/NginxControl.vue:26
 #, fuzzy
 msgid "Nginx reloaded successfully"
 msgstr "Saved successfully"
 
+#: src/views/preference/NginxSettings.vue:33
+msgid "Nginx Restart Command"
+msgstr ""
+
 #: src/components/NginxControl/NginxControl.vue:42
 #, fuzzy
 msgid "Nginx restarted successfully"
@@ -1417,15 +1436,20 @@ msgstr "Saved successfully"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:561
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:575
 #: src/views/notification/Notification.vue:38
-#: src/views/preference/AuthSettings.vue:104
-#: src/views/preference/BasicSettings.vue:101
+#: src/views/preference/AuthSettings.vue:138
+#: src/views/preference/CertSettings.vue:70
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/site/ngx_conf/LocationEditor.vue:90
 #: src/views/site/SiteList.vue:151 src/views/stream/StreamList.vue:165
 msgid "No"
 msgstr "No"
 
-#: src/views/preference/BasicSettings.vue:25
+#: src/views/preference/BasicSettings.vue:42
+#, fuzzy
+msgid "Node name"
+msgstr "Username"
+
+#: src/views/preference/BasicSettings.vue:23
 msgid "Node Secret"
 msgstr ""
 
@@ -1516,11 +1540,11 @@ msgstr ""
 msgid "Online"
 msgstr ""
 
-#: src/views/preference/Preference.vue:134
+#: src/views/preference/Preference.vue:171
 msgid "OpenAI"
 msgstr ""
 
-#: src/components/TwoFA/Authorization.vue:117 src/views/other/Login.vue:256
+#: src/components/TwoFA/Authorization.vue:117 src/views/other/Login.vue:254
 msgid "Or"
 msgstr ""
 
@@ -1564,7 +1588,7 @@ msgid ""
 "password replacement or as a 2FA method."
 msgstr ""
 
-#: src/views/other/Login.vue:208 src/views/user/userColumns.tsx:18
+#: src/views/other/Login.vue:206 src/views/user/userColumns.tsx:18
 msgid "Password"
 msgstr "Password"
 
@@ -1638,11 +1662,11 @@ msgstr ""
 msgid "Please input your E-mail!"
 msgstr "Please input your E-mail!"
 
-#: src/views/other/Install.vue:44 src/views/other/Login.vue:47
+#: src/views/other/Install.vue:44 src/views/other/Login.vue:46
 msgid "Please input your password!"
 msgstr "Please input your password!"
 
-#: src/views/other/Install.vue:38 src/views/other/Login.vue:41
+#: src/views/other/Install.vue:38 src/views/other/Login.vue:40
 msgid "Please input your username!"
 msgstr "Please input your username!"
 
@@ -1666,7 +1690,7 @@ msgstr ""
 msgid "Pre-release"
 msgstr ""
 
-#: src/routes/index.ts:260 src/views/preference/Preference.vue:111
+#: src/routes/index.ts:260 src/views/preference/Preference.vue:142
 msgid "Preference"
 msgstr ""
 
@@ -1727,7 +1751,7 @@ msgstr ""
 msgid "Recovery Code:"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:68
+#: src/views/preference/CertSettings.vue:37
 msgid "Recursive Nameservers"
 msgstr ""
 
@@ -1794,11 +1818,11 @@ msgstr ""
 msgid "Reloading nginx"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:109
+#: src/views/preference/AuthSettings.vue:143
 msgid "Remove"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:48
+#: src/views/preference/AuthSettings.vue:47
 #: src/views/preference/components/Passkey.vue:50
 #, fuzzy
 msgid "Remove successfully"
@@ -1891,7 +1915,19 @@ msgstr ""
 msgid "Restarting"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:19
+#: src/views/preference/AuthSettings.vue:81
+msgid "RP Display Name"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:87
+msgid "RP Origins"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:75
+msgid "RPID"
+msgstr ""
+
+#: src/views/preference/BasicSettings.vue:17
 #, fuzzy
 msgid "Run Mode"
 msgstr "Advance Mode"
@@ -1904,7 +1940,7 @@ msgstr ""
 #: src/views/certificate/CertificateEditor.vue:256
 #: src/views/config/ConfigEditor.vue:222
 #: src/views/preference/components/Passkey.vue:136
-#: src/views/preference/Preference.vue:151
+#: src/views/preference/Preference.vue:188
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:120
 #: src/views/site/SiteEdit.vue:260 src/views/stream/StreamEdit.vue:252
 msgid "Save"
@@ -1923,7 +1959,7 @@ msgstr "Save error %{msg}"
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:122
 #: src/views/certificate/CertificateEditor.vue:46
-#: src/views/preference/Preference.vue:79
+#: src/views/preference/Preference.vue:110
 #, fuzzy
 msgid "Save successfully"
 msgstr "Saved successfully"
@@ -1968,13 +2004,13 @@ msgstr "Send"
 #: src/views/config/ConfigEditor.vue:108
 #: src/views/environment/BatchUpgrader.vue:59
 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:68
-#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/AuthSettings.vue:49
 #: src/views/preference/components/Passkey.vue:26
 #: src/views/preference/components/Passkey.vue:43
 #: src/views/preference/components/Passkey.vue:56
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:58
-#: src/views/preference/Preference.vue:83 src/views/site/SiteList.vue:88
+#: src/views/preference/Preference.vue:114 src/views/site/SiteList.vue:88
 #: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81
 #: src/views/system/Upgrade.vue:42
 msgid "Server error"
@@ -1984,11 +2020,6 @@ msgstr "Server error"
 msgid "Server Info"
 msgstr "Server Info"
 
-#: src/views/preference/BasicSettings.vue:117
-#, fuzzy
-msgid "Server Name"
-msgstr "Server Info"
-
 #: src/views/site/cert/components/ObtainCert.vue:102
 msgid "server_name not found in directives"
 msgstr "server_name not found in directives"
@@ -1997,7 +2028,7 @@ msgstr "server_name not found in directives"
 msgid "server_name parameter is required"
 msgstr "server_name parameter is required"
 
-#: src/views/preference/BasicSettings.vue:64
+#: src/views/preference/CertSettings.vue:33
 msgid ""
 "Set the recursive nameservers to override the systems nameservers for the "
 "step of DNS challenge."
@@ -2019,7 +2050,7 @@ msgstr ""
 msgid "Show"
 msgstr ""
 
-#: src/views/other/Login.vue:265
+#: src/views/other/Login.vue:263
 msgid "Sign in with a passkey"
 msgstr ""
 
@@ -2056,7 +2087,7 @@ msgstr "Certificate Status"
 msgid "SSL Certificate Path"
 msgstr "Certificate Status"
 
-#: src/views/other/Login.vue:223
+#: src/views/other/Login.vue:221
 #, fuzzy
 msgid "SSO Login"
 msgstr "Login"
@@ -2185,7 +2216,7 @@ msgstr ""
 msgid "Terminal"
 msgstr "Terminal"
 
-#: src/views/preference/BasicSettings.vue:28
+#: src/views/preference/BasicSettings.vue:26
 msgid "Terminal Start Command"
 msgstr ""
 
@@ -2218,6 +2249,12 @@ msgid ""
 "dashes, and dots."
 msgstr ""
 
+#: src/views/preference/BasicSettings.vue:45
+msgid ""
+"The node name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
+msgstr ""
+
 #: src/views/certificate/CertificateEditor.vue:173
 #, fuzzy
 msgid "The path exists, but the file is not a certificate"
@@ -2239,12 +2276,6 @@ msgid ""
 "match the local version."
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:120
-msgid ""
-"The server name should only contain letters, unicode, numbers, hyphens, "
-"dashes, and dots."
-msgstr ""
-
 #: src/views/site/cert/components/AutoCertStepOne.vue:45
 #, fuzzy
 msgid ""
@@ -2254,8 +2285,8 @@ msgstr ""
 "Note: The server_name in the current configuration must be the domain name "
 "you need to get the certificate."
 
-#: src/views/preference/BasicSettings.vue:38
-#: src/views/preference/BasicSettings.vue:50
+#: src/views/preference/BasicSettings.vue:33
+#: src/views/preference/CertSettings.vue:19
 msgid "The url is invalid"
 msgstr ""
 
@@ -2291,7 +2322,11 @@ msgid ""
 "This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:67
+#: src/views/preference/AuthSettings.vue:98
+msgid "Throttle"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:118
 #: src/views/preference/components/AddPasskey.vue:71
 #: src/views/preference/LogrotateSettings.vue:11
 msgid "Tips"
@@ -2332,7 +2367,7 @@ msgstr ""
 msgid "Token is not valid"
 msgstr ""
 
-#: src/views/other/Login.vue:82
+#: src/views/other/Login.vue:80
 msgid "Too many login failed attempts, please try again later"
 msgstr ""
 
@@ -2350,7 +2385,7 @@ msgstr ""
 msgid "Trash"
 msgstr ""
 
-#: src/components/TwoFA/use2FAModal.ts:71
+#: src/components/TwoFA/use2FAModal.ts:66
 msgid "Two-factor authentication required"
 msgstr ""
 
@@ -2425,11 +2460,11 @@ msgstr ""
 msgid "User"
 msgstr "Username"
 
-#: src/views/other/Login.vue:85
+#: src/views/other/Login.vue:83
 msgid "User is banned"
 msgstr ""
 
-#: src/views/other/Login.vue:198 src/views/user/userColumns.tsx:9
+#: src/views/other/Login.vue:196 src/views/user/userColumns.tsx:9
 msgid "Username"
 msgstr "Username"
 
@@ -2485,6 +2520,10 @@ msgid ""
 "Nginx. Are you sure you want to continue?"
 msgstr ""
 
+#: src/views/preference/AuthSettings.vue:71
+msgid "Webauthn"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:78
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "
@@ -2505,8 +2544,8 @@ msgstr ""
 msgid "Writing certificate to disk"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:103
-#: src/views/preference/BasicSettings.vue:100
+#: src/views/preference/AuthSettings.vue:137
+#: src/views/preference/CertSettings.vue:69
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/site/ngx_conf/LocationEditor.vue:89
 msgid "Yes"
@@ -2530,6 +2569,14 @@ msgstr ""
 msgid "Your passkeys"
 msgstr ""
 
+#, fuzzy
+#~ msgid "File not found"
+#~ msgstr "File Not Found"
+
+#, fuzzy
+#~ msgid "Server Name"
+#~ msgstr "Server Info"
+
 #, fuzzy
 #~ msgid "Enable 2FA"
 #~ msgstr "Enabled"

+ 141 - 85
app/src/language/es/app.po

@@ -20,7 +20,7 @@ msgstr ""
 msgid "2FA"
 msgstr "2FA"
 
-#: src/views/preference/AuthSettings.vue:58
+#: src/views/preference/AuthSettings.vue:57
 msgid "2FA Settings"
 msgstr "Configuración de 2FA"
 
@@ -43,14 +43,14 @@ msgstr "Usuario ACME"
 #: src/views/config/configColumns.ts:38
 #: src/views/environment/envColumns.tsx:131
 #: src/views/notification/notificationColumns.tsx:54
-#: src/views/preference/AuthSettings.vue:27 src/views/site/SiteList.vue:54
+#: src/views/preference/AuthSettings.vue:26 src/views/site/SiteList.vue:54
 #: src/views/stream/StreamList.vue:47 src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Acción"
 
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:183
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:204
-#: src/views/preference/BasicSettings.vue:73
+#: src/views/preference/CertSettings.vue:42
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:162
 #: src/views/site/ngx_conf/NgxUpstream.vue:152
@@ -121,7 +121,7 @@ msgstr "Token de la API"
 msgid "Arch"
 msgstr "Arquitectura"
 
-#: src/views/preference/AuthSettings.vue:102
+#: src/views/preference/AuthSettings.vue:136
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr "¿Está seguro de eliminar esta IP bloqueada inmediatamente?"
 
@@ -159,7 +159,7 @@ msgstr "¿Está seguro de que quiere recuperar este elemento?"
 msgid "Are you sure you want to remove this directive?"
 msgstr "¿Está seguro de que quiere borrar esta directiva?"
 
-#: src/views/preference/BasicSettings.vue:99
+#: src/views/preference/CertSettings.vue:68
 msgid "Are you sure you want to remove this item?"
 msgstr "¿Está seguro de que desea eliminar este elemento?"
 
@@ -175,11 +175,11 @@ msgstr "Preguntar por ayuda a ChatGPT"
 msgid "Assistant"
 msgstr "Asistente"
 
-#: src/views/preference/AuthSettings.vue:18
+#: src/views/preference/AuthSettings.vue:17
 msgid "Attempts"
 msgstr "Intentos"
 
-#: src/views/preference/Preference.vue:122
+#: src/views/preference/Preference.vue:153
 msgid "Auth"
 msgstr "Autenticación"
 
@@ -187,7 +187,7 @@ msgstr "Autenticación"
 msgid "Authenticate with a passkey"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:63
+#: src/views/preference/AuthSettings.vue:62
 msgid "Authentication Settings"
 msgstr ""
 
@@ -223,15 +223,15 @@ msgstr "Volver al Inicio"
 msgid "Back to list"
 msgstr "Volver a la lista"
 
-#: src/views/preference/AuthSettings.vue:76
+#: src/views/preference/AuthSettings.vue:103
 msgid "Ban Threshold Minutes"
 msgstr "Umbral de Prohibición en Minutos"
 
-#: src/views/preference/AuthSettings.vue:90
+#: src/views/preference/AuthSettings.vue:124
 msgid "Banned IPs"
 msgstr "IPs prohibidas"
 
-#: src/views/preference/AuthSettings.vue:21
+#: src/views/preference/AuthSettings.vue:20
 msgid "Banned Until"
 msgstr "Bloqueado hasta"
 
@@ -240,7 +240,7 @@ msgid "Base information"
 msgstr "Información general"
 
 #: src/views/config/ConfigEditor.vue:241
-#: src/views/preference/Preference.vue:116
+#: src/views/preference/Preference.vue:147
 #: src/views/site/components/RightSettings.vue:75
 #: src/views/stream/components/RightSettings.vue:74
 msgid "Basic"
@@ -267,7 +267,7 @@ msgstr "Desarrollado con"
 msgid "CA Dir"
 msgstr "Dir CA"
 
-#: src/views/preference/BasicSettings.vue:47
+#: src/views/preference/CertSettings.vue:16
 msgid "CADir"
 msgstr "Directorio CA"
 
@@ -291,7 +291,12 @@ msgstr ""
 msgid "Cancel"
 msgstr "Cancelar"
 
-#: src/views/preference/BasicSettings.vue:55
+#: src/views/preference/Preference.vue:159
+#, fuzzy
+msgid "Cert"
+msgstr "Certificado automático"
+
+#: src/views/preference/CertSettings.vue:24
 msgid "Certificate Renewal Interval"
 msgstr "Intervalo de renovación del Certificado"
 
@@ -477,9 +482,10 @@ msgstr "Versión actual"
 msgid "Custom"
 msgstr "Personalizado"
 
-#: src/views/preference/BasicSettings.vue:121
+#: src/views/preference/BasicSettings.vue:46
+#, fuzzy
 msgid ""
-"Customize the name of local server to be displayed in the environment "
+"Customize the name of local node to be displayed in the environment "
 "indicator."
 msgstr ""
 "Personalice el nombre del servidor local para que se muestre en el indicador "
@@ -494,7 +500,7 @@ msgstr "Panel"
 msgid "Database (Optional, default: database)"
 msgstr "Base de datos (Opcional, default: database)"
 
-#: src/views/preference/BasicSettings.vue:60
+#: src/views/preference/CertSettings.vue:29
 msgid "Days"
 msgstr "Días"
 
@@ -875,11 +881,6 @@ msgstr "Archivo"
 msgid "File exists"
 msgstr "El archivo existe"
 
-#: src/views/preference/NginxSettings.vue:14
-#: src/views/preference/NginxSettings.vue:23
-msgid "File not found"
-msgstr "Archivo no Encontrado"
-
 #: src/views/other/Error.vue:9
 msgid "File Not Found"
 msgstr "Archivo no encontrado"
@@ -898,7 +899,7 @@ msgid ""
 "process."
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:43
+#: src/views/preference/BasicSettings.vue:38
 msgid "For Chinese user: https://mirror.ghproxy.com/"
 msgstr "Para usuario chino: https://mirror.ghproxy.com/"
 
@@ -934,7 +935,7 @@ msgstr "Obtener error de información de versión"
 msgid "Getting the certificate, please wait..."
 msgstr "Obteniendo el certificado, por favor espere..."
 
-#: src/views/preference/BasicSettings.vue:35
+#: src/views/preference/BasicSettings.vue:30
 msgid "Github Proxy"
 msgstr "Proxy Github"
 
@@ -946,15 +947,15 @@ msgstr "Ocultar"
 msgid "Home"
 msgstr "Inicio"
 
-#: src/views/preference/BasicSettings.vue:31
+#: src/views/preference/CertSettings.vue:12
 msgid "HTTP Challenge Port"
 msgstr "Puerto de desafío HTTP"
 
-#: src/views/preference/BasicSettings.vue:13
+#: src/views/preference/BasicSettings.vue:11
 msgid "HTTP Host"
 msgstr "Host HTTP"
 
-#: src/views/preference/BasicSettings.vue:16
+#: src/views/preference/BasicSettings.vue:14
 msgid "HTTP Port"
 msgstr "Puerto HTTP"
 
@@ -966,7 +967,7 @@ msgstr "HTTP01"
 msgid "If left blank, the default CA Dir will be used."
 msgstr "Si se deja en blanco, se utilizará el directorio CA predeterminado."
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:119
 msgid ""
 "If the number of login failed attempts from a ip reach the max attempts in "
 "ban threshold minutes, the ip will be banned for a period of time."
@@ -1003,7 +1004,7 @@ msgstr "Importar"
 msgid "Import Certificate"
 msgstr "Importar Certificado"
 
-#: src/views/other/Login.vue:79
+#: src/views/other/Login.vue:77
 msgid "Incorrect username or password"
 msgstr "Nombre de usuario o contraseña incorrectos"
 
@@ -1044,7 +1045,7 @@ msgstr "Intervalo"
 msgid "Invalid"
 msgstr "Inválido"
 
-#: src/views/other/Login.vue:89
+#: src/views/other/Login.vue:87
 msgid "Invalid 2FA or recovery code"
 msgstr "Código 2FA o de recuperación inválido"
 
@@ -1057,11 +1058,11 @@ msgstr "Nombre de archivo inválido"
 msgid "Invalid folder name"
 msgstr "Nombre de carpeta inválido"
 
-#: src/components/TwoFA/use2FAModal.ts:65
+#: src/components/TwoFA/use2FAModal.ts:60
 msgid "Invalid passcode or recovery code"
 msgstr "Código de acceso o código de recuperación inválido"
 
-#: src/views/preference/AuthSettings.vue:15
+#: src/views/preference/AuthSettings.vue:14
 msgid "IP"
 msgstr "IP"
 
@@ -1081,7 +1082,7 @@ msgstr "Certificado emitido con éxito"
 msgid "Issuer: %{issuer}"
 msgstr "Emisor: %{issuer}"
 
-#: src/views/preference/BasicSettings.vue:22
+#: src/views/preference/BasicSettings.vue:20
 msgid "Jwt Secret"
 msgstr "Secreto Jwt"
 
@@ -1163,11 +1164,11 @@ msgstr "Ubicaciones"
 msgid "Log"
 msgstr "Registro"
 
-#: src/routes/index.ts:305 src/views/other/Login.vue:247
+#: src/routes/index.ts:305 src/views/other/Login.vue:245
 msgid "Login"
 msgstr "Acceso"
 
-#: src/views/other/Login.vue:133 src/views/other/Login.vue:66
+#: src/views/other/Login.vue:131 src/views/other/Login.vue:64
 msgid "Login successful"
 msgstr "Acceso exitoso"
 
@@ -1175,7 +1176,7 @@ msgstr "Acceso exitoso"
 msgid "Logout successful"
 msgstr "Cierre de sesión exitoso"
 
-#: src/views/preference/Preference.vue:140
+#: src/views/preference/Preference.vue:177
 msgid "Logrotate"
 msgstr "Rotación de logs"
 
@@ -1225,7 +1226,7 @@ msgstr "Administrar usuarios"
 msgid "Managed Certificate"
 msgstr "Certificado Administrado"
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:109
 msgid "Max Attempts"
 msgstr "Intentos máximos"
 
@@ -1319,11 +1320,11 @@ msgstr "Se liberó una nueva versión"
 msgid "Next"
 msgstr "Siguiente"
 
-#: src/views/preference/Preference.vue:128
+#: src/views/preference/Preference.vue:165
 msgid "Nginx"
 msgstr "Nginx"
 
-#: src/views/preference/NginxSettings.vue:11
+#: src/views/preference/NginxSettings.vue:9
 msgid "Nginx Access Log Path"
 msgstr "Ruta de registro de acceso de Nginx"
 
@@ -1331,11 +1332,16 @@ msgstr "Ruta de registro de acceso de Nginx"
 msgid "Nginx Configuration Parse Error"
 msgstr "Error de análisis de configuración de Nginx"
 
+#: src/views/preference/NginxSettings.vue:15
+#, fuzzy
+msgid "Nginx Configurations Directory"
+msgstr "Error de análisis de configuración de Nginx"
+
 #: src/components/NginxControl/NginxControl.vue:68
 msgid "Nginx Control"
 msgstr "Control de Nginx"
 
-#: src/views/preference/NginxSettings.vue:20
+#: src/views/preference/NginxSettings.vue:12
 msgid "Nginx Error Log Path"
 msgstr "Ruta de registro de errores de Nginx"
 
@@ -1347,10 +1353,28 @@ msgstr ""
 msgid "Nginx Log"
 msgstr "Registro Nginx"
 
+#: src/views/preference/NginxSettings.vue:18
+msgid "Nginx Log Directory Whitelist"
+msgstr ""
+
+#: src/views/preference/NginxSettings.vue:27
+#, fuzzy
+msgid "Nginx PID Path"
+msgstr "Ruta de registro de errores de Nginx"
+
+#: src/views/preference/NginxSettings.vue:30
+msgid "Nginx Reload Command"
+msgstr ""
+
 #: src/components/NginxControl/NginxControl.vue:26
 msgid "Nginx reloaded successfully"
 msgstr "Nginx recargado con éxito"
 
+#: src/views/preference/NginxSettings.vue:33
+#, fuzzy
+msgid "Nginx Restart Command"
+msgstr "Comando de inicio de terminal"
+
 #: src/components/NginxControl/NginxControl.vue:42
 msgid "Nginx restarted successfully"
 msgstr "Nginx reiniciado con éxito"
@@ -1361,15 +1385,20 @@ msgstr "Nginx reiniciado con éxito"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:561
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:575
 #: src/views/notification/Notification.vue:38
-#: src/views/preference/AuthSettings.vue:104
-#: src/views/preference/BasicSettings.vue:101
+#: src/views/preference/AuthSettings.vue:138
+#: src/views/preference/CertSettings.vue:70
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/site/ngx_conf/LocationEditor.vue:90
 #: src/views/site/SiteList.vue:151 src/views/stream/StreamList.vue:165
 msgid "No"
 msgstr "No"
 
-#: src/views/preference/BasicSettings.vue:25
+#: src/views/preference/BasicSettings.vue:42
+#, fuzzy
+msgid "Node name"
+msgstr "Nuevo nombre"
+
+#: src/views/preference/BasicSettings.vue:23
 msgid "Node Secret"
 msgstr "Secreto del nodo"
 
@@ -1459,11 +1488,11 @@ msgstr "Una vez que se complete la verificación, los registros se eliminarán."
 msgid "Online"
 msgstr "En línea"
 
-#: src/views/preference/Preference.vue:134
+#: src/views/preference/Preference.vue:171
 msgid "OpenAI"
 msgstr "OpenAI"
 
-#: src/components/TwoFA/Authorization.vue:117 src/views/other/Login.vue:256
+#: src/components/TwoFA/Authorization.vue:117 src/views/other/Login.vue:254
 msgid "Or"
 msgstr ""
 
@@ -1506,7 +1535,7 @@ msgid ""
 "password replacement or as a 2FA method."
 msgstr ""
 
-#: src/views/other/Login.vue:208 src/views/user/userColumns.tsx:18
+#: src/views/other/Login.vue:206 src/views/user/userColumns.tsx:18
 msgid "Password"
 msgstr "Contraseña"
 
@@ -1586,11 +1615,11 @@ msgstr ""
 msgid "Please input your E-mail!"
 msgstr "¡Por favor ingrese su correo electrónico!"
 
-#: src/views/other/Install.vue:44 src/views/other/Login.vue:47
+#: src/views/other/Install.vue:44 src/views/other/Login.vue:46
 msgid "Please input your password!"
 msgstr "¡Por favor ingrese su contraseña!"
 
-#: src/views/other/Install.vue:38 src/views/other/Login.vue:41
+#: src/views/other/Install.vue:38 src/views/other/Login.vue:40
 msgid "Please input your username!"
 msgstr "¡Por favor ingrese su nombre de usuario!"
 
@@ -1617,7 +1646,7 @@ msgstr "¡Seleccione al menos un nodo!"
 msgid "Pre-release"
 msgstr "Prelanzamiento"
 
-#: src/routes/index.ts:260 src/views/preference/Preference.vue:111
+#: src/routes/index.ts:260 src/views/preference/Preference.vue:142
 msgid "Preference"
 msgstr "Configuración"
 
@@ -1677,7 +1706,7 @@ msgstr "Código de Recuperación"
 msgid "Recovery Code:"
 msgstr "Código de Recuperación:"
 
-#: src/views/preference/BasicSettings.vue:68
+#: src/views/preference/CertSettings.vue:37
 msgid "Recursive Nameservers"
 msgstr "Servidores de nombres recursivos"
 
@@ -1742,11 +1771,11 @@ msgstr "Recargando"
 msgid "Reloading nginx"
 msgstr "Recargando Nginx"
 
-#: src/views/preference/AuthSettings.vue:109
+#: src/views/preference/AuthSettings.vue:143
 msgid "Remove"
 msgstr "Eliminar"
 
-#: src/views/preference/AuthSettings.vue:48
+#: src/views/preference/AuthSettings.vue:47
 #: src/views/preference/components/Passkey.vue:50
 msgid "Remove successfully"
 msgstr "Eliminado con éxito"
@@ -1829,7 +1858,19 @@ msgstr "Reiniciar"
 msgid "Restarting"
 msgstr "Reiniciando"
 
-#: src/views/preference/BasicSettings.vue:19
+#: src/views/preference/AuthSettings.vue:81
+msgid "RP Display Name"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:87
+msgid "RP Origins"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:75
+msgid "RPID"
+msgstr ""
+
+#: src/views/preference/BasicSettings.vue:17
 msgid "Run Mode"
 msgstr "Modo de ejecución"
 
@@ -1841,7 +1882,7 @@ msgstr "Corriendo"
 #: src/views/certificate/CertificateEditor.vue:256
 #: src/views/config/ConfigEditor.vue:222
 #: src/views/preference/components/Passkey.vue:136
-#: src/views/preference/Preference.vue:151
+#: src/views/preference/Preference.vue:188
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:120
 #: src/views/site/SiteEdit.vue:260 src/views/stream/StreamEdit.vue:252
 msgid "Save"
@@ -1860,7 +1901,7 @@ msgstr "Error al guardar %{msg}"
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:122
 #: src/views/certificate/CertificateEditor.vue:46
-#: src/views/preference/Preference.vue:79
+#: src/views/preference/Preference.vue:110
 msgid "Save successfully"
 msgstr "Guardado con éxito"
 
@@ -1906,13 +1947,13 @@ msgstr "Enviado"
 #: src/views/config/ConfigEditor.vue:108
 #: src/views/environment/BatchUpgrader.vue:59
 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:68
-#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/AuthSettings.vue:49
 #: src/views/preference/components/Passkey.vue:26
 #: src/views/preference/components/Passkey.vue:43
 #: src/views/preference/components/Passkey.vue:56
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:58
-#: src/views/preference/Preference.vue:83 src/views/site/SiteList.vue:88
+#: src/views/preference/Preference.vue:114 src/views/site/SiteList.vue:88
 #: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81
 #: src/views/system/Upgrade.vue:42
 msgid "Server error"
@@ -1922,10 +1963,6 @@ msgstr "Error del servidor"
 msgid "Server Info"
 msgstr "Información del servidor"
 
-#: src/views/preference/BasicSettings.vue:117
-msgid "Server Name"
-msgstr "Nombre del servidor"
-
 #: src/views/site/cert/components/ObtainCert.vue:102
 msgid "server_name not found in directives"
 msgstr "No se encuentra server_name en las directivas"
@@ -1934,7 +1971,7 @@ msgstr "No se encuentra server_name en las directivas"
 msgid "server_name parameter is required"
 msgstr "Se requiere el parámetro server_name"
 
-#: src/views/preference/BasicSettings.vue:64
+#: src/views/preference/CertSettings.vue:33
 msgid ""
 "Set the recursive nameservers to override the systems nameservers for the "
 "step of DNS challenge."
@@ -1958,7 +1995,7 @@ msgstr "Usando el proveedor de desafíos HTTP01"
 msgid "Show"
 msgstr "Mostrar"
 
-#: src/views/other/Login.vue:265
+#: src/views/other/Login.vue:263
 msgid "Sign in with a passkey"
 msgstr ""
 
@@ -1990,7 +2027,7 @@ msgstr "Ruta de la llave del certificado SSL"
 msgid "SSL Certificate Path"
 msgstr "Ruta del certificado SSL"
 
-#: src/views/other/Login.vue:223
+#: src/views/other/Login.vue:221
 msgid "SSO Login"
 msgstr "Acceso SSO"
 
@@ -2116,7 +2153,7 @@ msgstr "Objetivo"
 msgid "Terminal"
 msgstr "Terminal"
 
-#: src/views/preference/BasicSettings.vue:28
+#: src/views/preference/BasicSettings.vue:26
 msgid "Terminal Start Command"
 msgstr "Comando de inicio de terminal"
 
@@ -2151,6 +2188,15 @@ msgstr ""
 "El nombre del modelo solo debe contener letras, unicode, números, guiones, "
 "rayas y puntos."
 
+#: src/views/preference/BasicSettings.vue:45
+#, fuzzy
+msgid ""
+"The node name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
+msgstr ""
+"El nombre del modelo solo debe contener letras, unicode, números, guiones, "
+"rayas y puntos."
+
 #: src/views/certificate/CertificateEditor.vue:173
 msgid "The path exists, but the file is not a certificate"
 msgstr "La ruta existe, pero el archivo no es un certificado"
@@ -2176,14 +2222,6 @@ msgstr ""
 "local. Para evitar errores potenciales, por favor actualice la Nginx UI "
 "remota para que coincida con la versión local."
 
-#: src/views/preference/BasicSettings.vue:120
-msgid ""
-"The server name should only contain letters, unicode, numbers, hyphens, "
-"dashes, and dots."
-msgstr ""
-"El nombre del servidor solo debe contener letras, Unicode, números, guiones, "
-"rayas y puntos."
-
 #: src/views/site/cert/components/AutoCertStepOne.vue:45
 msgid ""
 "The server_name in the current configuration must be the domain name you "
@@ -2192,8 +2230,8 @@ msgstr ""
 "El server_name en la configuración actual debe ser el nombre de dominio que "
 "necesita para obtener el certificado, soporta dominios múltiples."
 
-#: src/views/preference/BasicSettings.vue:38
-#: src/views/preference/BasicSettings.vue:50
+#: src/views/preference/BasicSettings.vue:33
+#: src/views/preference/CertSettings.vue:19
 msgid "The url is invalid"
 msgstr "La URL es inválida"
 
@@ -2231,7 +2269,11 @@ msgstr ""
 "Esto actualizará o reinstalará la interfaz de usuario de Nginx en "
 "%{nodeNames} a %{version}."
 
-#: src/views/preference/AuthSettings.vue:67
+#: src/views/preference/AuthSettings.vue:98
+msgid "Throttle"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:118
 #: src/views/preference/components/AddPasskey.vue:71
 #: src/views/preference/LogrotateSettings.vue:11
 msgid "Tips"
@@ -2278,7 +2320,7 @@ msgstr ""
 msgid "Token is not valid"
 msgstr "El token no es válido"
 
-#: src/views/other/Login.vue:82
+#: src/views/other/Login.vue:80
 msgid "Too many login failed attempts, please try again later"
 msgstr ""
 "Demasiados intentos fallidos de inicio de sesión, por favor intente "
@@ -2300,7 +2342,7 @@ msgstr ""
 msgid "Trash"
 msgstr "Basura"
 
-#: src/components/TwoFA/use2FAModal.ts:71
+#: src/components/TwoFA/use2FAModal.ts:66
 msgid "Two-factor authentication required"
 msgstr "Se requiere autenticación de dos factores"
 
@@ -2371,11 +2413,11 @@ msgstr "Usar código de recuperación"
 msgid "User"
 msgstr "Usuario"
 
-#: src/views/other/Login.vue:85
+#: src/views/other/Login.vue:83
 msgid "User is banned"
 msgstr "El usuario está bloqueado"
 
-#: src/views/other/Login.vue:198 src/views/user/userColumns.tsx:9
+#: src/views/other/Login.vue:196 src/views/user/userColumns.tsx:9
 msgid "Username"
 msgstr "Nombre de usuario"
 
@@ -2433,6 +2475,10 @@ msgstr ""
 "Eliminaremos la configuración de HTTPChallenge de este archivo y "
 "recargaremos Nginx. ¿Estás seguro de que quieres continuar?"
 
+#: src/views/preference/AuthSettings.vue:71
+msgid "Webauthn"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:78
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "
@@ -2453,8 +2499,8 @@ msgstr "Escribir la clave privada del certificado a disco"
 msgid "Writing certificate to disk"
 msgstr "Escribir certificado a disco"
 
-#: src/views/preference/AuthSettings.vue:103
-#: src/views/preference/BasicSettings.vue:100
+#: src/views/preference/AuthSettings.vue:137
+#: src/views/preference/CertSettings.vue:69
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/site/ngx_conf/LocationEditor.vue:89
 msgid "Yes"
@@ -2478,6 +2524,19 @@ msgstr ""
 msgid "Your passkeys"
 msgstr ""
 
+#~ msgid "File not found"
+#~ msgstr "Archivo no Encontrado"
+
+#~ msgid "Server Name"
+#~ msgstr "Nombre del servidor"
+
+#~ msgid ""
+#~ "The server name should only contain letters, unicode, numbers, hyphens, "
+#~ "dashes, and dots."
+#~ msgstr ""
+#~ "El nombre del servidor solo debe contener letras, Unicode, números, "
+#~ "guiones, rayas y puntos."
+
 #~ msgid "Enable 2FA"
 #~ msgstr "Habilitar 2FA"
 
@@ -2485,9 +2544,6 @@ msgstr ""
 #~ msgid "Rename "
 #~ msgstr "Renombrar"
 
-#~ msgid "Auto Cert"
-#~ msgstr "Certificado automático"
-
 #~ msgid "Certificate has expired"
 #~ msgstr "El certificado expiró"
 

+ 132 - 85
app/src/language/fr_FR/app.po

@@ -15,7 +15,7 @@ msgstr ""
 msgid "2FA"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:58
+#: src/views/preference/AuthSettings.vue:57
 msgid "2FA Settings"
 msgstr ""
 
@@ -39,14 +39,14 @@ msgstr "Nom d'utilisateur"
 #: src/views/config/configColumns.ts:38
 #: src/views/environment/envColumns.tsx:131
 #: src/views/notification/notificationColumns.tsx:54
-#: src/views/preference/AuthSettings.vue:27 src/views/site/SiteList.vue:54
+#: src/views/preference/AuthSettings.vue:26 src/views/site/SiteList.vue:54
 #: src/views/stream/StreamList.vue:47 src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Action"
 
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:183
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:204
-#: src/views/preference/BasicSettings.vue:73
+#: src/views/preference/CertSettings.vue:42
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:162
 #: src/views/site/ngx_conf/NgxUpstream.vue:152
@@ -123,7 +123,7 @@ msgstr "Jeton d'API"
 msgid "Arch"
 msgstr "Arch"
 
-#: src/views/preference/AuthSettings.vue:102
+#: src/views/preference/AuthSettings.vue:136
 #, fuzzy
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr "Etes-vous sûr que vous voulez supprimer ?"
@@ -166,7 +166,7 @@ msgstr "Voulez-vous vraiment supprimer cette directive ?"
 msgid "Are you sure you want to remove this directive?"
 msgstr "Voulez-vous vraiment supprimer cette directive ?"
 
-#: src/views/preference/BasicSettings.vue:99
+#: src/views/preference/CertSettings.vue:68
 #, fuzzy
 msgid "Are you sure you want to remove this item?"
 msgstr "Voulez-vous vraiment supprimer cette directive ?"
@@ -184,11 +184,11 @@ msgstr "Modèle ChatGPT"
 msgid "Assistant"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:18
+#: src/views/preference/AuthSettings.vue:17
 msgid "Attempts"
 msgstr ""
 
-#: src/views/preference/Preference.vue:122
+#: src/views/preference/Preference.vue:153
 #, fuzzy
 msgid "Auth"
 msgstr "Autheur"
@@ -197,7 +197,7 @@ msgstr "Autheur"
 msgid "Authenticate with a passkey"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:63
+#: src/views/preference/AuthSettings.vue:62
 msgid "Authentication Settings"
 msgstr ""
 
@@ -233,15 +233,15 @@ msgstr "Retour au menu principal"
 msgid "Back to list"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:76
+#: src/views/preference/AuthSettings.vue:103
 msgid "Ban Threshold Minutes"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:90
+#: src/views/preference/AuthSettings.vue:124
 msgid "Banned IPs"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:21
+#: src/views/preference/AuthSettings.vue:20
 msgid "Banned Until"
 msgstr ""
 
@@ -250,7 +250,7 @@ msgid "Base information"
 msgstr "Information générale"
 
 #: src/views/config/ConfigEditor.vue:241
-#: src/views/preference/Preference.vue:116
+#: src/views/preference/Preference.vue:147
 #: src/views/site/components/RightSettings.vue:75
 #: src/views/stream/components/RightSettings.vue:74
 msgid "Basic"
@@ -279,7 +279,7 @@ msgstr "Build avec"
 msgid "CA Dir"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:47
+#: src/views/preference/CertSettings.vue:16
 msgid "CADir"
 msgstr ""
 
@@ -303,7 +303,12 @@ msgstr ""
 msgid "Cancel"
 msgstr "Annuler"
 
-#: src/views/preference/BasicSettings.vue:55
+#: src/views/preference/Preference.vue:159
+#, fuzzy
+msgid "Cert"
+msgstr "Auto Cert"
+
+#: src/views/preference/CertSettings.vue:24
 #, fuzzy
 msgid "Certificate Renewal Interval"
 msgstr "Le certificat est valide"
@@ -497,9 +502,9 @@ msgstr "Version actuelle"
 msgid "Custom"
 msgstr "Custom"
 
-#: src/views/preference/BasicSettings.vue:121
+#: src/views/preference/BasicSettings.vue:46
 msgid ""
-"Customize the name of local server to be displayed in the environment "
+"Customize the name of local node to be displayed in the environment "
 "indicator."
 msgstr ""
 
@@ -512,7 +517,7 @@ msgstr "Dashboard"
 msgid "Database (Optional, default: database)"
 msgstr "Base de données (Facultatif, par défaut : database)"
 
-#: src/views/preference/BasicSettings.vue:60
+#: src/views/preference/CertSettings.vue:29
 msgid "Days"
 msgstr ""
 
@@ -917,12 +922,6 @@ msgstr "Fichier"
 msgid "File exists"
 msgstr "Le fichier existe"
 
-#: src/views/preference/NginxSettings.vue:14
-#: src/views/preference/NginxSettings.vue:23
-#, fuzzy
-msgid "File not found"
-msgstr "Fichier introuvable"
-
 #: src/views/other/Error.vue:9
 msgid "File Not Found"
 msgstr "Fichier introuvable"
@@ -941,7 +940,7 @@ msgid ""
 "process."
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:43
+#: src/views/preference/BasicSettings.vue:38
 #, fuzzy
 msgid "For Chinese user: https://mirror.ghproxy.com/"
 msgstr "Utilisateur chinois : https://mirror.ghproxy.com/"
@@ -979,7 +978,7 @@ msgstr "Erreur d'obtention des informations sur la version"
 msgid "Getting the certificate, please wait..."
 msgstr "Obtention du certificat, veuillez patienter..."
 
-#: src/views/preference/BasicSettings.vue:35
+#: src/views/preference/BasicSettings.vue:30
 msgid "Github Proxy"
 msgstr "Proxy Github"
 
@@ -991,15 +990,15 @@ msgstr ""
 msgid "Home"
 msgstr "Menu principal"
 
-#: src/views/preference/BasicSettings.vue:31
+#: src/views/preference/CertSettings.vue:12
 msgid "HTTP Challenge Port"
 msgstr "Port de challenge HTTP"
 
-#: src/views/preference/BasicSettings.vue:13
+#: src/views/preference/BasicSettings.vue:11
 msgid "HTTP Host"
 msgstr "Host HTTP"
 
-#: src/views/preference/BasicSettings.vue:16
+#: src/views/preference/BasicSettings.vue:14
 msgid "HTTP Port"
 msgstr "Port HTTP"
 
@@ -1011,7 +1010,7 @@ msgstr "HTTP01"
 msgid "If left blank, the default CA Dir will be used."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:119
 msgid ""
 "If the number of login failed attempts from a ip reach the max attempts in "
 "ban threshold minutes, the ip will be banned for a period of time."
@@ -1043,7 +1042,7 @@ msgstr "Exporter"
 msgid "Import Certificate"
 msgstr "État du certificat"
 
-#: src/views/other/Login.vue:79
+#: src/views/other/Login.vue:77
 #, fuzzy
 msgid "Incorrect username or password"
 msgstr "Le pseudo ou mot de passe est incorect"
@@ -1085,7 +1084,7 @@ msgstr ""
 msgid "Invalid"
 msgstr ""
 
-#: src/views/other/Login.vue:89
+#: src/views/other/Login.vue:87
 msgid "Invalid 2FA or recovery code"
 msgstr ""
 
@@ -1098,11 +1097,11 @@ msgstr ""
 msgid "Invalid folder name"
 msgstr ""
 
-#: src/components/TwoFA/use2FAModal.ts:65
+#: src/components/TwoFA/use2FAModal.ts:60
 msgid "Invalid passcode or recovery code"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:15
+#: src/views/preference/AuthSettings.vue:14
 msgid "IP"
 msgstr ""
 
@@ -1124,7 +1123,7 @@ msgstr "Certificat délivré avec succès"
 msgid "Issuer: %{issuer}"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:22
+#: src/views/preference/BasicSettings.vue:20
 msgid "Jwt Secret"
 msgstr "Secret Jwt"
 
@@ -1215,11 +1214,11 @@ msgstr "Localisations"
 msgid "Log"
 msgstr "Connexion"
 
-#: src/routes/index.ts:305 src/views/other/Login.vue:247
+#: src/routes/index.ts:305 src/views/other/Login.vue:245
 msgid "Login"
 msgstr "Connexion"
 
-#: src/views/other/Login.vue:133 src/views/other/Login.vue:66
+#: src/views/other/Login.vue:131 src/views/other/Login.vue:64
 msgid "Login successful"
 msgstr "Connexion réussie"
 
@@ -1227,7 +1226,7 @@ msgstr "Connexion réussie"
 msgid "Logout successful"
 msgstr "Déconnexion réussie"
 
-#: src/views/preference/Preference.vue:140
+#: src/views/preference/Preference.vue:177
 msgid "Logrotate"
 msgstr ""
 
@@ -1273,7 +1272,7 @@ msgstr "Gérer les utilisateurs"
 msgid "Managed Certificate"
 msgstr "Changer de certificat"
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:109
 msgid "Max Attempts"
 msgstr ""
 
@@ -1372,12 +1371,12 @@ msgstr "Nouvelle version publiée"
 msgid "Next"
 msgstr "Suivant"
 
-#: src/views/preference/Preference.vue:128
+#: src/views/preference/Preference.vue:165
 #, fuzzy
 msgid "Nginx"
 msgstr "Journal Nginx"
 
-#: src/views/preference/NginxSettings.vue:11
+#: src/views/preference/NginxSettings.vue:9
 msgid "Nginx Access Log Path"
 msgstr "Chemin du journal d'accès Nginx"
 
@@ -1385,11 +1384,16 @@ msgstr "Chemin du journal d'accès Nginx"
 msgid "Nginx Configuration Parse Error"
 msgstr "Erreur d'analyse de configuration Nginx"
 
+#: src/views/preference/NginxSettings.vue:15
+#, fuzzy
+msgid "Nginx Configurations Directory"
+msgstr "Erreur d'analyse de configuration Nginx"
+
 #: src/components/NginxControl/NginxControl.vue:68
 msgid "Nginx Control"
 msgstr "Contrôle Nginx"
 
-#: src/views/preference/NginxSettings.vue:20
+#: src/views/preference/NginxSettings.vue:12
 msgid "Nginx Error Log Path"
 msgstr "Chemin du journal des erreurs Nginx"
 
@@ -1401,10 +1405,28 @@ msgstr ""
 msgid "Nginx Log"
 msgstr "Journal Nginx"
 
+#: src/views/preference/NginxSettings.vue:18
+msgid "Nginx Log Directory Whitelist"
+msgstr ""
+
+#: src/views/preference/NginxSettings.vue:27
+#, fuzzy
+msgid "Nginx PID Path"
+msgstr "Chemin du journal des erreurs Nginx"
+
+#: src/views/preference/NginxSettings.vue:30
+msgid "Nginx Reload Command"
+msgstr ""
+
 #: src/components/NginxControl/NginxControl.vue:26
 msgid "Nginx reloaded successfully"
 msgstr "Nginx a été rechargé avec succès"
 
+#: src/views/preference/NginxSettings.vue:33
+#, fuzzy
+msgid "Nginx Restart Command"
+msgstr "Commande de démarrage du terminal"
+
 #: src/components/NginxControl/NginxControl.vue:42
 msgid "Nginx restarted successfully"
 msgstr "Nginx a redémarré avec succès"
@@ -1415,15 +1437,20 @@ msgstr "Nginx a redémarré avec succès"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:561
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:575
 #: src/views/notification/Notification.vue:38
-#: src/views/preference/AuthSettings.vue:104
-#: src/views/preference/BasicSettings.vue:101
+#: src/views/preference/AuthSettings.vue:138
+#: src/views/preference/CertSettings.vue:70
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/site/ngx_conf/LocationEditor.vue:90
 #: src/views/site/SiteList.vue:151 src/views/stream/StreamList.vue:165
 msgid "No"
 msgstr "Non"
 
-#: src/views/preference/BasicSettings.vue:25
+#: src/views/preference/BasicSettings.vue:42
+#, fuzzy
+msgid "Node name"
+msgstr "Nom d'utilisateur"
+
+#: src/views/preference/BasicSettings.vue:23
 #, fuzzy
 msgid "Node Secret"
 msgstr "Secret Jwt"
@@ -1514,11 +1541,11 @@ msgstr ""
 msgid "Online"
 msgstr ""
 
-#: src/views/preference/Preference.vue:134
+#: src/views/preference/Preference.vue:171
 msgid "OpenAI"
 msgstr "OpenAI"
 
-#: src/components/TwoFA/Authorization.vue:117 src/views/other/Login.vue:256
+#: src/components/TwoFA/Authorization.vue:117 src/views/other/Login.vue:254
 msgid "Or"
 msgstr ""
 
@@ -1561,7 +1588,7 @@ msgid ""
 "password replacement or as a 2FA method."
 msgstr ""
 
-#: src/views/other/Login.vue:208 src/views/user/userColumns.tsx:18
+#: src/views/other/Login.vue:206 src/views/user/userColumns.tsx:18
 msgid "Password"
 msgstr "Mot de passe"
 
@@ -1642,11 +1669,11 @@ msgstr ""
 msgid "Please input your E-mail!"
 msgstr "Veuillez saisir votre e-mail !"
 
-#: src/views/other/Install.vue:44 src/views/other/Login.vue:47
+#: src/views/other/Install.vue:44 src/views/other/Login.vue:46
 msgid "Please input your password!"
 msgstr "Veuillez saisir votre mot de passe !"
 
-#: src/views/other/Install.vue:38 src/views/other/Login.vue:41
+#: src/views/other/Install.vue:38 src/views/other/Login.vue:40
 msgid "Please input your username!"
 msgstr "Veuillez saisir votre nom d'utilisateur !"
 
@@ -1670,7 +1697,7 @@ msgstr ""
 msgid "Pre-release"
 msgstr ""
 
-#: src/routes/index.ts:260 src/views/preference/Preference.vue:111
+#: src/routes/index.ts:260 src/views/preference/Preference.vue:142
 msgid "Preference"
 msgstr "Préférence"
 
@@ -1734,7 +1761,7 @@ msgstr ""
 msgid "Recovery Code:"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:68
+#: src/views/preference/CertSettings.vue:37
 msgid "Recursive Nameservers"
 msgstr ""
 
@@ -1803,11 +1830,11 @@ msgstr "Rechargement"
 msgid "Reloading nginx"
 msgstr "Rechargement de nginx"
 
-#: src/views/preference/AuthSettings.vue:109
+#: src/views/preference/AuthSettings.vue:143
 msgid "Remove"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:48
+#: src/views/preference/AuthSettings.vue:47
 #: src/views/preference/components/Passkey.vue:50
 #, fuzzy
 msgid "Remove successfully"
@@ -1901,7 +1928,19 @@ msgstr "Redémarrer"
 msgid "Restarting"
 msgstr "Redémarrage"
 
-#: src/views/preference/BasicSettings.vue:19
+#: src/views/preference/AuthSettings.vue:81
+msgid "RP Display Name"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:87
+msgid "RP Origins"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:75
+msgid "RPID"
+msgstr ""
+
+#: src/views/preference/BasicSettings.vue:17
 msgid "Run Mode"
 msgstr "Mode d'exécution"
 
@@ -1913,7 +1952,7 @@ msgstr "En cours d'éxécution"
 #: src/views/certificate/CertificateEditor.vue:256
 #: src/views/config/ConfigEditor.vue:222
 #: src/views/preference/components/Passkey.vue:136
-#: src/views/preference/Preference.vue:151
+#: src/views/preference/Preference.vue:188
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:120
 #: src/views/site/SiteEdit.vue:260 src/views/stream/StreamEdit.vue:252
 msgid "Save"
@@ -1932,7 +1971,7 @@ msgstr "Enregistrer l'erreur %{msg}"
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:122
 #: src/views/certificate/CertificateEditor.vue:46
-#: src/views/preference/Preference.vue:79
+#: src/views/preference/Preference.vue:110
 msgid "Save successfully"
 msgstr "Sauvegarde réussie"
 
@@ -1976,13 +2015,13 @@ msgstr "Envoyer"
 #: src/views/config/ConfigEditor.vue:108
 #: src/views/environment/BatchUpgrader.vue:59
 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:68
-#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/AuthSettings.vue:49
 #: src/views/preference/components/Passkey.vue:26
 #: src/views/preference/components/Passkey.vue:43
 #: src/views/preference/components/Passkey.vue:56
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:58
-#: src/views/preference/Preference.vue:83 src/views/site/SiteList.vue:88
+#: src/views/preference/Preference.vue:114 src/views/site/SiteList.vue:88
 #: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81
 #: src/views/system/Upgrade.vue:42
 msgid "Server error"
@@ -1992,11 +2031,6 @@ msgstr "Erreur du serveur"
 msgid "Server Info"
 msgstr "Informations sur le serveur"
 
-#: src/views/preference/BasicSettings.vue:117
-#, fuzzy
-msgid "Server Name"
-msgstr "Informations sur le serveur"
-
 #: src/views/site/cert/components/ObtainCert.vue:102
 msgid "server_name not found in directives"
 msgstr "server_name introuvable dans les directives"
@@ -2005,7 +2039,7 @@ msgstr "server_name introuvable dans les directives"
 msgid "server_name parameter is required"
 msgstr "Le paramètre server_name est obligatoire"
 
-#: src/views/preference/BasicSettings.vue:64
+#: src/views/preference/CertSettings.vue:33
 msgid ""
 "Set the recursive nameservers to override the systems nameservers for the "
 "step of DNS challenge."
@@ -2029,7 +2063,7 @@ msgstr "Utilisation du fournisseur de challenge HTTP01"
 msgid "Show"
 msgstr ""
 
-#: src/views/other/Login.vue:265
+#: src/views/other/Login.vue:263
 msgid "Sign in with a passkey"
 msgstr ""
 
@@ -2063,7 +2097,7 @@ msgstr "Chemin de la clé du certificat SSL"
 msgid "SSL Certificate Path"
 msgstr "Chemin du certificat SSL"
 
-#: src/views/other/Login.vue:223
+#: src/views/other/Login.vue:221
 #, fuzzy
 msgid "SSO Login"
 msgstr "Connexion"
@@ -2193,7 +2227,7 @@ msgstr ""
 msgid "Terminal"
 msgstr "Terminal"
 
-#: src/views/preference/BasicSettings.vue:28
+#: src/views/preference/BasicSettings.vue:26
 msgid "Terminal Start Command"
 msgstr "Commande de démarrage du terminal"
 
@@ -2226,6 +2260,12 @@ msgid ""
 "dashes, and dots."
 msgstr ""
 
+#: src/views/preference/BasicSettings.vue:45
+msgid ""
+"The node name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
+msgstr ""
+
 #: src/views/certificate/CertificateEditor.vue:173
 #, fuzzy
 msgid "The path exists, but the file is not a certificate"
@@ -2247,12 +2287,6 @@ msgid ""
 "match the local version."
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:120
-msgid ""
-"The server name should only contain letters, unicode, numbers, hyphens, "
-"dashes, and dots."
-msgstr ""
-
 #: src/views/site/cert/components/AutoCertStepOne.vue:45
 #, fuzzy
 msgid ""
@@ -2263,8 +2297,8 @@ msgstr ""
 "dont vous avez besoin pour obtenir le certificat, prendre en charge "
 "plusieurs domaines."
 
-#: src/views/preference/BasicSettings.vue:38
-#: src/views/preference/BasicSettings.vue:50
+#: src/views/preference/BasicSettings.vue:33
+#: src/views/preference/CertSettings.vue:19
 msgid "The url is invalid"
 msgstr ""
 
@@ -2303,7 +2337,11 @@ msgid ""
 "This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:67
+#: src/views/preference/AuthSettings.vue:98
+msgid "Throttle"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:118
 #: src/views/preference/components/AddPasskey.vue:71
 #: src/views/preference/LogrotateSettings.vue:11
 msgid "Tips"
@@ -2348,7 +2386,7 @@ msgstr ""
 msgid "Token is not valid"
 msgstr ""
 
-#: src/views/other/Login.vue:82
+#: src/views/other/Login.vue:80
 msgid "Too many login failed attempts, please try again later"
 msgstr ""
 
@@ -2366,7 +2404,7 @@ msgstr ""
 msgid "Trash"
 msgstr ""
 
-#: src/components/TwoFA/use2FAModal.ts:71
+#: src/components/TwoFA/use2FAModal.ts:66
 msgid "Two-factor authentication required"
 msgstr ""
 
@@ -2439,11 +2477,11 @@ msgstr ""
 msgid "User"
 msgstr "Nom d'utilisateur"
 
-#: src/views/other/Login.vue:85
+#: src/views/other/Login.vue:83
 msgid "User is banned"
 msgstr ""
 
-#: src/views/other/Login.vue:198 src/views/user/userColumns.tsx:9
+#: src/views/other/Login.vue:196 src/views/user/userColumns.tsx:9
 msgid "Username"
 msgstr "Nom d'utilisateur"
 
@@ -2502,6 +2540,10 @@ msgstr ""
 "Nous allons supprimer la configuration HTTPChallenge de ce fichier et "
 "recharger le Nginx. Êtes-vous sûr de vouloir continuer?"
 
+#: src/views/preference/AuthSettings.vue:71
+msgid "Webauthn"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:78
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "
@@ -2522,8 +2564,8 @@ msgstr "Écriture de la clé privée du certificat sur le disque"
 msgid "Writing certificate to disk"
 msgstr "Écriture du certificat sur le disque"
 
-#: src/views/preference/AuthSettings.vue:103
-#: src/views/preference/BasicSettings.vue:100
+#: src/views/preference/AuthSettings.vue:137
+#: src/views/preference/CertSettings.vue:69
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/site/ngx_conf/LocationEditor.vue:89
 msgid "Yes"
@@ -2547,6 +2589,14 @@ msgstr ""
 msgid "Your passkeys"
 msgstr ""
 
+#, fuzzy
+#~ msgid "File not found"
+#~ msgstr "Fichier introuvable"
+
+#, fuzzy
+#~ msgid "Server Name"
+#~ msgstr "Informations sur le serveur"
+
 #, fuzzy
 #~ msgid "Enable 2FA"
 #~ msgstr "Activé"
@@ -2555,9 +2605,6 @@ msgstr ""
 #~ msgid "Rename "
 #~ msgstr "Nom d'utilisateur"
 
-#~ msgid "Auto Cert"
-#~ msgstr "Auto Cert"
-
 #~ msgid "Certificate has expired"
 #~ msgstr "Le certificat a expiré"
 

+ 132 - 85
app/src/language/ko_KR/app.po

@@ -18,7 +18,7 @@ msgstr ""
 msgid "2FA"
 msgstr "2FA"
 
-#: src/views/preference/AuthSettings.vue:58
+#: src/views/preference/AuthSettings.vue:57
 msgid "2FA Settings"
 msgstr "2FA 설정"
 
@@ -41,14 +41,14 @@ msgstr "ACME 사용자"
 #: src/views/config/configColumns.ts:38
 #: src/views/environment/envColumns.tsx:131
 #: src/views/notification/notificationColumns.tsx:54
-#: src/views/preference/AuthSettings.vue:27 src/views/site/SiteList.vue:54
+#: src/views/preference/AuthSettings.vue:26 src/views/site/SiteList.vue:54
 #: src/views/stream/StreamList.vue:47 src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "작업"
 
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:183
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:204
-#: src/views/preference/BasicSettings.vue:73
+#: src/views/preference/CertSettings.vue:42
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:162
 #: src/views/site/ngx_conf/NgxUpstream.vue:152
@@ -119,7 +119,7 @@ msgstr "API 토큰"
 msgid "Arch"
 msgstr "아키텍처"
 
-#: src/views/preference/AuthSettings.vue:102
+#: src/views/preference/AuthSettings.vue:136
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr "차단된 IP를 즉시 삭제하시겠습니까?"
 
@@ -157,7 +157,7 @@ msgstr "이 항목을 복구하시겠습니까?"
 msgid "Are you sure you want to remove this directive?"
 msgstr "이 지시문을 정말로 제거하시겠습니까?"
 
-#: src/views/preference/BasicSettings.vue:99
+#: src/views/preference/CertSettings.vue:68
 msgid "Are you sure you want to remove this item?"
 msgstr "이 항목을 제거하시겠습니까?"
 
@@ -173,11 +173,11 @@ msgstr "ChatGPT에게 도움 요청"
 msgid "Assistant"
 msgstr "조수"
 
-#: src/views/preference/AuthSettings.vue:18
+#: src/views/preference/AuthSettings.vue:17
 msgid "Attempts"
 msgstr "시도 횟수"
 
-#: src/views/preference/Preference.vue:122
+#: src/views/preference/Preference.vue:153
 msgid "Auth"
 msgstr "인증"
 
@@ -185,7 +185,7 @@ msgstr "인증"
 msgid "Authenticate with a passkey"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:63
+#: src/views/preference/AuthSettings.vue:62
 msgid "Authentication Settings"
 msgstr ""
 
@@ -221,15 +221,15 @@ msgstr "홈으로"
 msgid "Back to list"
 msgstr "목록으로 돌아가기"
 
-#: src/views/preference/AuthSettings.vue:76
+#: src/views/preference/AuthSettings.vue:103
 msgid "Ban Threshold Minutes"
 msgstr "차단 시간(분)"
 
-#: src/views/preference/AuthSettings.vue:90
+#: src/views/preference/AuthSettings.vue:124
 msgid "Banned IPs"
 msgstr "차단된 IP"
 
-#: src/views/preference/AuthSettings.vue:21
+#: src/views/preference/AuthSettings.vue:20
 msgid "Banned Until"
 msgstr "차단될 시간"
 
@@ -238,7 +238,7 @@ msgid "Base information"
 msgstr "기본 정보"
 
 #: src/views/config/ConfigEditor.vue:241
-#: src/views/preference/Preference.vue:116
+#: src/views/preference/Preference.vue:147
 #: src/views/site/components/RightSettings.vue:75
 #: src/views/stream/components/RightSettings.vue:74
 msgid "Basic"
@@ -265,7 +265,7 @@ msgstr "빌드 환경"
 msgid "CA Dir"
 msgstr "CA 디렉토리"
 
-#: src/views/preference/BasicSettings.vue:47
+#: src/views/preference/CertSettings.vue:16
 msgid "CADir"
 msgstr "CA 디렉토리"
 
@@ -289,7 +289,12 @@ msgstr ""
 msgid "Cancel"
 msgstr "취소"
 
-#: src/views/preference/BasicSettings.vue:55
+#: src/views/preference/Preference.vue:159
+#, fuzzy
+msgid "Cert"
+msgstr "자동 인증"
+
+#: src/views/preference/CertSettings.vue:24
 msgid "Certificate Renewal Interval"
 msgstr "인증서 갱신 간격"
 
@@ -476,9 +481,9 @@ msgstr "현재 버전"
 msgid "Custom"
 msgstr "사용자 정의"
 
-#: src/views/preference/BasicSettings.vue:121
+#: src/views/preference/BasicSettings.vue:46
 msgid ""
-"Customize the name of local server to be displayed in the environment "
+"Customize the name of local node to be displayed in the environment "
 "indicator."
 msgstr ""
 
@@ -491,7 +496,7 @@ msgstr "대시보드"
 msgid "Database (Optional, default: database)"
 msgstr "데이터베이스 (선택사항, 기본값: database)"
 
-#: src/views/preference/BasicSettings.vue:60
+#: src/views/preference/CertSettings.vue:29
 msgid "Days"
 msgstr ""
 
@@ -876,12 +881,6 @@ msgstr "파일"
 msgid "File exists"
 msgstr "파일이 존재함"
 
-#: src/views/preference/NginxSettings.vue:14
-#: src/views/preference/NginxSettings.vue:23
-#, fuzzy
-msgid "File not found"
-msgstr "파일을 찾을 수 없음"
-
 #: src/views/other/Error.vue:9
 msgid "File Not Found"
 msgstr "파일을 찾을 수 없음"
@@ -900,7 +899,7 @@ msgid ""
 "process."
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:43
+#: src/views/preference/BasicSettings.vue:38
 msgid "For Chinese user: https://mirror.ghproxy.com/"
 msgstr "중국 사용자를 위해: https://mirror.ghproxy.com/"
 
@@ -940,7 +939,7 @@ msgstr "릴리스 정보 가져오기 오류"
 msgid "Getting the certificate, please wait..."
 msgstr "인증서를 가져오는 중입니다. 잠시 기다려 주세요..."
 
-#: src/views/preference/BasicSettings.vue:35
+#: src/views/preference/BasicSettings.vue:30
 msgid "Github Proxy"
 msgstr "Github 프록시"
 
@@ -952,15 +951,15 @@ msgstr ""
 msgid "Home"
 msgstr "홈"
 
-#: src/views/preference/BasicSettings.vue:31
+#: src/views/preference/CertSettings.vue:12
 msgid "HTTP Challenge Port"
 msgstr "HTTP 검증 포트"
 
-#: src/views/preference/BasicSettings.vue:13
+#: src/views/preference/BasicSettings.vue:11
 msgid "HTTP Host"
 msgstr "HTTP 호스트"
 
-#: src/views/preference/BasicSettings.vue:16
+#: src/views/preference/BasicSettings.vue:14
 msgid "HTTP Port"
 msgstr "HTTP 포트"
 
@@ -972,7 +971,7 @@ msgstr "HTTP01"
 msgid "If left blank, the default CA Dir will be used."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:119
 msgid ""
 "If the number of login failed attempts from a ip reach the max attempts in "
 "ban threshold minutes, the ip will be banned for a period of time."
@@ -1003,7 +1002,7 @@ msgstr "가져오기"
 msgid "Import Certificate"
 msgstr "인증서 상태"
 
-#: src/views/other/Login.vue:79
+#: src/views/other/Login.vue:77
 #, fuzzy
 msgid "Incorrect username or password"
 msgstr "사용자 이름 또는 비밀번호가 올바르지 않습니다"
@@ -1047,7 +1046,7 @@ msgstr "간격"
 msgid "Invalid"
 msgstr "유효함"
 
-#: src/views/other/Login.vue:89
+#: src/views/other/Login.vue:87
 msgid "Invalid 2FA or recovery code"
 msgstr ""
 
@@ -1061,11 +1060,11 @@ msgstr "Invalid E-mail!"
 msgid "Invalid folder name"
 msgstr ""
 
-#: src/components/TwoFA/use2FAModal.ts:65
+#: src/components/TwoFA/use2FAModal.ts:60
 msgid "Invalid passcode or recovery code"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:15
+#: src/views/preference/AuthSettings.vue:14
 msgid "IP"
 msgstr ""
 
@@ -1088,7 +1087,7 @@ msgstr "성공적으로 활성화됨"
 msgid "Issuer: %{issuer}"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:22
+#: src/views/preference/BasicSettings.vue:20
 msgid "Jwt Secret"
 msgstr "Jwt 토큰"
 
@@ -1176,11 +1175,11 @@ msgstr "위치들"
 msgid "Log"
 msgstr "로그인"
 
-#: src/routes/index.ts:305 src/views/other/Login.vue:247
+#: src/routes/index.ts:305 src/views/other/Login.vue:245
 msgid "Login"
 msgstr "로그인"
 
-#: src/views/other/Login.vue:133 src/views/other/Login.vue:66
+#: src/views/other/Login.vue:131 src/views/other/Login.vue:64
 msgid "Login successful"
 msgstr "로그인 성공"
 
@@ -1188,7 +1187,7 @@ msgstr "로그인 성공"
 msgid "Logout successful"
 msgstr "로그아웃 성공"
 
-#: src/views/preference/Preference.vue:140
+#: src/views/preference/Preference.vue:177
 msgid "Logrotate"
 msgstr "로그관리"
 
@@ -1239,7 +1238,7 @@ msgstr "사용자 관리"
 msgid "Managed Certificate"
 msgstr "인증서 유효"
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:109
 msgid "Max Attempts"
 msgstr ""
 
@@ -1340,11 +1339,11 @@ msgstr "새 버전 출시"
 msgid "Next"
 msgstr "다음"
 
-#: src/views/preference/Preference.vue:128
+#: src/views/preference/Preference.vue:165
 msgid "Nginx"
 msgstr "Nginx"
 
-#: src/views/preference/NginxSettings.vue:11
+#: src/views/preference/NginxSettings.vue:9
 msgid "Nginx Access Log Path"
 msgstr "Nginx 접근 로그 경로"
 
@@ -1353,11 +1352,16 @@ msgstr "Nginx 접근 로그 경로"
 msgid "Nginx Configuration Parse Error"
 msgstr "Nginx 구성 오류름"
 
+#: src/views/preference/NginxSettings.vue:15
+#, fuzzy
+msgid "Nginx Configurations Directory"
+msgstr "Nginx 구성 오류름"
+
 #: src/components/NginxControl/NginxControl.vue:68
 msgid "Nginx Control"
 msgstr "Nginx 제어"
 
-#: src/views/preference/NginxSettings.vue:20
+#: src/views/preference/NginxSettings.vue:12
 msgid "Nginx Error Log Path"
 msgstr "Nginx 오류 로그 경로"
 
@@ -1369,11 +1373,29 @@ msgstr ""
 msgid "Nginx Log"
 msgstr "Nginx 로그"
 
+#: src/views/preference/NginxSettings.vue:18
+msgid "Nginx Log Directory Whitelist"
+msgstr ""
+
+#: src/views/preference/NginxSettings.vue:27
+#, fuzzy
+msgid "Nginx PID Path"
+msgstr "Nginx 오류 로그 경로"
+
+#: src/views/preference/NginxSettings.vue:30
+msgid "Nginx Reload Command"
+msgstr ""
+
 #: src/components/NginxControl/NginxControl.vue:26
 #, fuzzy
 msgid "Nginx reloaded successfully"
 msgstr "Nginx가 성공적으로 리로드됨"
 
+#: src/views/preference/NginxSettings.vue:33
+#, fuzzy
+msgid "Nginx Restart Command"
+msgstr "터미널 시작 명령"
+
 #: src/components/NginxControl/NginxControl.vue:42
 #, fuzzy
 msgid "Nginx restarted successfully"
@@ -1385,15 +1407,20 @@ msgstr "Nginx가 성공적으로 재시작됨"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:561
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:575
 #: src/views/notification/Notification.vue:38
-#: src/views/preference/AuthSettings.vue:104
-#: src/views/preference/BasicSettings.vue:101
+#: src/views/preference/AuthSettings.vue:138
+#: src/views/preference/CertSettings.vue:70
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/site/ngx_conf/LocationEditor.vue:90
 #: src/views/site/SiteList.vue:151 src/views/stream/StreamList.vue:165
 msgid "No"
 msgstr "아니요"
 
-#: src/views/preference/BasicSettings.vue:25
+#: src/views/preference/BasicSettings.vue:42
+#, fuzzy
+msgid "Node name"
+msgstr "이름 변경"
+
+#: src/views/preference/BasicSettings.vue:23
 msgid "Node Secret"
 msgstr "노드 시크릿"
 
@@ -1484,11 +1511,11 @@ msgstr "검증이 완료되면, 레코드는 제거됩니다."
 msgid "Online"
 msgstr "온라인"
 
-#: src/views/preference/Preference.vue:134
+#: src/views/preference/Preference.vue:171
 msgid "OpenAI"
 msgstr "오픈AI"
 
-#: src/components/TwoFA/Authorization.vue:117 src/views/other/Login.vue:256
+#: src/components/TwoFA/Authorization.vue:117 src/views/other/Login.vue:254
 msgid "Or"
 msgstr ""
 
@@ -1532,7 +1559,7 @@ msgid ""
 "password replacement or as a 2FA method."
 msgstr ""
 
-#: src/views/other/Login.vue:208 src/views/user/userColumns.tsx:18
+#: src/views/other/Login.vue:206 src/views/user/userColumns.tsx:18
 msgid "Password"
 msgstr "비밀번호"
 
@@ -1608,11 +1635,11 @@ msgstr "이름을 입력해주세요, 이것은 새 구성의 파일 이름으
 msgid "Please input your E-mail!"
 msgstr "이메일을 입력해주세요!"
 
-#: src/views/other/Install.vue:44 src/views/other/Login.vue:47
+#: src/views/other/Install.vue:44 src/views/other/Login.vue:46
 msgid "Please input your password!"
 msgstr "비밀번호를 입력해주세요!"
 
-#: src/views/other/Install.vue:38 src/views/other/Login.vue:41
+#: src/views/other/Install.vue:38 src/views/other/Login.vue:40
 msgid "Please input your username!"
 msgstr "사용자 이름을 입력해주세요!"
 
@@ -1637,7 +1664,7 @@ msgstr "적어도 하나의 노드를 선택해주세요!"
 msgid "Pre-release"
 msgstr "사전 출시"
 
-#: src/routes/index.ts:260 src/views/preference/Preference.vue:111
+#: src/routes/index.ts:260 src/views/preference/Preference.vue:142
 msgid "Preference"
 msgstr "환경설정"
 
@@ -1699,7 +1726,7 @@ msgstr ""
 msgid "Recovery Code:"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:68
+#: src/views/preference/CertSettings.vue:37
 msgid "Recursive Nameservers"
 msgstr ""
 
@@ -1769,11 +1796,11 @@ msgstr "리로딩 중"
 msgid "Reloading nginx"
 msgstr "Nginx 리로딩 중"
 
-#: src/views/preference/AuthSettings.vue:109
+#: src/views/preference/AuthSettings.vue:143
 msgid "Remove"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:48
+#: src/views/preference/AuthSettings.vue:47
 #: src/views/preference/components/Passkey.vue:50
 #, fuzzy
 msgid "Remove successfully"
@@ -1867,7 +1894,19 @@ msgstr "재시작"
 msgid "Restarting"
 msgstr "재시작 중"
 
-#: src/views/preference/BasicSettings.vue:19
+#: src/views/preference/AuthSettings.vue:81
+msgid "RP Display Name"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:87
+msgid "RP Origins"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:75
+msgid "RPID"
+msgstr ""
+
+#: src/views/preference/BasicSettings.vue:17
 #, fuzzy
 msgid "Run Mode"
 msgstr "실행 모드"
@@ -1880,7 +1919,7 @@ msgstr "실행 중"
 #: src/views/certificate/CertificateEditor.vue:256
 #: src/views/config/ConfigEditor.vue:222
 #: src/views/preference/components/Passkey.vue:136
-#: src/views/preference/Preference.vue:151
+#: src/views/preference/Preference.vue:188
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:120
 #: src/views/site/SiteEdit.vue:260 src/views/stream/StreamEdit.vue:252
 msgid "Save"
@@ -1899,7 +1938,7 @@ msgstr "저장 오류 %{msg}"
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:122
 #: src/views/certificate/CertificateEditor.vue:46
-#: src/views/preference/Preference.vue:79
+#: src/views/preference/Preference.vue:110
 #, fuzzy
 msgid "Save successfully"
 msgstr "성공적으로 저장됨"
@@ -1944,13 +1983,13 @@ msgstr "보내기"
 #: src/views/config/ConfigEditor.vue:108
 #: src/views/environment/BatchUpgrader.vue:59
 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:68
-#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/AuthSettings.vue:49
 #: src/views/preference/components/Passkey.vue:26
 #: src/views/preference/components/Passkey.vue:43
 #: src/views/preference/components/Passkey.vue:56
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:58
-#: src/views/preference/Preference.vue:83 src/views/site/SiteList.vue:88
+#: src/views/preference/Preference.vue:114 src/views/site/SiteList.vue:88
 #: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81
 #: src/views/system/Upgrade.vue:42
 msgid "Server error"
@@ -1960,11 +1999,6 @@ msgstr "서버 오류"
 msgid "Server Info"
 msgstr "서버 정보"
 
-#: src/views/preference/BasicSettings.vue:117
-#, fuzzy
-msgid "Server Name"
-msgstr "Server Info"
-
 #: src/views/site/cert/components/ObtainCert.vue:102
 msgid "server_name not found in directives"
 msgstr "directives에서 server_name을 찾을 수 없습니다"
@@ -1973,7 +2007,7 @@ msgstr "directives에서 server_name을 찾을 수 없습니다"
 msgid "server_name parameter is required"
 msgstr "server_name 매개변수가 필요합니다"
 
-#: src/views/preference/BasicSettings.vue:64
+#: src/views/preference/CertSettings.vue:33
 msgid ""
 "Set the recursive nameservers to override the systems nameservers for the "
 "step of DNS challenge."
@@ -1995,7 +2029,7 @@ msgstr "HTTP01 공급자 설정"
 msgid "Show"
 msgstr ""
 
-#: src/views/other/Login.vue:265
+#: src/views/other/Login.vue:263
 msgid "Sign in with a passkey"
 msgstr ""
 
@@ -2031,7 +2065,7 @@ msgstr "SSL 인증서 키 경로"
 msgid "SSL Certificate Path"
 msgstr "SSL 인증서 경로"
 
-#: src/views/other/Login.vue:223
+#: src/views/other/Login.vue:221
 #, fuzzy
 msgid "SSO Login"
 msgstr "SSO 로그인"
@@ -2160,7 +2194,7 @@ msgstr "대상"
 msgid "Terminal"
 msgstr "터미널"
 
-#: src/views/preference/BasicSettings.vue:28
+#: src/views/preference/BasicSettings.vue:26
 msgid "Terminal Start Command"
 msgstr "터미널 시작 명령"
 
@@ -2193,6 +2227,12 @@ msgid ""
 "dashes, and dots."
 msgstr ""
 
+#: src/views/preference/BasicSettings.vue:45
+msgid ""
+"The node name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
+msgstr ""
+
 #: src/views/certificate/CertificateEditor.vue:173
 #, fuzzy
 msgid "The path exists, but the file is not a certificate"
@@ -2214,12 +2254,6 @@ msgid ""
 "match the local version."
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:120
-msgid ""
-"The server name should only contain letters, unicode, numbers, hyphens, "
-"dashes, and dots."
-msgstr ""
-
 #: src/views/site/cert/components/AutoCertStepOne.vue:45
 #, fuzzy
 msgid ""
@@ -2229,8 +2263,8 @@ msgstr ""
 "Note: The server_name in the current configuration must be the domain name "
 "you need to get the certificate."
 
-#: src/views/preference/BasicSettings.vue:38
-#: src/views/preference/BasicSettings.vue:50
+#: src/views/preference/BasicSettings.vue:33
+#: src/views/preference/CertSettings.vue:19
 #, fuzzy
 msgid "The url is invalid"
 msgstr "유효한 URL이 아닙니다"
@@ -2268,7 +2302,11 @@ msgid ""
 "This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:67
+#: src/views/preference/AuthSettings.vue:98
+msgid "Throttle"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:118
 #: src/views/preference/components/AddPasskey.vue:71
 #: src/views/preference/LogrotateSettings.vue:11
 msgid "Tips"
@@ -2312,7 +2350,7 @@ msgstr ""
 msgid "Token is not valid"
 msgstr "토큰이 유효하지 않습니다"
 
-#: src/views/other/Login.vue:82
+#: src/views/other/Login.vue:80
 msgid "Too many login failed attempts, please try again later"
 msgstr ""
 
@@ -2330,7 +2368,7 @@ msgstr ""
 msgid "Trash"
 msgstr ""
 
-#: src/components/TwoFA/use2FAModal.ts:71
+#: src/components/TwoFA/use2FAModal.ts:66
 msgid "Two-factor authentication required"
 msgstr ""
 
@@ -2405,11 +2443,11 @@ msgstr ""
 msgid "User"
 msgstr "사용자 이름"
 
-#: src/views/other/Login.vue:85
+#: src/views/other/Login.vue:83
 msgid "User is banned"
 msgstr ""
 
-#: src/views/other/Login.vue:198 src/views/user/userColumns.tsx:9
+#: src/views/other/Login.vue:196 src/views/user/userColumns.tsx:9
 msgid "Username"
 msgstr "사용자 이름"
 
@@ -2471,6 +2509,10 @@ msgstr ""
 "이 파일에서 HTTPChallenge 구성을 제거하고 Nginx를 다시 로드할 예정입니다. 계"
 "속하시겠습니까?"
 
+#: src/views/preference/AuthSettings.vue:71
+msgid "Webauthn"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:78
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "
@@ -2491,8 +2533,8 @@ msgstr "인증서 개인 키를 디스크에 쓰기"
 msgid "Writing certificate to disk"
 msgstr "인증서를 디스크에 쓰기"
 
-#: src/views/preference/AuthSettings.vue:103
-#: src/views/preference/BasicSettings.vue:100
+#: src/views/preference/AuthSettings.vue:137
+#: src/views/preference/CertSettings.vue:69
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/site/ngx_conf/LocationEditor.vue:89
 msgid "Yes"
@@ -2516,6 +2558,14 @@ msgstr ""
 msgid "Your passkeys"
 msgstr ""
 
+#, fuzzy
+#~ msgid "File not found"
+#~ msgstr "파일을 찾을 수 없음"
+
+#, fuzzy
+#~ msgid "Server Name"
+#~ msgstr "Server Info"
+
 #, fuzzy
 #~ msgid "Enable 2FA"
 #~ msgstr "활성화"
@@ -2528,9 +2578,6 @@ msgstr ""
 #~ msgid "Rename "
 #~ msgstr "이름 변경"
 
-#~ msgid "Auto Cert"
-#~ msgstr "자동 인증"
-
 #~ msgid "Certificate has expired"
 #~ msgstr "인증서가 만료되었습니다"
 

+ 118 - 79
app/src/language/messages.pot

@@ -6,7 +6,7 @@ msgstr ""
 msgid "2FA"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:58
+#: src/views/preference/AuthSettings.vue:57
 msgid "2FA Settings"
 msgstr ""
 
@@ -31,7 +31,7 @@ msgstr ""
 #: src/views/config/configColumns.ts:38
 #: src/views/environment/envColumns.tsx:131
 #: src/views/notification/notificationColumns.tsx:54
-#: src/views/preference/AuthSettings.vue:27
+#: src/views/preference/AuthSettings.vue:26
 #: src/views/site/SiteList.vue:54
 #: src/views/stream/StreamList.vue:47
 #: src/views/user/userColumns.tsx:60
@@ -40,7 +40,7 @@ msgstr ""
 
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:183
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:204
-#: src/views/preference/BasicSettings.vue:73
+#: src/views/preference/CertSettings.vue:42
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:162
 #: src/views/site/ngx_conf/NgxUpstream.vue:152
@@ -114,7 +114,7 @@ msgstr ""
 msgid "Arch"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:102
+#: src/views/preference/AuthSettings.vue:136
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr ""
 
@@ -152,7 +152,7 @@ msgstr ""
 msgid "Are you sure you want to remove this directive?"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:99
+#: src/views/preference/CertSettings.vue:68
 msgid "Are you sure you want to remove this item?"
 msgstr ""
 
@@ -168,11 +168,11 @@ msgstr ""
 msgid "Assistant"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:18
+#: src/views/preference/AuthSettings.vue:17
 msgid "Attempts"
 msgstr ""
 
-#: src/views/preference/Preference.vue:122
+#: src/views/preference/Preference.vue:153
 msgid "Auth"
 msgstr ""
 
@@ -180,7 +180,7 @@ msgstr ""
 msgid "Authenticate with a passkey"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:63
+#: src/views/preference/AuthSettings.vue:62
 msgid "Authentication Settings"
 msgstr ""
 
@@ -219,15 +219,15 @@ msgstr ""
 msgid "Back to list"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:76
+#: src/views/preference/AuthSettings.vue:103
 msgid "Ban Threshold Minutes"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:90
+#: src/views/preference/AuthSettings.vue:124
 msgid "Banned IPs"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:21
+#: src/views/preference/AuthSettings.vue:20
 msgid "Banned Until"
 msgstr ""
 
@@ -236,7 +236,7 @@ msgid "Base information"
 msgstr ""
 
 #: src/views/config/ConfigEditor.vue:241
-#: src/views/preference/Preference.vue:116
+#: src/views/preference/Preference.vue:147
 #: src/views/site/components/RightSettings.vue:75
 #: src/views/stream/components/RightSettings.vue:74
 msgid "Basic"
@@ -264,7 +264,7 @@ msgstr ""
 msgid "CA Dir"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:47
+#: src/views/preference/CertSettings.vue:16
 msgid "CADir"
 msgstr ""
 
@@ -288,7 +288,11 @@ msgstr ""
 msgid "Cancel"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:55
+#: src/views/preference/Preference.vue:159
+msgid "Cert"
+msgstr ""
+
+#: src/views/preference/CertSettings.vue:24
 msgid "Certificate Renewal Interval"
 msgstr ""
 
@@ -472,8 +476,8 @@ msgstr ""
 msgid "Custom"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:121
-msgid "Customize the name of local server to be displayed in the environment indicator."
+#: src/views/preference/BasicSettings.vue:46
+msgid "Customize the name of local node to be displayed in the environment indicator."
 msgstr ""
 
 #: src/routes/index.ts:39
@@ -487,7 +491,7 @@ msgstr ""
 msgid "Database (Optional, default: database)"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:60
+#: src/views/preference/CertSettings.vue:29
 msgid "Days"
 msgstr ""
 
@@ -879,11 +883,6 @@ msgstr ""
 msgid "File exists"
 msgstr ""
 
-#: src/views/preference/NginxSettings.vue:14
-#: src/views/preference/NginxSettings.vue:23
-msgid "File not found"
-msgstr ""
-
 #: src/views/other/Error.vue:9
 msgid "File Not Found"
 msgstr ""
@@ -901,7 +900,7 @@ msgstr ""
 msgid "Follow the instructions in the dialog to complete the passkey registration process."
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:43
+#: src/views/preference/BasicSettings.vue:38
 msgid "For Chinese user: https://mirror.ghproxy.com/"
 msgstr ""
 
@@ -938,7 +937,7 @@ msgstr ""
 msgid "Getting the certificate, please wait..."
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:35
+#: src/views/preference/BasicSettings.vue:30
 msgid "Github Proxy"
 msgstr ""
 
@@ -950,15 +949,15 @@ msgstr ""
 msgid "Home"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:31
+#: src/views/preference/CertSettings.vue:12
 msgid "HTTP Challenge Port"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:13
+#: src/views/preference/BasicSettings.vue:11
 msgid "HTTP Host"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:16
+#: src/views/preference/BasicSettings.vue:14
 msgid "HTTP Port"
 msgstr ""
 
@@ -970,7 +969,7 @@ msgstr ""
 msgid "If left blank, the default CA Dir will be used."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:119
 msgid "If the number of login failed attempts from a ip reach the max attempts in ban threshold minutes, the ip will be banned for a period of time."
 msgstr ""
 
@@ -995,7 +994,7 @@ msgstr ""
 msgid "Import Certificate"
 msgstr ""
 
-#: src/views/other/Login.vue:79
+#: src/views/other/Login.vue:77
 msgid "Incorrect username or password"
 msgstr ""
 
@@ -1038,7 +1037,7 @@ msgstr ""
 msgid "Invalid"
 msgstr ""
 
-#: src/views/other/Login.vue:89
+#: src/views/other/Login.vue:87
 msgid "Invalid 2FA or recovery code"
 msgstr ""
 
@@ -1051,11 +1050,11 @@ msgstr ""
 msgid "Invalid folder name"
 msgstr ""
 
-#: src/components/TwoFA/use2FAModal.ts:65
+#: src/components/TwoFA/use2FAModal.ts:60
 msgid "Invalid passcode or recovery code"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:15
+#: src/views/preference/AuthSettings.vue:14
 msgid "IP"
 msgstr ""
 
@@ -1075,7 +1074,7 @@ msgstr ""
 msgid "Issuer: %{issuer}"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:22
+#: src/views/preference/BasicSettings.vue:20
 msgid "Jwt Secret"
 msgstr ""
 
@@ -1156,12 +1155,12 @@ msgid "Log"
 msgstr ""
 
 #: src/routes/index.ts:305
-#: src/views/other/Login.vue:247
+#: src/views/other/Login.vue:245
 msgid "Login"
 msgstr ""
 
-#: src/views/other/Login.vue:133
-#: src/views/other/Login.vue:66
+#: src/views/other/Login.vue:131
+#: src/views/other/Login.vue:64
 msgid "Login successful"
 msgstr ""
 
@@ -1169,7 +1168,7 @@ msgstr ""
 msgid "Logout successful"
 msgstr ""
 
-#: src/views/preference/Preference.vue:140
+#: src/views/preference/Preference.vue:177
 msgid "Logrotate"
 msgstr ""
 
@@ -1207,7 +1206,7 @@ msgstr ""
 msgid "Managed Certificate"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:109
 msgid "Max Attempts"
 msgstr ""
 
@@ -1306,11 +1305,11 @@ msgstr ""
 msgid "Next"
 msgstr ""
 
-#: src/views/preference/Preference.vue:128
+#: src/views/preference/Preference.vue:165
 msgid "Nginx"
 msgstr ""
 
-#: src/views/preference/NginxSettings.vue:11
+#: src/views/preference/NginxSettings.vue:9
 msgid "Nginx Access Log Path"
 msgstr ""
 
@@ -1319,11 +1318,15 @@ msgstr ""
 msgid "Nginx Configuration Parse Error"
 msgstr ""
 
+#: src/views/preference/NginxSettings.vue:15
+msgid "Nginx Configurations Directory"
+msgstr ""
+
 #: src/components/NginxControl/NginxControl.vue:68
 msgid "Nginx Control"
 msgstr ""
 
-#: src/views/preference/NginxSettings.vue:20
+#: src/views/preference/NginxSettings.vue:12
 msgid "Nginx Error Log Path"
 msgstr ""
 
@@ -1336,10 +1339,26 @@ msgstr ""
 msgid "Nginx Log"
 msgstr ""
 
+#: src/views/preference/NginxSettings.vue:18
+msgid "Nginx Log Directory Whitelist"
+msgstr ""
+
+#: src/views/preference/NginxSettings.vue:27
+msgid "Nginx PID Path"
+msgstr ""
+
+#: src/views/preference/NginxSettings.vue:30
+msgid "Nginx Reload Command"
+msgstr ""
+
 #: src/components/NginxControl/NginxControl.vue:26
 msgid "Nginx reloaded successfully"
 msgstr ""
 
+#: src/views/preference/NginxSettings.vue:33
+msgid "Nginx Restart Command"
+msgstr ""
+
 #: src/components/NginxControl/NginxControl.vue:42
 msgid "Nginx restarted successfully"
 msgstr ""
@@ -1350,8 +1369,8 @@ msgstr ""
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:561
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:575
 #: src/views/notification/Notification.vue:38
-#: src/views/preference/AuthSettings.vue:104
-#: src/views/preference/BasicSettings.vue:101
+#: src/views/preference/AuthSettings.vue:138
+#: src/views/preference/CertSettings.vue:70
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/site/ngx_conf/LocationEditor.vue:90
 #: src/views/site/SiteList.vue:151
@@ -1359,7 +1378,11 @@ msgstr ""
 msgid "No"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:25
+#: src/views/preference/BasicSettings.vue:42
+msgid "Node name"
+msgstr ""
+
+#: src/views/preference/BasicSettings.vue:23
 msgid "Node Secret"
 msgstr ""
 
@@ -1447,12 +1470,12 @@ msgstr ""
 msgid "Online"
 msgstr ""
 
-#: src/views/preference/Preference.vue:134
+#: src/views/preference/Preference.vue:171
 msgid "OpenAI"
 msgstr ""
 
 #: src/components/TwoFA/Authorization.vue:117
-#: src/views/other/Login.vue:256
+#: src/views/other/Login.vue:254
 msgid "Or"
 msgstr ""
 
@@ -1492,7 +1515,7 @@ msgstr ""
 msgid "Passkeys are webauthn credentials that validate your identity using touch, facial recognition, a device password, or a PIN. They can be used as a password replacement or as a 2FA method."
 msgstr ""
 
-#: src/views/other/Login.vue:208
+#: src/views/other/Login.vue:206
 #: src/views/user/userColumns.tsx:18
 msgid "Password"
 msgstr ""
@@ -1558,12 +1581,12 @@ msgid "Please input your E-mail!"
 msgstr ""
 
 #: src/views/other/Install.vue:44
-#: src/views/other/Login.vue:47
+#: src/views/other/Login.vue:46
 msgid "Please input your password!"
 msgstr ""
 
 #: src/views/other/Install.vue:38
-#: src/views/other/Login.vue:41
+#: src/views/other/Login.vue:40
 msgid "Please input your username!"
 msgstr ""
 
@@ -1588,7 +1611,7 @@ msgid "Pre-release"
 msgstr ""
 
 #: src/routes/index.ts:260
-#: src/views/preference/Preference.vue:111
+#: src/views/preference/Preference.vue:142
 msgid "Preference"
 msgstr ""
 
@@ -1647,7 +1670,7 @@ msgstr ""
 msgid "Recovery Code:"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:68
+#: src/views/preference/CertSettings.vue:37
 msgid "Recursive Nameservers"
 msgstr ""
 
@@ -1708,11 +1731,11 @@ msgstr ""
 msgid "Reloading nginx"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:109
+#: src/views/preference/AuthSettings.vue:143
 msgid "Remove"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:48
+#: src/views/preference/AuthSettings.vue:47
 #: src/views/preference/components/Passkey.vue:50
 msgid "Remove successfully"
 msgstr ""
@@ -1789,7 +1812,19 @@ msgstr ""
 msgid "Restarting"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:19
+#: src/views/preference/AuthSettings.vue:81
+msgid "RP Display Name"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:87
+msgid "RP Origins"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:75
+msgid "RPID"
+msgstr ""
+
+#: src/views/preference/BasicSettings.vue:17
 msgid "Run Mode"
 msgstr ""
 
@@ -1801,7 +1836,7 @@ msgstr ""
 #: src/views/certificate/CertificateEditor.vue:256
 #: src/views/config/ConfigEditor.vue:222
 #: src/views/preference/components/Passkey.vue:136
-#: src/views/preference/Preference.vue:151
+#: src/views/preference/Preference.vue:188
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:120
 #: src/views/site/SiteEdit.vue:260
 #: src/views/stream/StreamEdit.vue:252
@@ -1821,7 +1856,7 @@ msgstr ""
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:122
 #: src/views/certificate/CertificateEditor.vue:46
-#: src/views/preference/Preference.vue:79
+#: src/views/preference/Preference.vue:110
 msgid "Save successfully"
 msgstr ""
 
@@ -1867,13 +1902,13 @@ msgstr ""
 #: src/views/environment/BatchUpgrader.vue:59
 #: src/views/environment/Environment.vue:15
 #: src/views/other/Install.vue:68
-#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/AuthSettings.vue:49
 #: src/views/preference/components/Passkey.vue:26
 #: src/views/preference/components/Passkey.vue:43
 #: src/views/preference/components/Passkey.vue:56
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:58
-#: src/views/preference/Preference.vue:83
+#: src/views/preference/Preference.vue:114
 #: src/views/site/SiteList.vue:88
 #: src/views/stream/StreamList.vue:113
 #: src/views/stream/StreamList.vue:81
@@ -1885,10 +1920,6 @@ msgstr ""
 msgid "Server Info"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:117
-msgid "Server Name"
-msgstr ""
-
 #: src/views/site/cert/components/ObtainCert.vue:102
 msgid "server_name not found in directives"
 msgstr ""
@@ -1897,7 +1928,7 @@ msgstr ""
 msgid "server_name parameter is required"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:64
+#: src/views/preference/CertSettings.vue:33
 msgid "Set the recursive nameservers to override the systems nameservers for the step of DNS challenge."
 msgstr ""
 
@@ -1917,7 +1948,7 @@ msgstr ""
 msgid "Show"
 msgstr ""
 
-#: src/views/other/Login.vue:265
+#: src/views/other/Login.vue:263
 msgid "Sign in with a passkey"
 msgstr ""
 
@@ -1949,7 +1980,7 @@ msgstr ""
 msgid "SSL Certificate Path"
 msgstr ""
 
-#: src/views/other/Login.vue:223
+#: src/views/other/Login.vue:221
 msgid "SSO Login"
 msgstr ""
 
@@ -2065,7 +2096,7 @@ msgstr ""
 msgid "Terminal"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:28
+#: src/views/preference/BasicSettings.vue:26
 msgid "Terminal Start Command"
 msgstr ""
 
@@ -2089,6 +2120,10 @@ msgstr ""
 msgid "The model name should only contain letters, unicode, numbers, hyphens, dashes, and dots."
 msgstr ""
 
+#: src/views/preference/BasicSettings.vue:45
+msgid "The node name should only contain letters, unicode, numbers, hyphens, dashes, and dots."
+msgstr ""
+
 #: src/views/certificate/CertificateEditor.vue:173
 msgid "The path exists, but the file is not a certificate"
 msgstr ""
@@ -2105,16 +2140,12 @@ msgstr ""
 msgid "The remote Nginx UI version is not compatible with the local Nginx UI version. To avoid potential errors, please upgrade the remote Nginx UI to match the local version."
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:120
-msgid "The server name should only contain letters, unicode, numbers, hyphens, dashes, and dots."
-msgstr ""
-
 #: src/views/site/cert/components/AutoCertStepOne.vue:45
 msgid "The server_name in the current configuration must be the domain name you need to get the certificate, supportmultiple domains."
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:38
-#: src/views/preference/BasicSettings.vue:50
+#: src/views/preference/BasicSettings.vue:33
+#: src/views/preference/CertSettings.vue:19
 msgid "The url is invalid"
 msgstr ""
 
@@ -2149,7 +2180,11 @@ msgstr ""
 msgid "This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:67
+#: src/views/preference/AuthSettings.vue:98
+msgid "Throttle"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:118
 #: src/views/preference/components/AddPasskey.vue:71
 #: src/views/preference/LogrotateSettings.vue:11
 msgid "Tips"
@@ -2179,7 +2214,7 @@ msgstr ""
 msgid "Token is not valid"
 msgstr ""
 
-#: src/views/other/Login.vue:82
+#: src/views/other/Login.vue:80
 msgid "Too many login failed attempts, please try again later"
 msgstr ""
 
@@ -2195,7 +2230,7 @@ msgstr ""
 msgid "Trash"
 msgstr ""
 
-#: src/components/TwoFA/use2FAModal.ts:71
+#: src/components/TwoFA/use2FAModal.ts:66
 msgid "Two-factor authentication required"
 msgstr ""
 
@@ -2270,11 +2305,11 @@ msgstr ""
 msgid "User"
 msgstr ""
 
-#: src/views/other/Login.vue:85
+#: src/views/other/Login.vue:83
 msgid "User is banned"
 msgstr ""
 
-#: src/views/other/Login.vue:198
+#: src/views/other/Login.vue:196
 #: src/views/user/userColumns.tsx:9
 msgid "Username"
 msgstr ""
@@ -2326,6 +2361,10 @@ msgstr ""
 msgid "We will remove the HTTPChallenge configuration from this file and reload the Nginx. Are you sure you want to continue?"
 msgstr ""
 
+#: src/views/preference/AuthSettings.vue:71
+msgid "Webauthn"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:78
 msgid "When Enabled, Nginx UI will automatically re-register users upon startup. Generally, do not enable this unless you are in a dev environment and using Pebble as CA."
 msgstr ""
@@ -2343,8 +2382,8 @@ msgstr ""
 msgid "Writing certificate to disk"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:103
-#: src/views/preference/BasicSettings.vue:100
+#: src/views/preference/AuthSettings.vue:137
+#: src/views/preference/CertSettings.vue:69
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/site/ngx_conf/LocationEditor.vue:89
 msgid "Yes"

+ 141 - 85
app/src/language/ru_RU/app.po

@@ -18,7 +18,7 @@ msgstr ""
 msgid "2FA"
 msgstr "2ФА"
 
-#: src/views/preference/AuthSettings.vue:58
+#: src/views/preference/AuthSettings.vue:57
 msgid "2FA Settings"
 msgstr "Настройки 2ФА"
 
@@ -41,14 +41,14 @@ msgstr "Пользователь ACME"
 #: src/views/config/configColumns.ts:38
 #: src/views/environment/envColumns.tsx:131
 #: src/views/notification/notificationColumns.tsx:54
-#: src/views/preference/AuthSettings.vue:27 src/views/site/SiteList.vue:54
+#: src/views/preference/AuthSettings.vue:26 src/views/site/SiteList.vue:54
 #: src/views/stream/StreamList.vue:47 src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Действие"
 
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:183
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:204
-#: src/views/preference/BasicSettings.vue:73
+#: src/views/preference/CertSettings.vue:42
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:162
 #: src/views/site/ngx_conf/NgxUpstream.vue:152
@@ -119,7 +119,7 @@ msgstr "API токен"
 msgid "Arch"
 msgstr "Архитектура"
 
-#: src/views/preference/AuthSettings.vue:102
+#: src/views/preference/AuthSettings.vue:136
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr "Вы уверены, что хотите немедленно удалить этот заблокированный IP?"
 
@@ -158,7 +158,7 @@ msgstr "Вы уверены, что хотите восстановить это
 msgid "Are you sure you want to remove this directive?"
 msgstr "Вы уверены, что хотите удалить эту директиву?"
 
-#: src/views/preference/BasicSettings.vue:99
+#: src/views/preference/CertSettings.vue:68
 msgid "Are you sure you want to remove this item?"
 msgstr "Вы уверены, что хотите удалить этот элемент?"
 
@@ -175,11 +175,11 @@ msgstr "Обратитесь за помощью к ChatGPT"
 msgid "Assistant"
 msgstr "Ассистент"
 
-#: src/views/preference/AuthSettings.vue:18
+#: src/views/preference/AuthSettings.vue:17
 msgid "Attempts"
 msgstr "Попытки"
 
-#: src/views/preference/Preference.vue:122
+#: src/views/preference/Preference.vue:153
 msgid "Auth"
 msgstr "Авторизация"
 
@@ -187,7 +187,7 @@ msgstr "Авторизация"
 msgid "Authenticate with a passkey"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:63
+#: src/views/preference/AuthSettings.vue:62
 msgid "Authentication Settings"
 msgstr ""
 
@@ -223,15 +223,15 @@ msgstr "Вернуться на главную"
 msgid "Back to list"
 msgstr "Возврат к списку"
 
-#: src/views/preference/AuthSettings.vue:76
+#: src/views/preference/AuthSettings.vue:103
 msgid "Ban Threshold Minutes"
 msgstr "Порог блокировки в минутах"
 
-#: src/views/preference/AuthSettings.vue:90
+#: src/views/preference/AuthSettings.vue:124
 msgid "Banned IPs"
 msgstr "Заблокированные IP-адреса"
 
-#: src/views/preference/AuthSettings.vue:21
+#: src/views/preference/AuthSettings.vue:20
 msgid "Banned Until"
 msgstr "Заблокирован до"
 
@@ -240,7 +240,7 @@ msgid "Base information"
 msgstr "Основная информация"
 
 #: src/views/config/ConfigEditor.vue:241
-#: src/views/preference/Preference.vue:116
+#: src/views/preference/Preference.vue:147
 #: src/views/site/components/RightSettings.vue:75
 #: src/views/stream/components/RightSettings.vue:74
 #, fuzzy
@@ -268,7 +268,7 @@ msgstr "Собрать с"
 msgid "CA Dir"
 msgstr "Директория корневого сертификата"
 
-#: src/views/preference/BasicSettings.vue:47
+#: src/views/preference/CertSettings.vue:16
 msgid "CADir"
 msgstr ""
 
@@ -292,7 +292,12 @@ msgstr ""
 msgid "Cancel"
 msgstr "Отмена"
 
-#: src/views/preference/BasicSettings.vue:55
+#: src/views/preference/Preference.vue:159
+#, fuzzy
+msgid "Cert"
+msgstr "Авто Сертификат"
+
+#: src/views/preference/CertSettings.vue:24
 msgid "Certificate Renewal Interval"
 msgstr "Интервал обновления сертификата"
 
@@ -477,9 +482,10 @@ msgstr "Текущяя версия"
 msgid "Custom"
 msgstr "Пользовательский"
 
-#: src/views/preference/BasicSettings.vue:121
+#: src/views/preference/BasicSettings.vue:46
+#, fuzzy
 msgid ""
-"Customize the name of local server to be displayed in the environment "
+"Customize the name of local node to be displayed in the environment "
 "indicator."
 msgstr "Настройте имя локального сервера для отображения в индикаторе среды."
 
@@ -492,7 +498,7 @@ msgstr "Доска"
 msgid "Database (Optional, default: database)"
 msgstr "База данных (Опционально, по умолчанию: database)"
 
-#: src/views/preference/BasicSettings.vue:60
+#: src/views/preference/CertSettings.vue:29
 msgid "Days"
 msgstr "Дни"
 
@@ -874,11 +880,6 @@ msgstr "Файл"
 msgid "File exists"
 msgstr "Файл существует"
 
-#: src/views/preference/NginxSettings.vue:14
-#: src/views/preference/NginxSettings.vue:23
-msgid "File not found"
-msgstr "Файл не найден"
-
 #: src/views/other/Error.vue:9
 msgid "File Not Found"
 msgstr "Файл не найден"
@@ -897,7 +898,7 @@ msgid ""
 "process."
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:43
+#: src/views/preference/BasicSettings.vue:38
 msgid "For Chinese user: https://mirror.ghproxy.com/"
 msgstr "Для китайских пользователей: https://mirror.ghproxy.com/"
 
@@ -933,7 +934,7 @@ msgstr "Ошибка получения информации о выпуске"
 msgid "Getting the certificate, please wait..."
 msgstr "Получение сертификата, пожалуйста, подождите..."
 
-#: src/views/preference/BasicSettings.vue:35
+#: src/views/preference/BasicSettings.vue:30
 msgid "Github Proxy"
 msgstr "Прокси Github"
 
@@ -945,15 +946,15 @@ msgstr "Скрыть"
 msgid "Home"
 msgstr "Главная"
 
-#: src/views/preference/BasicSettings.vue:31
+#: src/views/preference/CertSettings.vue:12
 msgid "HTTP Challenge Port"
 msgstr "Порт HTTP Challenge"
 
-#: src/views/preference/BasicSettings.vue:13
+#: src/views/preference/BasicSettings.vue:11
 msgid "HTTP Host"
 msgstr "Хостинг HTTP"
 
-#: src/views/preference/BasicSettings.vue:16
+#: src/views/preference/BasicSettings.vue:14
 msgid "HTTP Port"
 msgstr "Порт HTTP"
 
@@ -965,7 +966,7 @@ msgstr "HTTP01"
 msgid "If left blank, the default CA Dir will be used."
 msgstr "Если оставить пустым, будет использоваться каталог CA по умолчанию."
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:119
 msgid ""
 "If the number of login failed attempts from a ip reach the max attempts in "
 "ban threshold minutes, the ip will be banned for a period of time."
@@ -1002,7 +1003,7 @@ msgstr "Импорт"
 msgid "Import Certificate"
 msgstr "Импортировать сертификат"
 
-#: src/views/other/Login.vue:79
+#: src/views/other/Login.vue:77
 msgid "Incorrect username or password"
 msgstr "Неверное имя пользователя или пароль"
 
@@ -1043,7 +1044,7 @@ msgstr "Интервал"
 msgid "Invalid"
 msgstr "Недействительно"
 
-#: src/views/other/Login.vue:89
+#: src/views/other/Login.vue:87
 msgid "Invalid 2FA or recovery code"
 msgstr "Неверный 2FA или код восстановления"
 
@@ -1056,11 +1057,11 @@ msgstr "Неверное имя файла"
 msgid "Invalid folder name"
 msgstr "Недопустимое имя папки"
 
-#: src/components/TwoFA/use2FAModal.ts:65
+#: src/components/TwoFA/use2FAModal.ts:60
 msgid "Invalid passcode or recovery code"
 msgstr "Неверный пароль или код восстановления"
 
-#: src/views/preference/AuthSettings.vue:15
+#: src/views/preference/AuthSettings.vue:14
 msgid "IP"
 msgstr "IP"
 
@@ -1080,7 +1081,7 @@ msgstr "Сертификат успешно выдан"
 msgid "Issuer: %{issuer}"
 msgstr "Издатель: %{issuer}"
 
-#: src/views/preference/BasicSettings.vue:22
+#: src/views/preference/BasicSettings.vue:20
 msgid "Jwt Secret"
 msgstr "Jwt секрет"
 
@@ -1162,11 +1163,11 @@ msgstr "Locations"
 msgid "Log"
 msgstr "Журнал"
 
-#: src/routes/index.ts:305 src/views/other/Login.vue:247
+#: src/routes/index.ts:305 src/views/other/Login.vue:245
 msgid "Login"
 msgstr "Логин"
 
-#: src/views/other/Login.vue:133 src/views/other/Login.vue:66
+#: src/views/other/Login.vue:131 src/views/other/Login.vue:64
 msgid "Login successful"
 msgstr "Авторизация успешна"
 
@@ -1174,7 +1175,7 @@ msgstr "Авторизация успешна"
 msgid "Logout successful"
 msgstr "Выход выполнен успешно"
 
-#: src/views/preference/Preference.vue:140
+#: src/views/preference/Preference.vue:177
 msgid "Logrotate"
 msgstr "Прокрутка"
 
@@ -1223,7 +1224,7 @@ msgstr "Пользователи"
 msgid "Managed Certificate"
 msgstr "Управление сертификатом"
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:109
 msgid "Max Attempts"
 msgstr "Максимальное количество попыток"
 
@@ -1317,11 +1318,11 @@ msgstr "Вышла новая версия"
 msgid "Next"
 msgstr "Дальше"
 
-#: src/views/preference/Preference.vue:128
+#: src/views/preference/Preference.vue:165
 msgid "Nginx"
 msgstr "Nginx"
 
-#: src/views/preference/NginxSettings.vue:11
+#: src/views/preference/NginxSettings.vue:9
 msgid "Nginx Access Log Path"
 msgstr "Путь для Nginx Access Log"
 
@@ -1329,11 +1330,16 @@ msgstr "Путь для Nginx Access Log"
 msgid "Nginx Configuration Parse Error"
 msgstr "Ошибка разбора конфигурации Nginx"
 
+#: src/views/preference/NginxSettings.vue:15
+#, fuzzy
+msgid "Nginx Configurations Directory"
+msgstr "Ошибка разбора конфигурации Nginx"
+
 #: src/components/NginxControl/NginxControl.vue:68
 msgid "Nginx Control"
 msgstr "Управление Nginx"
 
-#: src/views/preference/NginxSettings.vue:20
+#: src/views/preference/NginxSettings.vue:12
 msgid "Nginx Error Log Path"
 msgstr "Путь для Nginx Error Log"
 
@@ -1345,10 +1351,28 @@ msgstr ""
 msgid "Nginx Log"
 msgstr "Журнал"
 
+#: src/views/preference/NginxSettings.vue:18
+msgid "Nginx Log Directory Whitelist"
+msgstr ""
+
+#: src/views/preference/NginxSettings.vue:27
+#, fuzzy
+msgid "Nginx PID Path"
+msgstr "Путь для Nginx Error Log"
+
+#: src/views/preference/NginxSettings.vue:30
+msgid "Nginx Reload Command"
+msgstr ""
+
 #: src/components/NginxControl/NginxControl.vue:26
 msgid "Nginx reloaded successfully"
 msgstr "Nginx успешно перезагружен"
 
+#: src/views/preference/NginxSettings.vue:33
+#, fuzzy
+msgid "Nginx Restart Command"
+msgstr "Терминальная команда запуска"
+
 #: src/components/NginxControl/NginxControl.vue:42
 msgid "Nginx restarted successfully"
 msgstr "Nginx успешно перезапущен"
@@ -1359,15 +1383,20 @@ msgstr "Nginx успешно перезапущен"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:561
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:575
 #: src/views/notification/Notification.vue:38
-#: src/views/preference/AuthSettings.vue:104
-#: src/views/preference/BasicSettings.vue:101
+#: src/views/preference/AuthSettings.vue:138
+#: src/views/preference/CertSettings.vue:70
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/site/ngx_conf/LocationEditor.vue:90
 #: src/views/site/SiteList.vue:151 src/views/stream/StreamList.vue:165
 msgid "No"
 msgstr "Нет"
 
-#: src/views/preference/BasicSettings.vue:25
+#: src/views/preference/BasicSettings.vue:42
+#, fuzzy
+msgid "Node name"
+msgstr "Новое имя"
+
+#: src/views/preference/BasicSettings.vue:23
 msgid "Node Secret"
 msgstr ""
 
@@ -1457,11 +1486,11 @@ msgstr "После завершения проверки записи будут
 msgid "Online"
 msgstr "Онлайн"
 
-#: src/views/preference/Preference.vue:134
+#: src/views/preference/Preference.vue:171
 msgid "OpenAI"
 msgstr "OpenAI"
 
-#: src/components/TwoFA/Authorization.vue:117 src/views/other/Login.vue:256
+#: src/components/TwoFA/Authorization.vue:117 src/views/other/Login.vue:254
 msgid "Or"
 msgstr ""
 
@@ -1504,7 +1533,7 @@ msgid ""
 "password replacement or as a 2FA method."
 msgstr ""
 
-#: src/views/other/Login.vue:208 src/views/user/userColumns.tsx:18
+#: src/views/other/Login.vue:206 src/views/user/userColumns.tsx:18
 msgid "Password"
 msgstr "Пароль"
 
@@ -1584,11 +1613,11 @@ msgstr ""
 msgid "Please input your E-mail!"
 msgstr "Введите ваш E-mail!"
 
-#: src/views/other/Install.vue:44 src/views/other/Login.vue:47
+#: src/views/other/Install.vue:44 src/views/other/Login.vue:46
 msgid "Please input your password!"
 msgstr "Введите ваш пароль!"
 
-#: src/views/other/Install.vue:38 src/views/other/Login.vue:41
+#: src/views/other/Install.vue:38 src/views/other/Login.vue:40
 msgid "Please input your username!"
 msgstr "Введите ваше имя пользователя!"
 
@@ -1615,7 +1644,7 @@ msgstr "Пожалуйста, выберите хотя бы один узел!"
 msgid "Pre-release"
 msgstr "Предварительный выпуск"
 
-#: src/routes/index.ts:260 src/views/preference/Preference.vue:111
+#: src/routes/index.ts:260 src/views/preference/Preference.vue:142
 msgid "Preference"
 msgstr "Настройки"
 
@@ -1674,7 +1703,7 @@ msgstr "Код восстановления"
 msgid "Recovery Code:"
 msgstr "Код восстановления:"
 
-#: src/views/preference/BasicSettings.vue:68
+#: src/views/preference/CertSettings.vue:37
 msgid "Recursive Nameservers"
 msgstr "Рекурсивные DNS"
 
@@ -1739,11 +1768,11 @@ msgstr "Перезагружается"
 msgid "Reloading nginx"
 msgstr "Перезагружается nginx"
 
-#: src/views/preference/AuthSettings.vue:109
+#: src/views/preference/AuthSettings.vue:143
 msgid "Remove"
 msgstr "Удалить"
 
-#: src/views/preference/AuthSettings.vue:48
+#: src/views/preference/AuthSettings.vue:47
 #: src/views/preference/components/Passkey.vue:50
 msgid "Remove successfully"
 msgstr "Удалено успешно"
@@ -1827,7 +1856,19 @@ msgstr "Перезапуск"
 msgid "Restarting"
 msgstr "Перезапускается"
 
-#: src/views/preference/BasicSettings.vue:19
+#: src/views/preference/AuthSettings.vue:81
+msgid "RP Display Name"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:87
+msgid "RP Origins"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:75
+msgid "RPID"
+msgstr ""
+
+#: src/views/preference/BasicSettings.vue:17
 msgid "Run Mode"
 msgstr "Режим работы"
 
@@ -1839,7 +1880,7 @@ msgstr "Выполняется"
 #: src/views/certificate/CertificateEditor.vue:256
 #: src/views/config/ConfigEditor.vue:222
 #: src/views/preference/components/Passkey.vue:136
-#: src/views/preference/Preference.vue:151
+#: src/views/preference/Preference.vue:188
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:120
 #: src/views/site/SiteEdit.vue:260 src/views/stream/StreamEdit.vue:252
 msgid "Save"
@@ -1858,7 +1899,7 @@ msgstr "Ошибка сохранения %{msg}"
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:122
 #: src/views/certificate/CertificateEditor.vue:46
-#: src/views/preference/Preference.vue:79
+#: src/views/preference/Preference.vue:110
 msgid "Save successfully"
 msgstr "Сохранено успешно"
 
@@ -1904,13 +1945,13 @@ msgstr "Отправлено"
 #: src/views/config/ConfigEditor.vue:108
 #: src/views/environment/BatchUpgrader.vue:59
 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:68
-#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/AuthSettings.vue:49
 #: src/views/preference/components/Passkey.vue:26
 #: src/views/preference/components/Passkey.vue:43
 #: src/views/preference/components/Passkey.vue:56
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:58
-#: src/views/preference/Preference.vue:83 src/views/site/SiteList.vue:88
+#: src/views/preference/Preference.vue:114 src/views/site/SiteList.vue:88
 #: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81
 #: src/views/system/Upgrade.vue:42
 msgid "Server error"
@@ -1920,10 +1961,6 @@ msgstr "Ошибка сервера"
 msgid "Server Info"
 msgstr "Информация о сервере"
 
-#: src/views/preference/BasicSettings.vue:117
-msgid "Server Name"
-msgstr "Имя сервера"
-
 #: src/views/site/cert/components/ObtainCert.vue:102
 msgid "server_name not found in directives"
 msgstr "server_name не нашел в директивах"
@@ -1932,7 +1969,7 @@ msgstr "server_name не нашел в директивах"
 msgid "server_name parameter is required"
 msgstr "server_name параметр обязателен"
 
-#: src/views/preference/BasicSettings.vue:64
+#: src/views/preference/CertSettings.vue:33
 msgid ""
 "Set the recursive nameservers to override the systems nameservers for the "
 "step of DNS challenge."
@@ -1956,7 +1993,7 @@ msgstr ""
 msgid "Show"
 msgstr "Показать"
 
-#: src/views/other/Login.vue:265
+#: src/views/other/Login.vue:263
 msgid "Sign in with a passkey"
 msgstr ""
 
@@ -1988,7 +2025,7 @@ msgstr "Путь к ключу SSL-сертификата"
 msgid "SSL Certificate Path"
 msgstr "Путь к SSL сертификату"
 
-#: src/views/other/Login.vue:223
+#: src/views/other/Login.vue:221
 msgid "SSO Login"
 msgstr "SSO Вход"
 
@@ -2113,7 +2150,7 @@ msgstr "Цель"
 msgid "Terminal"
 msgstr "Терминал"
 
-#: src/views/preference/BasicSettings.vue:28
+#: src/views/preference/BasicSettings.vue:26
 msgid "Terminal Start Command"
 msgstr "Терминальная команда запуска"
 
@@ -2147,6 +2184,15 @@ msgstr ""
 "Имя модели должно содержать только буквы, юникод, цифры, дефисы, тире и "
 "точки."
 
+#: src/views/preference/BasicSettings.vue:45
+#, fuzzy
+msgid ""
+"The node name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
+msgstr ""
+"Имя модели должно содержать только буквы, юникод, цифры, дефисы, тире и "
+"точки."
+
 #: src/views/certificate/CertificateEditor.vue:173
 msgid "The path exists, but the file is not a certificate"
 msgstr "Путь существует, но файл не является сертификатом"
@@ -2172,14 +2218,6 @@ msgstr ""
 "избежать потенциальных ошибок, пожалуйста, обновите удаленную версию Nginx "
 "UI до соответствия с локальной версией."
 
-#: src/views/preference/BasicSettings.vue:120
-msgid ""
-"The server name should only contain letters, unicode, numbers, hyphens, "
-"dashes, and dots."
-msgstr ""
-"Имя сервера должно содержать только буквы, юникод, цифры, дефисы, тире и "
-"точки."
-
 #: src/views/site/cert/components/AutoCertStepOne.vue:45
 msgid ""
 "The server_name in the current configuration must be the domain name you "
@@ -2188,8 +2226,8 @@ msgstr ""
 "server_name в текущей конфигурации должен быть доменным именем, для которого "
 "вам нужно получить сертификат, поддержка нескольких доменов."
 
-#: src/views/preference/BasicSettings.vue:38
-#: src/views/preference/BasicSettings.vue:50
+#: src/views/preference/BasicSettings.vue:33
+#: src/views/preference/CertSettings.vue:19
 msgid "The url is invalid"
 msgstr "URL недействителен"
 
@@ -2227,7 +2265,11 @@ msgstr ""
 "Это обновит или переустановит интерфейс Nginx на %{nodeNames} до версии "
 "%{version}."
 
-#: src/views/preference/AuthSettings.vue:67
+#: src/views/preference/AuthSettings.vue:98
+msgid "Throttle"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:118
 #: src/views/preference/components/AddPasskey.vue:71
 #: src/views/preference/LogrotateSettings.vue:11
 msgid "Tips"
@@ -2274,7 +2316,7 @@ msgstr ""
 msgid "Token is not valid"
 msgstr "Токен недействителен"
 
-#: src/views/other/Login.vue:82
+#: src/views/other/Login.vue:80
 msgid "Too many login failed attempts, please try again later"
 msgstr "Слишком много неудачных попыток входа, попробуйте позже"
 
@@ -2294,7 +2336,7 @@ msgstr ""
 msgid "Trash"
 msgstr "Корзина"
 
-#: src/components/TwoFA/use2FAModal.ts:71
+#: src/components/TwoFA/use2FAModal.ts:66
 msgid "Two-factor authentication required"
 msgstr "Требуется двухфакторная аутентификация"
 
@@ -2365,11 +2407,11 @@ msgstr "Использовать код восстановления"
 msgid "User"
 msgstr "Пользователь"
 
-#: src/views/other/Login.vue:85
+#: src/views/other/Login.vue:83
 msgid "User is banned"
 msgstr "Пользователь заблокирован"
 
-#: src/views/other/Login.vue:198 src/views/user/userColumns.tsx:9
+#: src/views/other/Login.vue:196 src/views/user/userColumns.tsx:9
 msgid "Username"
 msgstr "Имя пользователя"
 
@@ -2428,6 +2470,10 @@ msgstr ""
 "Мы удалим конфигурацию HTTPChallenge из этого файла и перезагрузим Nginx. Вы "
 "уверены, что хотите продолжить?"
 
+#: src/views/preference/AuthSettings.vue:71
+msgid "Webauthn"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:78
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "
@@ -2448,8 +2494,8 @@ msgstr "Запись закрытого ключа сертификата на 
 msgid "Writing certificate to disk"
 msgstr "Запись сертификата на диск"
 
-#: src/views/preference/AuthSettings.vue:103
-#: src/views/preference/BasicSettings.vue:100
+#: src/views/preference/AuthSettings.vue:137
+#: src/views/preference/CertSettings.vue:69
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/site/ngx_conf/LocationEditor.vue:89
 msgid "Yes"
@@ -2473,6 +2519,19 @@ msgstr ""
 msgid "Your passkeys"
 msgstr ""
 
+#~ msgid "File not found"
+#~ msgstr "Файл не найден"
+
+#~ msgid "Server Name"
+#~ msgstr "Имя сервера"
+
+#~ msgid ""
+#~ "The server name should only contain letters, unicode, numbers, hyphens, "
+#~ "dashes, and dots."
+#~ msgstr ""
+#~ "Имя сервера должно содержать только буквы, юникод, цифры, дефисы, тире и "
+#~ "точки."
+
 #~ msgid "Enable 2FA"
 #~ msgstr "Включить 2ФА"
 
@@ -2480,9 +2539,6 @@ msgstr ""
 #~ msgid "Rename "
 #~ msgstr "Имя пользователя"
 
-#~ msgid "Auto Cert"
-#~ msgstr "Авто Сертификат"
-
 #~ msgid "Certificate has expired"
 #~ msgstr "Срок действия сертификата истек"
 

File diff suppressed because it is too large
+ 334 - 144
app/src/language/tr_TR/app.po


+ 131 - 85
app/src/language/vi_VN/app.po

@@ -13,7 +13,7 @@ msgstr ""
 msgid "2FA"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:58
+#: src/views/preference/AuthSettings.vue:57
 msgid "2FA Settings"
 msgstr ""
 
@@ -37,14 +37,14 @@ msgstr "Người dùng"
 #: src/views/config/configColumns.ts:38
 #: src/views/environment/envColumns.tsx:131
 #: src/views/notification/notificationColumns.tsx:54
-#: src/views/preference/AuthSettings.vue:27 src/views/site/SiteList.vue:54
+#: src/views/preference/AuthSettings.vue:26 src/views/site/SiteList.vue:54
 #: src/views/stream/StreamList.vue:47 src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "Hành động"
 
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:183
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:204
-#: src/views/preference/BasicSettings.vue:73
+#: src/views/preference/CertSettings.vue:42
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:162
 #: src/views/site/ngx_conf/NgxUpstream.vue:152
@@ -119,7 +119,7 @@ msgstr ""
 msgid "Arch"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:102
+#: src/views/preference/AuthSettings.vue:136
 #, fuzzy
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr "Bạn chắc chắn muốn xóa nó "
@@ -164,7 +164,7 @@ msgstr "Bạn chắc chắn muốn xoá directive này ?"
 msgid "Are you sure you want to remove this directive?"
 msgstr "Bạn chắc chắn muốn xoá directive này ?"
 
-#: src/views/preference/BasicSettings.vue:99
+#: src/views/preference/CertSettings.vue:68
 #, fuzzy
 msgid "Are you sure you want to remove this item?"
 msgstr "Bạn chắc chắn muốn xoá directive này ?"
@@ -182,11 +182,11 @@ msgstr "Hỏi ChatGPT"
 msgid "Assistant"
 msgstr "Trợ lý"
 
-#: src/views/preference/AuthSettings.vue:18
+#: src/views/preference/AuthSettings.vue:17
 msgid "Attempts"
 msgstr ""
 
-#: src/views/preference/Preference.vue:122
+#: src/views/preference/Preference.vue:153
 #, fuzzy
 msgid "Auth"
 msgstr "Tác giả"
@@ -195,7 +195,7 @@ msgstr "Tác giả"
 msgid "Authenticate with a passkey"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:63
+#: src/views/preference/AuthSettings.vue:62
 msgid "Authentication Settings"
 msgstr ""
 
@@ -232,15 +232,15 @@ msgstr "Quay lại"
 msgid "Back to list"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:76
+#: src/views/preference/AuthSettings.vue:103
 msgid "Ban Threshold Minutes"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:90
+#: src/views/preference/AuthSettings.vue:124
 msgid "Banned IPs"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:21
+#: src/views/preference/AuthSettings.vue:20
 msgid "Banned Until"
 msgstr ""
 
@@ -249,7 +249,7 @@ msgid "Base information"
 msgstr "Thông tin"
 
 #: src/views/config/ConfigEditor.vue:241
-#: src/views/preference/Preference.vue:116
+#: src/views/preference/Preference.vue:147
 #: src/views/site/components/RightSettings.vue:75
 #: src/views/stream/components/RightSettings.vue:74
 #, fuzzy
@@ -279,7 +279,7 @@ msgstr "Xây dựng với"
 msgid "CA Dir"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:47
+#: src/views/preference/CertSettings.vue:16
 msgid "CADir"
 msgstr ""
 
@@ -303,7 +303,12 @@ msgstr ""
 msgid "Cancel"
 msgstr "Huỷ"
 
-#: src/views/preference/BasicSettings.vue:55
+#: src/views/preference/Preference.vue:159
+#, fuzzy
+msgid "Cert"
+msgstr "Tự động ký chứng chỉ SSL"
+
+#: src/views/preference/CertSettings.vue:24
 #, fuzzy
 msgid "Certificate Renewal Interval"
 msgstr "Chứng chỉ SSL hợp lệ"
@@ -499,9 +504,9 @@ msgstr "Phiên bản hiện tại"
 msgid "Custom"
 msgstr "Tuỳ chỉnh"
 
-#: src/views/preference/BasicSettings.vue:121
+#: src/views/preference/BasicSettings.vue:46
 msgid ""
-"Customize the name of local server to be displayed in the environment "
+"Customize the name of local node to be displayed in the environment "
 "indicator."
 msgstr ""
 
@@ -514,7 +519,7 @@ msgstr "Bảng điều khiển"
 msgid "Database (Optional, default: database)"
 msgstr "Tên cơ sở dữ liệu (Tuỳ chọn, Mặc định là: database)"
 
-#: src/views/preference/BasicSettings.vue:60
+#: src/views/preference/CertSettings.vue:29
 msgid "Days"
 msgstr ""
 
@@ -920,12 +925,6 @@ msgstr "Tệp tin"
 msgid "File exists"
 msgstr "Tệp tin đã tồn tại"
 
-#: src/views/preference/NginxSettings.vue:14
-#: src/views/preference/NginxSettings.vue:23
-#, fuzzy
-msgid "File not found"
-msgstr "Không tìm thấy tệp tin"
-
 #: src/views/other/Error.vue:9
 msgid "File Not Found"
 msgstr "Không tìm thấy tệp tin"
@@ -944,7 +943,7 @@ msgid ""
 "process."
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:43
+#: src/views/preference/BasicSettings.vue:38
 #, fuzzy
 msgid "For Chinese user: https://mirror.ghproxy.com/"
 msgstr "Người dùng Trung Quốc: https://mirror.ghproxy.com/"
@@ -985,7 +984,7 @@ msgstr "Nhận lỗi thông tin phát hành"
 msgid "Getting the certificate, please wait..."
 msgstr "Đang lấy chứng chỉ, vui lòng đợi..."
 
-#: src/views/preference/BasicSettings.vue:35
+#: src/views/preference/BasicSettings.vue:30
 msgid "Github Proxy"
 msgstr ""
 
@@ -997,15 +996,15 @@ msgstr ""
 msgid "Home"
 msgstr "Trang chủ"
 
-#: src/views/preference/BasicSettings.vue:31
+#: src/views/preference/CertSettings.vue:12
 msgid "HTTP Challenge Port"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:13
+#: src/views/preference/BasicSettings.vue:11
 msgid "HTTP Host"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:16
+#: src/views/preference/BasicSettings.vue:14
 msgid "HTTP Port"
 msgstr ""
 
@@ -1017,7 +1016,7 @@ msgstr ""
 msgid "If left blank, the default CA Dir will be used."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:119
 msgid ""
 "If the number of login failed attempts from a ip reach the max attempts in "
 "ban threshold minutes, the ip will be banned for a period of time."
@@ -1049,7 +1048,7 @@ msgstr "Xuất"
 msgid "Import Certificate"
 msgstr "Chứng chỉ"
 
-#: src/views/other/Login.vue:79
+#: src/views/other/Login.vue:77
 #, fuzzy
 msgid "Incorrect username or password"
 msgstr "Tên người dùng hoặc mật khẩu không chính xác"
@@ -1093,7 +1092,7 @@ msgstr ""
 msgid "Invalid"
 msgstr "Hợp lệ"
 
-#: src/views/other/Login.vue:89
+#: src/views/other/Login.vue:87
 msgid "Invalid 2FA or recovery code"
 msgstr ""
 
@@ -1107,11 +1106,11 @@ msgstr "E-mail không chính xác!"
 msgid "Invalid folder name"
 msgstr ""
 
-#: src/components/TwoFA/use2FAModal.ts:65
+#: src/components/TwoFA/use2FAModal.ts:60
 msgid "Invalid passcode or recovery code"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:15
+#: src/views/preference/AuthSettings.vue:14
 msgid "IP"
 msgstr ""
 
@@ -1134,7 +1133,7 @@ msgstr "Cấp chứng chỉ thành công"
 msgid "Issuer: %{issuer}"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:22
+#: src/views/preference/BasicSettings.vue:20
 msgid "Jwt Secret"
 msgstr ""
 
@@ -1223,11 +1222,11 @@ msgstr "Locations"
 msgid "Log"
 msgstr "Log"
 
-#: src/routes/index.ts:305 src/views/other/Login.vue:247
+#: src/routes/index.ts:305 src/views/other/Login.vue:245
 msgid "Login"
 msgstr "Đăng nhập"
 
-#: src/views/other/Login.vue:133 src/views/other/Login.vue:66
+#: src/views/other/Login.vue:131 src/views/other/Login.vue:64
 msgid "Login successful"
 msgstr "Đăng nhập thành công"
 
@@ -1235,7 +1234,7 @@ msgstr "Đăng nhập thành công"
 msgid "Logout successful"
 msgstr "Đã đăng xuất"
 
-#: src/views/preference/Preference.vue:140
+#: src/views/preference/Preference.vue:177
 msgid "Logrotate"
 msgstr ""
 
@@ -1280,7 +1279,7 @@ msgstr "Người dùng"
 msgid "Managed Certificate"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:109
 msgid "Max Attempts"
 msgstr ""
 
@@ -1381,11 +1380,11 @@ msgstr "Đã có phiên bản mới"
 msgid "Next"
 msgstr "Tiếp theo"
 
-#: src/views/preference/Preference.vue:128
+#: src/views/preference/Preference.vue:165
 msgid "Nginx"
 msgstr ""
 
-#: src/views/preference/NginxSettings.vue:11
+#: src/views/preference/NginxSettings.vue:9
 msgid "Nginx Access Log Path"
 msgstr "Vị trí lưu log truy cập (Access log) của Nginx"
 
@@ -1394,11 +1393,16 @@ msgstr "Vị trí lưu log truy cập (Access log) của Nginx"
 msgid "Nginx Configuration Parse Error"
 msgstr "Lỗi phân tích cú pháp cấu hình Nginx"
 
+#: src/views/preference/NginxSettings.vue:15
+#, fuzzy
+msgid "Nginx Configurations Directory"
+msgstr "Lỗi phân tích cú pháp cấu hình Nginx"
+
 #: src/components/NginxControl/NginxControl.vue:68
 msgid "Nginx Control"
 msgstr ""
 
-#: src/views/preference/NginxSettings.vue:20
+#: src/views/preference/NginxSettings.vue:12
 msgid "Nginx Error Log Path"
 msgstr "Vị trí lưu log lỗi (Error log) của Nginx"
 
@@ -1410,11 +1414,28 @@ msgstr ""
 msgid "Nginx Log"
 msgstr ""
 
+#: src/views/preference/NginxSettings.vue:18
+msgid "Nginx Log Directory Whitelist"
+msgstr ""
+
+#: src/views/preference/NginxSettings.vue:27
+#, fuzzy
+msgid "Nginx PID Path"
+msgstr "Vị trí lưu log lỗi (Error log) của Nginx"
+
+#: src/views/preference/NginxSettings.vue:30
+msgid "Nginx Reload Command"
+msgstr ""
+
 #: src/components/NginxControl/NginxControl.vue:26
 #, fuzzy
 msgid "Nginx reloaded successfully"
 msgstr "Reload Nginx thành công"
 
+#: src/views/preference/NginxSettings.vue:33
+msgid "Nginx Restart Command"
+msgstr ""
+
 #: src/components/NginxControl/NginxControl.vue:42
 #, fuzzy
 msgid "Nginx restarted successfully"
@@ -1426,15 +1447,20 @@ msgstr "Restart Nginx thành công"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:561
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:575
 #: src/views/notification/Notification.vue:38
-#: src/views/preference/AuthSettings.vue:104
-#: src/views/preference/BasicSettings.vue:101
+#: src/views/preference/AuthSettings.vue:138
+#: src/views/preference/CertSettings.vue:70
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/site/ngx_conf/LocationEditor.vue:90
 #: src/views/site/SiteList.vue:151 src/views/stream/StreamList.vue:165
 msgid "No"
 msgstr "Không"
 
-#: src/views/preference/BasicSettings.vue:25
+#: src/views/preference/BasicSettings.vue:42
+#, fuzzy
+msgid "Node name"
+msgstr "Username"
+
+#: src/views/preference/BasicSettings.vue:23
 msgid "Node Secret"
 msgstr ""
 
@@ -1525,11 +1551,11 @@ msgstr "Sau khi quá trình xác minh hoàn tất, bản ghi sẽ bị xóa."
 msgid "Online"
 msgstr "Trực tuyến"
 
-#: src/views/preference/Preference.vue:134
+#: src/views/preference/Preference.vue:171
 msgid "OpenAI"
 msgstr ""
 
-#: src/components/TwoFA/Authorization.vue:117 src/views/other/Login.vue:256
+#: src/components/TwoFA/Authorization.vue:117 src/views/other/Login.vue:254
 msgid "Or"
 msgstr ""
 
@@ -1573,7 +1599,7 @@ msgid ""
 "password replacement or as a 2FA method."
 msgstr ""
 
-#: src/views/other/Login.vue:208 src/views/user/userColumns.tsx:18
+#: src/views/other/Login.vue:206 src/views/user/userColumns.tsx:18
 msgid "Password"
 msgstr "Mật khẩu"
 
@@ -1651,11 +1677,11 @@ msgstr ""
 msgid "Please input your E-mail!"
 msgstr "Vui lòng nhập E-mail của bạn!"
 
-#: src/views/other/Install.vue:44 src/views/other/Login.vue:47
+#: src/views/other/Install.vue:44 src/views/other/Login.vue:46
 msgid "Please input your password!"
 msgstr "Vui lòng nhập mật khẩu!"
 
-#: src/views/other/Install.vue:38 src/views/other/Login.vue:41
+#: src/views/other/Install.vue:38 src/views/other/Login.vue:40
 msgid "Please input your username!"
 msgstr "Vui lòng nhập username!"
 
@@ -1679,7 +1705,7 @@ msgstr ""
 msgid "Pre-release"
 msgstr ""
 
-#: src/routes/index.ts:260 src/views/preference/Preference.vue:111
+#: src/routes/index.ts:260 src/views/preference/Preference.vue:142
 msgid "Preference"
 msgstr "Cài đặt"
 
@@ -1740,7 +1766,7 @@ msgstr ""
 msgid "Recovery Code:"
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:68
+#: src/views/preference/CertSettings.vue:37
 msgid "Recursive Nameservers"
 msgstr ""
 
@@ -1810,11 +1836,11 @@ msgstr "Đang tải lại"
 msgid "Reloading nginx"
 msgstr "Tải lại nginx"
 
-#: src/views/preference/AuthSettings.vue:109
+#: src/views/preference/AuthSettings.vue:143
 msgid "Remove"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:48
+#: src/views/preference/AuthSettings.vue:47
 #: src/views/preference/components/Passkey.vue:50
 #, fuzzy
 msgid "Remove successfully"
@@ -1908,7 +1934,19 @@ msgstr "Khởi động lại"
 msgid "Restarting"
 msgstr "Đang khởi động lại"
 
-#: src/views/preference/BasicSettings.vue:19
+#: src/views/preference/AuthSettings.vue:81
+msgid "RP Display Name"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:87
+msgid "RP Origins"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:75
+msgid "RPID"
+msgstr ""
+
+#: src/views/preference/BasicSettings.vue:17
 #, fuzzy
 msgid "Run Mode"
 msgstr "Run Mode"
@@ -1921,7 +1959,7 @@ msgstr "Running"
 #: src/views/certificate/CertificateEditor.vue:256
 #: src/views/config/ConfigEditor.vue:222
 #: src/views/preference/components/Passkey.vue:136
-#: src/views/preference/Preference.vue:151
+#: src/views/preference/Preference.vue:188
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:120
 #: src/views/site/SiteEdit.vue:260 src/views/stream/StreamEdit.vue:252
 msgid "Save"
@@ -1940,7 +1978,7 @@ msgstr "Đã xảy ra lỗi khi lưu %{msg}"
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:122
 #: src/views/certificate/CertificateEditor.vue:46
-#: src/views/preference/Preference.vue:79
+#: src/views/preference/Preference.vue:110
 #, fuzzy
 msgid "Save successfully"
 msgstr "Lưu thành công"
@@ -1985,13 +2023,13 @@ msgstr "Gửi"
 #: src/views/config/ConfigEditor.vue:108
 #: src/views/environment/BatchUpgrader.vue:59
 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:68
-#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/AuthSettings.vue:49
 #: src/views/preference/components/Passkey.vue:26
 #: src/views/preference/components/Passkey.vue:43
 #: src/views/preference/components/Passkey.vue:56
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:58
-#: src/views/preference/Preference.vue:83 src/views/site/SiteList.vue:88
+#: src/views/preference/Preference.vue:114 src/views/site/SiteList.vue:88
 #: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81
 #: src/views/system/Upgrade.vue:42
 msgid "Server error"
@@ -2001,11 +2039,6 @@ msgstr "Lỗi máy chủ"
 msgid "Server Info"
 msgstr "Thông tin máy chủ"
 
-#: src/views/preference/BasicSettings.vue:117
-#, fuzzy
-msgid "Server Name"
-msgstr "Thông tin máy chủ"
-
 #: src/views/site/cert/components/ObtainCert.vue:102
 msgid "server_name not found in directives"
 msgstr "không tìm thấy server_name trong directives"
@@ -2014,7 +2047,7 @@ msgstr "không tìm thấy server_name trong directives"
 msgid "server_name parameter is required"
 msgstr "Tham số server_name là bắt buộc"
 
-#: src/views/preference/BasicSettings.vue:64
+#: src/views/preference/CertSettings.vue:33
 msgid ""
 "Set the recursive nameservers to override the systems nameservers for the "
 "step of DNS challenge."
@@ -2037,7 +2070,7 @@ msgstr "Sử dụng HTTP01 để xác thực SSL"
 msgid "Show"
 msgstr ""
 
-#: src/views/other/Login.vue:265
+#: src/views/other/Login.vue:263
 msgid "Sign in with a passkey"
 msgstr ""
 
@@ -2070,7 +2103,7 @@ msgstr ""
 msgid "SSL Certificate Path"
 msgstr ""
 
-#: src/views/other/Login.vue:223
+#: src/views/other/Login.vue:221
 msgid "SSO Login"
 msgstr ""
 
@@ -2198,7 +2231,7 @@ msgstr "Mục tiêu"
 msgid "Terminal"
 msgstr "Terminal"
 
-#: src/views/preference/BasicSettings.vue:28
+#: src/views/preference/BasicSettings.vue:26
 msgid "Terminal Start Command"
 msgstr ""
 
@@ -2230,6 +2263,12 @@ msgid ""
 "dashes, and dots."
 msgstr ""
 
+#: src/views/preference/BasicSettings.vue:45
+msgid ""
+"The node name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
+msgstr ""
+
 #: src/views/certificate/CertificateEditor.vue:173
 msgid "The path exists, but the file is not a certificate"
 msgstr ""
@@ -2250,12 +2289,6 @@ msgid ""
 "match the local version."
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:120
-msgid ""
-"The server name should only contain letters, unicode, numbers, hyphens, "
-"dashes, and dots."
-msgstr ""
-
 #: src/views/site/cert/components/AutoCertStepOne.vue:45
 #, fuzzy
 msgid ""
@@ -2264,8 +2297,8 @@ msgid ""
 msgstr ""
 "Lưu ý: server_name trong cấu hình hiện tại phải là tên miền bạn muốn ký SSL."
 
-#: src/views/preference/BasicSettings.vue:38
-#: src/views/preference/BasicSettings.vue:50
+#: src/views/preference/BasicSettings.vue:33
+#: src/views/preference/CertSettings.vue:19
 msgid "The url is invalid"
 msgstr ""
 
@@ -2301,7 +2334,11 @@ msgid ""
 "This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:67
+#: src/views/preference/AuthSettings.vue:98
+msgid "Throttle"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:118
 #: src/views/preference/components/AddPasskey.vue:71
 #: src/views/preference/LogrotateSettings.vue:11
 msgid "Tips"
@@ -2346,7 +2383,7 @@ msgstr ""
 msgid "Token is not valid"
 msgstr ""
 
-#: src/views/other/Login.vue:82
+#: src/views/other/Login.vue:80
 msgid "Too many login failed attempts, please try again later"
 msgstr ""
 
@@ -2364,7 +2401,7 @@ msgstr ""
 msgid "Trash"
 msgstr ""
 
-#: src/components/TwoFA/use2FAModal.ts:71
+#: src/components/TwoFA/use2FAModal.ts:66
 msgid "Two-factor authentication required"
 msgstr ""
 
@@ -2439,11 +2476,11 @@ msgstr ""
 msgid "User"
 msgstr "Người dùng"
 
-#: src/views/other/Login.vue:85
+#: src/views/other/Login.vue:83
 msgid "User is banned"
 msgstr ""
 
-#: src/views/other/Login.vue:198 src/views/user/userColumns.tsx:9
+#: src/views/other/Login.vue:196 src/views/user/userColumns.tsx:9
 msgid "Username"
 msgstr "Username"
 
@@ -2505,6 +2542,10 @@ msgstr ""
 "Chúng tôi sẽ xóa cấu hình HTTPChallenge khỏi tệp này và tải lại Nginx. Bạn "
 "có muốn tiếp tục không?"
 
+#: src/views/preference/AuthSettings.vue:71
+msgid "Webauthn"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:78
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "
@@ -2525,8 +2566,8 @@ msgstr "Ghi Private Key vào disk"
 msgid "Writing certificate to disk"
 msgstr "Ghi chứng chỉ vào disk"
 
-#: src/views/preference/AuthSettings.vue:103
-#: src/views/preference/BasicSettings.vue:100
+#: src/views/preference/AuthSettings.vue:137
+#: src/views/preference/CertSettings.vue:69
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/site/ngx_conf/LocationEditor.vue:89
 msgid "Yes"
@@ -2550,6 +2591,14 @@ msgstr ""
 msgid "Your passkeys"
 msgstr ""
 
+#, fuzzy
+#~ msgid "File not found"
+#~ msgstr "Không tìm thấy tệp tin"
+
+#, fuzzy
+#~ msgid "Server Name"
+#~ msgstr "Thông tin máy chủ"
+
 #, fuzzy
 #~ msgid "Enable 2FA"
 #~ msgstr "Đã bật"
@@ -2558,9 +2607,6 @@ msgstr ""
 #~ msgid "Rename "
 #~ msgstr "Username"
 
-#~ msgid "Auto Cert"
-#~ msgstr "Tự động ký chứng chỉ SSL"
-
 #~ msgid "Certificate has expired"
 #~ msgstr "Chứng chỉ đã hết hạn"
 

BIN
app/src/language/zh_CN/app.mo


+ 130 - 83
app/src/language/zh_CN/app.po

@@ -17,7 +17,7 @@ msgstr ""
 msgid "2FA"
 msgstr "2FA"
 
-#: src/views/preference/AuthSettings.vue:58
+#: src/views/preference/AuthSettings.vue:57
 msgid "2FA Settings"
 msgstr "2FA 设置"
 
@@ -40,14 +40,14 @@ msgstr "ACME 用户"
 #: src/views/config/configColumns.ts:38
 #: src/views/environment/envColumns.tsx:131
 #: src/views/notification/notificationColumns.tsx:54
-#: src/views/preference/AuthSettings.vue:27 src/views/site/SiteList.vue:54
+#: src/views/preference/AuthSettings.vue:26 src/views/site/SiteList.vue:54
 #: src/views/stream/StreamList.vue:47 src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "操作"
 
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:183
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:204
-#: src/views/preference/BasicSettings.vue:73
+#: src/views/preference/CertSettings.vue:42
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:162
 #: src/views/site/ngx_conf/NgxUpstream.vue:152
@@ -118,7 +118,7 @@ msgstr "API Token"
 msgid "Arch"
 msgstr "架构"
 
-#: src/views/preference/AuthSettings.vue:102
+#: src/views/preference/AuthSettings.vue:136
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr "您确定要立即删除这个被禁用的 IP 吗?"
 
@@ -155,7 +155,7 @@ msgstr "您确定要恢复这个项目吗?"
 msgid "Are you sure you want to remove this directive?"
 msgstr "您确定要删除这条指令?"
 
-#: src/views/preference/BasicSettings.vue:99
+#: src/views/preference/CertSettings.vue:68
 msgid "Are you sure you want to remove this item?"
 msgstr "您确定要删除这个项目吗?"
 
@@ -171,11 +171,11 @@ msgstr "与ChatGPT聊天"
 msgid "Assistant"
 msgstr "助手"
 
-#: src/views/preference/AuthSettings.vue:18
+#: src/views/preference/AuthSettings.vue:17
 msgid "Attempts"
 msgstr "尝试次数"
 
-#: src/views/preference/Preference.vue:122
+#: src/views/preference/Preference.vue:153
 msgid "Auth"
 msgstr "认证"
 
@@ -183,7 +183,7 @@ msgstr "认证"
 msgid "Authenticate with a passkey"
 msgstr "通过 Passkey 认证"
 
-#: src/views/preference/AuthSettings.vue:63
+#: src/views/preference/AuthSettings.vue:62
 msgid "Authentication Settings"
 msgstr "认证设置"
 
@@ -219,15 +219,15 @@ msgstr "返回首页"
 msgid "Back to list"
 msgstr "返回列表"
 
-#: src/views/preference/AuthSettings.vue:76
+#: src/views/preference/AuthSettings.vue:103
 msgid "Ban Threshold Minutes"
 msgstr "禁止阈值(分钟)"
 
-#: src/views/preference/AuthSettings.vue:90
+#: src/views/preference/AuthSettings.vue:124
 msgid "Banned IPs"
 msgstr "禁止 IP 列表"
 
-#: src/views/preference/AuthSettings.vue:21
+#: src/views/preference/AuthSettings.vue:20
 msgid "Banned Until"
 msgstr "禁用至"
 
@@ -236,7 +236,7 @@ msgid "Base information"
 msgstr "基本信息"
 
 #: src/views/config/ConfigEditor.vue:241
-#: src/views/preference/Preference.vue:116
+#: src/views/preference/Preference.vue:147
 #: src/views/site/components/RightSettings.vue:75
 #: src/views/stream/components/RightSettings.vue:74
 msgid "Basic"
@@ -263,7 +263,7 @@ msgstr "构建基于"
 msgid "CA Dir"
 msgstr "CA Dir"
 
-#: src/views/preference/BasicSettings.vue:47
+#: src/views/preference/CertSettings.vue:16
 msgid "CADir"
 msgstr "CADir"
 
@@ -287,7 +287,11 @@ msgstr "无法扫描?使用文本密钥绑定"
 msgid "Cancel"
 msgstr "取消"
 
-#: src/views/preference/BasicSettings.vue:55
+#: src/views/preference/Preference.vue:159
+msgid "Cert"
+msgstr "证书"
+
+#: src/views/preference/CertSettings.vue:24
 msgid "Certificate Renewal Interval"
 msgstr "证书续期间隔"
 
@@ -467,9 +471,9 @@ msgstr "当前版本"
 msgid "Custom"
 msgstr "自定义"
 
-#: src/views/preference/BasicSettings.vue:121
+#: src/views/preference/BasicSettings.vue:46
 msgid ""
-"Customize the name of local server to be displayed in the environment "
+"Customize the name of local node to be displayed in the environment "
 "indicator."
 msgstr "自定义显示在环境指示器中的本地服务器名称。"
 
@@ -482,7 +486,7 @@ msgstr "仪表盘"
 msgid "Database (Optional, default: database)"
 msgstr "数据库 (可选,默认: database)"
 
-#: src/views/preference/BasicSettings.vue:60
+#: src/views/preference/CertSettings.vue:29
 msgid "Days"
 msgstr "天"
 
@@ -860,11 +864,6 @@ msgstr "文件"
 msgid "File exists"
 msgstr "文件已存在"
 
-#: src/views/preference/NginxSettings.vue:14
-#: src/views/preference/NginxSettings.vue:23
-msgid "File not found"
-msgstr "文件未找到"
-
 #: src/views/other/Error.vue:9
 msgid "File Not Found"
 msgstr "未找到文件"
@@ -883,7 +882,7 @@ msgid ""
 "process."
 msgstr "按照对话框中的指示完成 Passkey 的注册过程。"
 
-#: src/views/preference/BasicSettings.vue:43
+#: src/views/preference/BasicSettings.vue:38
 msgid "For Chinese user: https://mirror.ghproxy.com/"
 msgstr "中国用户:https://mirror.ghproxy.com/"
 
@@ -919,7 +918,7 @@ msgstr "获取发布信息错误"
 msgid "Getting the certificate, please wait..."
 msgstr "正在获取证书,请稍等..."
 
-#: src/views/preference/BasicSettings.vue:35
+#: src/views/preference/BasicSettings.vue:30
 msgid "Github Proxy"
 msgstr "Github代理"
 
@@ -931,15 +930,15 @@ msgstr "隐藏"
 msgid "Home"
 msgstr "首页"
 
-#: src/views/preference/BasicSettings.vue:31
+#: src/views/preference/CertSettings.vue:12
 msgid "HTTP Challenge Port"
 msgstr "HTTP Challenge 监听端口"
 
-#: src/views/preference/BasicSettings.vue:13
+#: src/views/preference/BasicSettings.vue:11
 msgid "HTTP Host"
 msgstr "HTTP 监听主机"
 
-#: src/views/preference/BasicSettings.vue:16
+#: src/views/preference/BasicSettings.vue:14
 msgid "HTTP Port"
 msgstr "HTTP 监听端口"
 
@@ -951,7 +950,7 @@ msgstr "HTTP01"
 msgid "If left blank, the default CA Dir will be used."
 msgstr "如果留空,则使用默认 CA Dir。"
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:119
 msgid ""
 "If the number of login failed attempts from a ip reach the max attempts in "
 "ban threshold minutes, the ip will be banned for a period of time."
@@ -983,7 +982,7 @@ msgstr "导入"
 msgid "Import Certificate"
 msgstr "导入证书"
 
-#: src/views/other/Login.vue:79
+#: src/views/other/Login.vue:77
 msgid "Incorrect username or password"
 msgstr "用户名或密码错误"
 
@@ -1024,7 +1023,7 @@ msgstr "间隔"
 msgid "Invalid"
 msgstr "无效的"
 
-#: src/views/other/Login.vue:89
+#: src/views/other/Login.vue:87
 msgid "Invalid 2FA or recovery code"
 msgstr "无效的二步验证码或恢复密码"
 
@@ -1037,11 +1036,11 @@ msgstr "文件名无效"
 msgid "Invalid folder name"
 msgstr "无效文件夹名"
 
-#: src/components/TwoFA/use2FAModal.ts:65
+#: src/components/TwoFA/use2FAModal.ts:60
 msgid "Invalid passcode or recovery code"
 msgstr "二次验证码或恢复代码无效"
 
-#: src/views/preference/AuthSettings.vue:15
+#: src/views/preference/AuthSettings.vue:14
 msgid "IP"
 msgstr "IP"
 
@@ -1061,7 +1060,7 @@ msgstr "证书申请成功"
 msgid "Issuer: %{issuer}"
 msgstr "颁发者:%{issuer}"
 
-#: src/views/preference/BasicSettings.vue:22
+#: src/views/preference/BasicSettings.vue:20
 msgid "Jwt Secret"
 msgstr "Jwt 密钥"
 
@@ -1141,11 +1140,11 @@ msgstr "Locations"
 msgid "Log"
 msgstr "日志"
 
-#: src/routes/index.ts:305 src/views/other/Login.vue:247
+#: src/routes/index.ts:305 src/views/other/Login.vue:245
 msgid "Login"
 msgstr "登录"
 
-#: src/views/other/Login.vue:133 src/views/other/Login.vue:66
+#: src/views/other/Login.vue:131 src/views/other/Login.vue:64
 msgid "Login successful"
 msgstr "登录成功"
 
@@ -1153,7 +1152,7 @@ msgstr "登录成功"
 msgid "Logout successful"
 msgstr "登出成功"
 
-#: src/views/preference/Preference.vue:140
+#: src/views/preference/Preference.vue:177
 msgid "Logrotate"
 msgstr "Logrotate"
 
@@ -1200,7 +1199,7 @@ msgstr "用户管理"
 msgid "Managed Certificate"
 msgstr "托管证书"
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:109
 msgid "Max Attempts"
 msgstr "最大尝试次数"
 
@@ -1294,11 +1293,11 @@ msgstr "新版本发布"
 msgid "Next"
 msgstr "下一步"
 
-#: src/views/preference/Preference.vue:128
+#: src/views/preference/Preference.vue:165
 msgid "Nginx"
 msgstr "Nginx"
 
-#: src/views/preference/NginxSettings.vue:11
+#: src/views/preference/NginxSettings.vue:9
 msgid "Nginx Access Log Path"
 msgstr "Nginx 访问日志路径"
 
@@ -1306,11 +1305,15 @@ msgstr "Nginx 访问日志路径"
 msgid "Nginx Configuration Parse Error"
 msgstr "Nginx 配置解析错误"
 
+#: src/views/preference/NginxSettings.vue:15
+msgid "Nginx Configurations Directory"
+msgstr "Nginx 配置目录"
+
 #: src/components/NginxControl/NginxControl.vue:68
 msgid "Nginx Control"
 msgstr "控制 Nginx"
 
-#: src/views/preference/NginxSettings.vue:20
+#: src/views/preference/NginxSettings.vue:12
 msgid "Nginx Error Log Path"
 msgstr "Nginx 错误日志路径"
 
@@ -1322,10 +1325,26 @@ msgstr "Nginx 未启动"
 msgid "Nginx Log"
 msgstr "Nginx 日志"
 
+#: src/views/preference/NginxSettings.vue:18
+msgid "Nginx Log Directory Whitelist"
+msgstr "Nginx 日志目录白名单"
+
+#: src/views/preference/NginxSettings.vue:27
+msgid "Nginx PID Path"
+msgstr "Nginx PID 路径"
+
+#: src/views/preference/NginxSettings.vue:30
+msgid "Nginx Reload Command"
+msgstr "Nginx 重载命令"
+
 #: src/components/NginxControl/NginxControl.vue:26
 msgid "Nginx reloaded successfully"
 msgstr "Nginx 重载成功"
 
+#: src/views/preference/NginxSettings.vue:33
+msgid "Nginx Restart Command"
+msgstr "Nginx 重启命令"
+
 #: src/components/NginxControl/NginxControl.vue:42
 msgid "Nginx restarted successfully"
 msgstr "Nginx 重启成功"
@@ -1336,15 +1355,19 @@ msgstr "Nginx 重启成功"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:561
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:575
 #: src/views/notification/Notification.vue:38
-#: src/views/preference/AuthSettings.vue:104
-#: src/views/preference/BasicSettings.vue:101
+#: src/views/preference/AuthSettings.vue:138
+#: src/views/preference/CertSettings.vue:70
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/site/ngx_conf/LocationEditor.vue:90
 #: src/views/site/SiteList.vue:151 src/views/stream/StreamList.vue:165
 msgid "No"
 msgstr "取消"
 
-#: src/views/preference/BasicSettings.vue:25
+#: src/views/preference/BasicSettings.vue:42
+msgid "Node name"
+msgstr "节点名称"
+
+#: src/views/preference/BasicSettings.vue:23
 msgid "Node Secret"
 msgstr "节点密钥"
 
@@ -1432,11 +1455,11 @@ msgstr "一旦验证完成,这些记录将被删除。"
 msgid "Online"
 msgstr "在线"
 
-#: src/views/preference/Preference.vue:134
+#: src/views/preference/Preference.vue:171
 msgid "OpenAI"
 msgstr "OpenAI"
 
-#: src/components/TwoFA/Authorization.vue:117 src/views/other/Login.vue:256
+#: src/components/TwoFA/Authorization.vue:117 src/views/other/Login.vue:254
 msgid "Or"
 msgstr "或"
 
@@ -1481,7 +1504,7 @@ msgstr ""
 "Passkey 是一种网络认证凭据,可通过指纹、面部识别、设备密码或 PIN 码验证身份。"
 "它们可用作密码替代品或二步验证方法。"
 
-#: src/views/other/Login.vue:208 src/views/user/userColumns.tsx:18
+#: src/views/other/Login.vue:206 src/views/user/userColumns.tsx:18
 msgid "Password"
 msgstr "密码"
 
@@ -1555,11 +1578,11 @@ msgstr "请输入名称,这将被用作新配置的文件名!"
 msgid "Please input your E-mail!"
 msgstr "请输入您的邮箱!"
 
-#: src/views/other/Install.vue:44 src/views/other/Login.vue:47
+#: src/views/other/Install.vue:44 src/views/other/Login.vue:46
 msgid "Please input your password!"
 msgstr "请输入您的密码!"
 
-#: src/views/other/Install.vue:38 src/views/other/Login.vue:41
+#: src/views/other/Install.vue:38 src/views/other/Login.vue:40
 msgid "Please input your username!"
 msgstr "请输入您的用户名!"
 
@@ -1583,7 +1606,7 @@ msgstr "请至少选择一个节点!"
 msgid "Pre-release"
 msgstr "预发布"
 
-#: src/routes/index.ts:260 src/views/preference/Preference.vue:111
+#: src/routes/index.ts:260 src/views/preference/Preference.vue:142
 msgid "Preference"
 msgstr "偏好设置"
 
@@ -1642,7 +1665,7 @@ msgstr "恢复代码"
 msgid "Recovery Code:"
 msgstr "恢复代码:"
 
-#: src/views/preference/BasicSettings.vue:68
+#: src/views/preference/CertSettings.vue:37
 msgid "Recursive Nameservers"
 msgstr "递归域名服务器"
 
@@ -1705,11 +1728,11 @@ msgstr "重载中"
 msgid "Reloading nginx"
 msgstr "正在重载 Nginx"
 
-#: src/views/preference/AuthSettings.vue:109
+#: src/views/preference/AuthSettings.vue:143
 msgid "Remove"
 msgstr "删除"
 
-#: src/views/preference/AuthSettings.vue:48
+#: src/views/preference/AuthSettings.vue:47
 #: src/views/preference/components/Passkey.vue:50
 msgid "Remove successfully"
 msgstr "移除成功"
@@ -1792,7 +1815,19 @@ msgstr "重启"
 msgid "Restarting"
 msgstr "重启中"
 
-#: src/views/preference/BasicSettings.vue:19
+#: src/views/preference/AuthSettings.vue:81
+msgid "RP Display Name"
+msgstr "依赖方显示名称"
+
+#: src/views/preference/AuthSettings.vue:87
+msgid "RP Origins"
+msgstr "依赖方的源"
+
+#: src/views/preference/AuthSettings.vue:75
+msgid "RPID"
+msgstr "依赖方 ID"
+
+#: src/views/preference/BasicSettings.vue:17
 msgid "Run Mode"
 msgstr "运行模式"
 
@@ -1804,7 +1839,7 @@ msgstr "运行中"
 #: src/views/certificate/CertificateEditor.vue:256
 #: src/views/config/ConfigEditor.vue:222
 #: src/views/preference/components/Passkey.vue:136
-#: src/views/preference/Preference.vue:151
+#: src/views/preference/Preference.vue:188
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:120
 #: src/views/site/SiteEdit.vue:260 src/views/stream/StreamEdit.vue:252
 msgid "Save"
@@ -1823,7 +1858,7 @@ msgstr "保存错误 %{msg}"
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:122
 #: src/views/certificate/CertificateEditor.vue:46
-#: src/views/preference/Preference.vue:79
+#: src/views/preference/Preference.vue:110
 msgid "Save successfully"
 msgstr "保存成功"
 
@@ -1867,13 +1902,13 @@ msgstr "上传"
 #: src/views/config/ConfigEditor.vue:108
 #: src/views/environment/BatchUpgrader.vue:59
 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:68
-#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/AuthSettings.vue:49
 #: src/views/preference/components/Passkey.vue:26
 #: src/views/preference/components/Passkey.vue:43
 #: src/views/preference/components/Passkey.vue:56
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:58
-#: src/views/preference/Preference.vue:83 src/views/site/SiteList.vue:88
+#: src/views/preference/Preference.vue:114 src/views/site/SiteList.vue:88
 #: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81
 #: src/views/system/Upgrade.vue:42
 msgid "Server error"
@@ -1883,10 +1918,6 @@ msgstr "服务器错误"
 msgid "Server Info"
 msgstr "服务器信息"
 
-#: src/views/preference/BasicSettings.vue:117
-msgid "Server Name"
-msgstr "服务器名称"
-
 #: src/views/site/cert/components/ObtainCert.vue:102
 msgid "server_name not found in directives"
 msgstr "未在指令集合中找到 server_name"
@@ -1895,7 +1926,7 @@ msgstr "未在指令集合中找到 server_name"
 msgid "server_name parameter is required"
 msgstr "必须为 server_name 指令指明参数"
 
-#: src/views/preference/BasicSettings.vue:64
+#: src/views/preference/CertSettings.vue:33
 msgid ""
 "Set the recursive nameservers to override the systems nameservers for the "
 "step of DNS challenge."
@@ -1917,7 +1948,7 @@ msgstr "使用 HTTP01 challenge provider"
 msgid "Show"
 msgstr "显示"
 
-#: src/views/other/Login.vue:265
+#: src/views/other/Login.vue:263
 msgid "Sign in with a passkey"
 msgstr "使用 Passkey 登录"
 
@@ -1949,7 +1980,7 @@ msgstr "SSL证书密钥路径"
 msgid "SSL Certificate Path"
 msgstr "SSL证书路径"
 
-#: src/views/other/Login.vue:223
+#: src/views/other/Login.vue:221
 msgid "SSO Login"
 msgstr "SSO 登录"
 
@@ -2068,7 +2099,7 @@ msgstr "目标"
 msgid "Terminal"
 msgstr "终端"
 
-#: src/views/preference/BasicSettings.vue:28
+#: src/views/preference/BasicSettings.vue:26
 msgid "Terminal Start Command"
 msgstr "终端启动命令"
 
@@ -2099,6 +2130,12 @@ msgid ""
 "dashes, and dots."
 msgstr "模型只能包含字母、Unicode、数字、连词符、破折号和点。"
 
+#: src/views/preference/BasicSettings.vue:45
+msgid ""
+"The node name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
+msgstr "节点名称只能包含字母、统一码、数字、连字符、破折号和点。"
+
 #: src/views/certificate/CertificateEditor.vue:173
 msgid "The path exists, but the file is not a certificate"
 msgstr "路径存在,但文件不是证书"
@@ -2121,20 +2158,14 @@ msgstr ""
 "远程 Nginx UI 版本与本地 Nginx UI版本不兼容。为避免意料之外的错误,请升级远"
 "程 Nginx UI,使其与本地版本一致。"
 
-#: src/views/preference/BasicSettings.vue:120
-msgid ""
-"The server name should only contain letters, unicode, numbers, hyphens, "
-"dashes, and dots."
-msgstr "服务器名称只能包含字母、Unicode、数字、连词符、破折号和点。"
-
 #: src/views/site/cert/components/AutoCertStepOne.vue:45
 msgid ""
 "The server_name in the current configuration must be the domain name you "
 "need to get the certificate, supportmultiple domains."
 msgstr "当前配置中的 server_name 必须是获取证书所需的域名,支持多个域名。"
 
-#: src/views/preference/BasicSettings.vue:38
-#: src/views/preference/BasicSettings.vue:50
+#: src/views/preference/BasicSettings.vue:33
+#: src/views/preference/CertSettings.vue:19
 msgid "The url is invalid"
 msgstr "URL无效"
 
@@ -2170,7 +2201,11 @@ msgid ""
 "This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
 msgstr "将 %{nodeNames} 上的 Nginx UI 升级或重新安装到 %{version} 版本。"
 
-#: src/views/preference/AuthSettings.vue:67
+#: src/views/preference/AuthSettings.vue:98
+msgid "Throttle"
+msgstr "限流"
+
+#: src/views/preference/AuthSettings.vue:118
 #: src/views/preference/components/AddPasskey.vue:71
 #: src/views/preference/LogrotateSettings.vue:11
 msgid "Tips"
@@ -2218,7 +2253,7 @@ msgstr ""
 msgid "Token is not valid"
 msgstr "Token 无效"
 
-#: src/views/other/Login.vue:82
+#: src/views/other/Login.vue:80
 msgid "Too many login failed attempts, please try again later"
 msgstr "登录失败次数过多,请稍后再试"
 
@@ -2236,7 +2271,7 @@ msgstr "TOTP 是一种使用基于时间的一次性密码算法的双因素身
 msgid "Trash"
 msgstr "回收站"
 
-#: src/components/TwoFA/use2FAModal.ts:71
+#: src/components/TwoFA/use2FAModal.ts:66
 msgid "Two-factor authentication required"
 msgstr "需要两步验证"
 
@@ -2306,11 +2341,11 @@ msgstr "使用恢复代码"
 msgid "User"
 msgstr "用户"
 
-#: src/views/other/Login.vue:85
+#: src/views/other/Login.vue:83
 msgid "User is banned"
 msgstr "用户被禁止"
 
-#: src/views/other/Login.vue:198 src/views/user/userColumns.tsx:9
+#: src/views/other/Login.vue:196 src/views/user/userColumns.tsx:9
 msgid "Username"
 msgstr "用户名"
 
@@ -2365,6 +2400,10 @@ msgid ""
 msgstr ""
 "我们将从这个文件中删除HTTPChallenge的配置,并重新加载Nginx。你确定要继续吗?"
 
+#: src/views/preference/AuthSettings.vue:71
+msgid "Webauthn"
+msgstr "Webauthn"
+
 #: src/views/certificate/ACMEUser.vue:78
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "
@@ -2387,8 +2426,8 @@ msgstr "正在将证书私钥写入磁盘"
 msgid "Writing certificate to disk"
 msgstr "正在将证书写入磁盘"
 
-#: src/views/preference/AuthSettings.vue:103
-#: src/views/preference/BasicSettings.vue:100
+#: src/views/preference/AuthSettings.vue:137
+#: src/views/preference/CertSettings.vue:69
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/site/ngx_conf/LocationEditor.vue:89
 msgid "Yes"
@@ -2412,6 +2451,17 @@ msgstr "您尚未配置 Webauthn 的设置,因此无法添加 Passkey。"
 msgid "Your passkeys"
 msgstr "你的 Passkeys"
 
+#~ msgid "File not found"
+#~ msgstr "文件未找到"
+
+#~ msgid "Server Name"
+#~ msgstr "服务器名称"
+
+#~ msgid ""
+#~ "The server name should only contain letters, unicode, numbers, hyphens, "
+#~ "dashes, and dots."
+#~ msgstr "服务器名称只能包含字母、Unicode、数字、连词符、破折号和点。"
+
 #~ msgid "Enable 2FA"
 #~ msgstr "启用二步验证"
 
@@ -2422,9 +2472,6 @@ msgstr "你的 Passkeys"
 #~ msgid "Rename "
 #~ msgstr "重命名"
 
-#~ msgid "Auto Cert"
-#~ msgstr "自动更新"
-
 #~ msgid "Certificate has expired"
 #~ msgstr "此证书已过期"
 

+ 137 - 83
app/src/language/zh_TW/app.po

@@ -21,7 +21,7 @@ msgstr ""
 msgid "2FA"
 msgstr "多重要素驗證"
 
-#: src/views/preference/AuthSettings.vue:58
+#: src/views/preference/AuthSettings.vue:57
 msgid "2FA Settings"
 msgstr "多重要素驗證設定"
 
@@ -44,14 +44,14 @@ msgstr "ACME 用戶"
 #: src/views/config/configColumns.ts:38
 #: src/views/environment/envColumns.tsx:131
 #: src/views/notification/notificationColumns.tsx:54
-#: src/views/preference/AuthSettings.vue:27 src/views/site/SiteList.vue:54
+#: src/views/preference/AuthSettings.vue:26 src/views/site/SiteList.vue:54
 #: src/views/stream/StreamList.vue:47 src/views/user/userColumns.tsx:60
 msgid "Action"
 msgstr "操作"
 
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:183
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:204
-#: src/views/preference/BasicSettings.vue:73
+#: src/views/preference/CertSettings.vue:42
 #: src/views/site/ngx_conf/config_template/ConfigTemplate.vue:117
 #: src/views/site/ngx_conf/NgxServer.vue:162
 #: src/views/site/ngx_conf/NgxUpstream.vue:152
@@ -122,7 +122,7 @@ msgstr "API Token"
 msgid "Arch"
 msgstr "架構"
 
-#: src/views/preference/AuthSettings.vue:102
+#: src/views/preference/AuthSettings.vue:136
 msgid "Are you sure to delete this banned IP immediately?"
 msgstr "您確定要刪除這個被禁用的 IP 嗎?"
 
@@ -160,7 +160,7 @@ msgstr "您確定要恢復此項目嗎?"
 msgid "Are you sure you want to remove this directive?"
 msgstr "您確定要刪除這條指令嗎?"
 
-#: src/views/preference/BasicSettings.vue:99
+#: src/views/preference/CertSettings.vue:68
 msgid "Are you sure you want to remove this item?"
 msgstr "您確定要刪除此項目嗎?"
 
@@ -176,11 +176,11 @@ msgstr "向 ChatGPT 尋求幫助"
 msgid "Assistant"
 msgstr "助理"
 
-#: src/views/preference/AuthSettings.vue:18
+#: src/views/preference/AuthSettings.vue:17
 msgid "Attempts"
 msgstr "嘗試次數"
 
-#: src/views/preference/Preference.vue:122
+#: src/views/preference/Preference.vue:153
 msgid "Auth"
 msgstr "身份驗證"
 
@@ -188,7 +188,7 @@ msgstr "身份驗證"
 msgid "Authenticate with a passkey"
 msgstr ""
 
-#: src/views/preference/AuthSettings.vue:63
+#: src/views/preference/AuthSettings.vue:62
 msgid "Authentication Settings"
 msgstr ""
 
@@ -224,15 +224,15 @@ msgstr "返回首頁"
 msgid "Back to list"
 msgstr "返回列表"
 
-#: src/views/preference/AuthSettings.vue:76
+#: src/views/preference/AuthSettings.vue:103
 msgid "Ban Threshold Minutes"
 msgstr "封禁閾值分鐘數"
 
-#: src/views/preference/AuthSettings.vue:90
+#: src/views/preference/AuthSettings.vue:124
 msgid "Banned IPs"
 msgstr "被禁止的 IP"
 
-#: src/views/preference/AuthSettings.vue:21
+#: src/views/preference/AuthSettings.vue:20
 msgid "Banned Until"
 msgstr "禁止至"
 
@@ -241,7 +241,7 @@ msgid "Base information"
 msgstr "基本資訊"
 
 #: src/views/config/ConfigEditor.vue:241
-#: src/views/preference/Preference.vue:116
+#: src/views/preference/Preference.vue:147
 #: src/views/site/components/RightSettings.vue:75
 #: src/views/stream/components/RightSettings.vue:74
 msgid "Basic"
@@ -268,7 +268,7 @@ msgstr "構建基於"
 msgid "CA Dir"
 msgstr "CA Dir"
 
-#: src/views/preference/BasicSettings.vue:47
+#: src/views/preference/CertSettings.vue:16
 msgid "CADir"
 msgstr "CADir"
 
@@ -292,7 +292,12 @@ msgstr ""
 msgid "Cancel"
 msgstr "取消"
 
-#: src/views/preference/BasicSettings.vue:55
+#: src/views/preference/Preference.vue:159
+#, fuzzy
+msgid "Cert"
+msgstr "自動憑證"
+
+#: src/views/preference/CertSettings.vue:24
 msgid "Certificate Renewal Interval"
 msgstr "憑證更新間隔"
 
@@ -474,9 +479,10 @@ msgstr "目前版本"
 msgid "Custom"
 msgstr "自訂"
 
-#: src/views/preference/BasicSettings.vue:121
+#: src/views/preference/BasicSettings.vue:46
+#, fuzzy
 msgid ""
-"Customize the name of local server to be displayed in the environment "
+"Customize the name of local node to be displayed in the environment "
 "indicator."
 msgstr "自訂本地伺服器名稱以顯示在環境指示器中。"
 
@@ -489,7 +495,7 @@ msgstr "儀表板"
 msgid "Database (Optional, default: database)"
 msgstr "資料庫 (可選,預設: database)"
 
-#: src/views/preference/BasicSettings.vue:60
+#: src/views/preference/CertSettings.vue:29
 msgid "Days"
 msgstr "天"
 
@@ -866,11 +872,6 @@ msgstr "檔案"
 msgid "File exists"
 msgstr "檔案已存在"
 
-#: src/views/preference/NginxSettings.vue:14
-#: src/views/preference/NginxSettings.vue:23
-msgid "File not found"
-msgstr "找不到檔案"
-
 #: src/views/other/Error.vue:9
 msgid "File Not Found"
 msgstr "找不到檔案"
@@ -889,7 +890,7 @@ msgid ""
 "process."
 msgstr ""
 
-#: src/views/preference/BasicSettings.vue:43
+#: src/views/preference/BasicSettings.vue:38
 msgid "For Chinese user: https://mirror.ghproxy.com/"
 msgstr "中國使用者:https://mirror.ghproxy.com/"
 
@@ -925,7 +926,7 @@ msgstr "取得發布資訊錯誤"
 msgid "Getting the certificate, please wait..."
 msgstr "正在取得憑證,請稍候..."
 
-#: src/views/preference/BasicSettings.vue:35
+#: src/views/preference/BasicSettings.vue:30
 msgid "Github Proxy"
 msgstr "Github 代理"
 
@@ -937,15 +938,15 @@ msgstr "隱藏"
 msgid "Home"
 msgstr "首頁"
 
-#: src/views/preference/BasicSettings.vue:31
+#: src/views/preference/CertSettings.vue:12
 msgid "HTTP Challenge Port"
 msgstr "HTTP 挑戰埠"
 
-#: src/views/preference/BasicSettings.vue:13
+#: src/views/preference/BasicSettings.vue:11
 msgid "HTTP Host"
 msgstr "HTTP 監聽主機"
 
-#: src/views/preference/BasicSettings.vue:16
+#: src/views/preference/BasicSettings.vue:14
 msgid "HTTP Port"
 msgstr "HTTP 監聽埠"
 
@@ -957,7 +958,7 @@ msgstr "HTTP01"
 msgid "If left blank, the default CA Dir will be used."
 msgstr "如果留空,將使用默認的 CA Dir。"
 
-#: src/views/preference/AuthSettings.vue:68
+#: src/views/preference/AuthSettings.vue:119
 msgid ""
 "If the number of login failed attempts from a ip reach the max attempts in "
 "ban threshold minutes, the ip will be banned for a period of time."
@@ -989,7 +990,7 @@ msgstr "導入"
 msgid "Import Certificate"
 msgstr "導入憑證"
 
-#: src/views/other/Login.vue:79
+#: src/views/other/Login.vue:77
 msgid "Incorrect username or password"
 msgstr "使用者名稱或密碼不正確"
 
@@ -1030,7 +1031,7 @@ msgstr "間隔"
 msgid "Invalid"
 msgstr "無效"
 
-#: src/views/other/Login.vue:89
+#: src/views/other/Login.vue:87
 msgid "Invalid 2FA or recovery code"
 msgstr "無效的多重因素驗證或恢復碼"
 
@@ -1043,11 +1044,11 @@ msgstr "無效的檔案名"
 msgid "Invalid folder name"
 msgstr "無效的資料夾名稱"
 
-#: src/components/TwoFA/use2FAModal.ts:65
+#: src/components/TwoFA/use2FAModal.ts:60
 msgid "Invalid passcode or recovery code"
 msgstr "無效的密碼或恢復碼"
 
-#: src/views/preference/AuthSettings.vue:15
+#: src/views/preference/AuthSettings.vue:14
 msgid "IP"
 msgstr "IP"
 
@@ -1067,7 +1068,7 @@ msgstr "成功頒發憑證"
 msgid "Issuer: %{issuer}"
 msgstr "發行者:%{issuer}"
 
-#: src/views/preference/BasicSettings.vue:22
+#: src/views/preference/BasicSettings.vue:20
 msgid "Jwt Secret"
 msgstr "Jwt Secret"
 
@@ -1149,11 +1150,11 @@ msgstr "Locations"
 msgid "Log"
 msgstr "日誌"
 
-#: src/routes/index.ts:305 src/views/other/Login.vue:247
+#: src/routes/index.ts:305 src/views/other/Login.vue:245
 msgid "Login"
 msgstr "登入"
 
-#: src/views/other/Login.vue:133 src/views/other/Login.vue:66
+#: src/views/other/Login.vue:131 src/views/other/Login.vue:64
 msgid "Login successful"
 msgstr "登入成功"
 
@@ -1161,7 +1162,7 @@ msgstr "登入成功"
 msgid "Logout successful"
 msgstr "登出成功"
 
-#: src/views/preference/Preference.vue:140
+#: src/views/preference/Preference.vue:177
 msgid "Logrotate"
 msgstr "Logrotate"
 
@@ -1207,7 +1208,7 @@ msgstr "管理使用者"
 msgid "Managed Certificate"
 msgstr "受管理的憑證"
 
-#: src/views/preference/AuthSettings.vue:82
+#: src/views/preference/AuthSettings.vue:109
 msgid "Max Attempts"
 msgstr "最大嘗試次數"
 
@@ -1301,11 +1302,11 @@ msgstr "新版本發布"
 msgid "Next"
 msgstr "下一步"
 
-#: src/views/preference/Preference.vue:128
+#: src/views/preference/Preference.vue:165
 msgid "Nginx"
 msgstr "Nginx"
 
-#: src/views/preference/NginxSettings.vue:11
+#: src/views/preference/NginxSettings.vue:9
 msgid "Nginx Access Log Path"
 msgstr "Nginx 存取日誌路徑"
 
@@ -1313,11 +1314,16 @@ msgstr "Nginx 存取日誌路徑"
 msgid "Nginx Configuration Parse Error"
 msgstr "Nginx 設定解析錯誤"
 
+#: src/views/preference/NginxSettings.vue:15
+#, fuzzy
+msgid "Nginx Configurations Directory"
+msgstr "Nginx 設定解析錯誤"
+
 #: src/components/NginxControl/NginxControl.vue:68
 msgid "Nginx Control"
 msgstr "Nginx 控制元件"
 
-#: src/views/preference/NginxSettings.vue:20
+#: src/views/preference/NginxSettings.vue:12
 msgid "Nginx Error Log Path"
 msgstr "Nginx 錯誤日誌路徑"
 
@@ -1329,10 +1335,28 @@ msgstr ""
 msgid "Nginx Log"
 msgstr "Nginx 日誌"
 
+#: src/views/preference/NginxSettings.vue:18
+msgid "Nginx Log Directory Whitelist"
+msgstr ""
+
+#: src/views/preference/NginxSettings.vue:27
+#, fuzzy
+msgid "Nginx PID Path"
+msgstr "Nginx 錯誤日誌路徑"
+
+#: src/views/preference/NginxSettings.vue:30
+msgid "Nginx Reload Command"
+msgstr ""
+
 #: src/components/NginxControl/NginxControl.vue:26
 msgid "Nginx reloaded successfully"
 msgstr "Nginx 重新載入成功"
 
+#: src/views/preference/NginxSettings.vue:33
+#, fuzzy
+msgid "Nginx Restart Command"
+msgstr "終端機啟動指令"
+
 #: src/components/NginxControl/NginxControl.vue:42
 msgid "Nginx restarted successfully"
 msgstr "Nginx 重啟成功"
@@ -1343,15 +1367,20 @@ msgstr "Nginx 重啟成功"
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:561
 #: src/components/StdDesign/StdDataDisplay/StdTable.vue:575
 #: src/views/notification/Notification.vue:38
-#: src/views/preference/AuthSettings.vue:104
-#: src/views/preference/BasicSettings.vue:101
+#: src/views/preference/AuthSettings.vue:138
+#: src/views/preference/CertSettings.vue:70
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:90
 #: src/views/site/ngx_conf/LocationEditor.vue:90
 #: src/views/site/SiteList.vue:151 src/views/stream/StreamList.vue:165
 msgid "No"
 msgstr "取消"
 
-#: src/views/preference/BasicSettings.vue:25
+#: src/views/preference/BasicSettings.vue:42
+#, fuzzy
+msgid "Node name"
+msgstr "新名稱"
+
+#: src/views/preference/BasicSettings.vue:23
 msgid "Node Secret"
 msgstr "Node Secret"
 
@@ -1439,11 +1468,11 @@ msgstr "驗證完成後,記錄將被刪除。"
 msgid "Online"
 msgstr "線上"
 
-#: src/views/preference/Preference.vue:134
+#: src/views/preference/Preference.vue:171
 msgid "OpenAI"
 msgstr "OpenAI"
 
-#: src/components/TwoFA/Authorization.vue:117 src/views/other/Login.vue:256
+#: src/components/TwoFA/Authorization.vue:117 src/views/other/Login.vue:254
 msgid "Or"
 msgstr ""
 
@@ -1486,7 +1515,7 @@ msgid ""
 "password replacement or as a 2FA method."
 msgstr ""
 
-#: src/views/other/Login.vue:208 src/views/user/userColumns.tsx:18
+#: src/views/other/Login.vue:206 src/views/user/userColumns.tsx:18
 msgid "Password"
 msgstr "密碼"
 
@@ -1561,11 +1590,11 @@ msgstr "請輸入名稱,這將作為新設定的檔名!"
 msgid "Please input your E-mail!"
 msgstr "請輸入您的電子郵件!"
 
-#: src/views/other/Install.vue:44 src/views/other/Login.vue:47
+#: src/views/other/Install.vue:44 src/views/other/Login.vue:46
 msgid "Please input your password!"
 msgstr "請輸入您的密碼!"
 
-#: src/views/other/Install.vue:38 src/views/other/Login.vue:41
+#: src/views/other/Install.vue:38 src/views/other/Login.vue:40
 msgid "Please input your username!"
 msgstr "請輸入您的使用者名稱!"
 
@@ -1590,7 +1619,7 @@ msgstr "請至少選擇一個節點!"
 msgid "Pre-release"
 msgstr "預先發布"
 
-#: src/routes/index.ts:260 src/views/preference/Preference.vue:111
+#: src/routes/index.ts:260 src/views/preference/Preference.vue:142
 msgid "Preference"
 msgstr "偏好設定"
 
@@ -1650,7 +1679,7 @@ msgstr "恢復碼"
 msgid "Recovery Code:"
 msgstr "恢復碼:"
 
-#: src/views/preference/BasicSettings.vue:68
+#: src/views/preference/CertSettings.vue:37
 msgid "Recursive Nameservers"
 msgstr "遞迴名稱伺服器"
 
@@ -1715,11 +1744,11 @@ msgstr "重新載入中"
 msgid "Reloading nginx"
 msgstr "正在重新載入 Nginx"
 
-#: src/views/preference/AuthSettings.vue:109
+#: src/views/preference/AuthSettings.vue:143
 msgid "Remove"
 msgstr "移除"
 
-#: src/views/preference/AuthSettings.vue:48
+#: src/views/preference/AuthSettings.vue:47
 #: src/views/preference/components/Passkey.vue:50
 msgid "Remove successfully"
 msgstr "移除成功"
@@ -1802,7 +1831,19 @@ msgstr "重新啟動"
 msgid "Restarting"
 msgstr "正在重新啟動"
 
-#: src/views/preference/BasicSettings.vue:19
+#: src/views/preference/AuthSettings.vue:81
+msgid "RP Display Name"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:87
+msgid "RP Origins"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:75
+msgid "RPID"
+msgstr ""
+
+#: src/views/preference/BasicSettings.vue:17
 msgid "Run Mode"
 msgstr "執行模式"
 
@@ -1814,7 +1855,7 @@ msgstr "執行中"
 #: src/views/certificate/CertificateEditor.vue:256
 #: src/views/config/ConfigEditor.vue:222
 #: src/views/preference/components/Passkey.vue:136
-#: src/views/preference/Preference.vue:151
+#: src/views/preference/Preference.vue:188
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:120
 #: src/views/site/SiteEdit.vue:260 src/views/stream/StreamEdit.vue:252
 msgid "Save"
@@ -1833,7 +1874,7 @@ msgstr "儲存錯誤 %{msg}"
 #: src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue:39
 #: src/components/StdDesign/StdDataDisplay/StdCurd.vue:122
 #: src/views/certificate/CertificateEditor.vue:46
-#: src/views/preference/Preference.vue:79
+#: src/views/preference/Preference.vue:110
 msgid "Save successfully"
 msgstr "儲存成功"
 
@@ -1877,13 +1918,13 @@ msgstr "傳送"
 #: src/views/config/ConfigEditor.vue:108
 #: src/views/environment/BatchUpgrader.vue:59
 #: src/views/environment/Environment.vue:15 src/views/other/Install.vue:68
-#: src/views/preference/AuthSettings.vue:50
+#: src/views/preference/AuthSettings.vue:49
 #: src/views/preference/components/Passkey.vue:26
 #: src/views/preference/components/Passkey.vue:43
 #: src/views/preference/components/Passkey.vue:56
 #: src/views/preference/components/TOTP.vue:45
 #: src/views/preference/components/TOTP.vue:58
-#: src/views/preference/Preference.vue:83 src/views/site/SiteList.vue:88
+#: src/views/preference/Preference.vue:114 src/views/site/SiteList.vue:88
 #: src/views/stream/StreamList.vue:113 src/views/stream/StreamList.vue:81
 #: src/views/system/Upgrade.vue:42
 msgid "Server error"
@@ -1893,10 +1934,6 @@ msgstr "伺服器錯誤"
 msgid "Server Info"
 msgstr "伺服器資訊"
 
-#: src/views/preference/BasicSettings.vue:117
-msgid "Server Name"
-msgstr "伺服器名稱"
-
 #: src/views/site/cert/components/ObtainCert.vue:102
 msgid "server_name not found in directives"
 msgstr "在指令中未找到 server_name"
@@ -1905,7 +1942,7 @@ msgstr "在指令中未找到 server_name"
 msgid "server_name parameter is required"
 msgstr "必須提供 server_name 參數"
 
-#: src/views/preference/BasicSettings.vue:64
+#: src/views/preference/CertSettings.vue:33
 msgid ""
 "Set the recursive nameservers to override the systems nameservers for the "
 "step of DNS challenge."
@@ -1927,7 +1964,7 @@ msgstr "使用 HTTP01 挑戰提供者"
 msgid "Show"
 msgstr "顯示"
 
-#: src/views/other/Login.vue:265
+#: src/views/other/Login.vue:263
 msgid "Sign in with a passkey"
 msgstr ""
 
@@ -1959,7 +1996,7 @@ msgstr "SSL 憑證金鑰路徑"
 msgid "SSL Certificate Path"
 msgstr "SSL 憑證路徑"
 
-#: src/views/other/Login.vue:223
+#: src/views/other/Login.vue:221
 msgid "SSO Login"
 msgstr "SSO 登錄"
 
@@ -2078,7 +2115,7 @@ msgstr "目標"
 msgid "Terminal"
 msgstr "終端機"
 
-#: src/views/preference/BasicSettings.vue:28
+#: src/views/preference/BasicSettings.vue:26
 msgid "Terminal Start Command"
 msgstr "終端機啟動指令"
 
@@ -2109,6 +2146,13 @@ msgid ""
 "dashes, and dots."
 msgstr "模型名稱應僅包含字母、Unicode、數字、連字號、破折號和點。"
 
+#: src/views/preference/BasicSettings.vue:45
+#, fuzzy
+msgid ""
+"The node name should only contain letters, unicode, numbers, hyphens, "
+"dashes, and dots."
+msgstr "模型名稱應僅包含字母、Unicode、數字、連字號、破折號和點。"
+
 #: src/views/certificate/CertificateEditor.vue:173
 msgid "The path exists, but the file is not a certificate"
 msgstr "路徑存在,但檔案不是憑證"
@@ -2131,20 +2175,14 @@ msgstr ""
 "遠端 Nginx UI 版本與本地 Nginx UI 版本不兼容。為避免潛在錯誤,請升級遠端 "
 "Nginx UI 以匹配本地版本。"
 
-#: src/views/preference/BasicSettings.vue:120
-msgid ""
-"The server name should only contain letters, unicode, numbers, hyphens, "
-"dashes, and dots."
-msgstr "伺服器名稱應僅包含字母、Unicode、數字、連字符、破折號和點。"
-
 #: src/views/site/cert/components/AutoCertStepOne.vue:45
 msgid ""
 "The server_name in the current configuration must be the domain name you "
 "need to get the certificate, supportmultiple domains."
 msgstr "當前配置中的 server_name 必須是您需要獲取憑證的網域,支持多個網域。"
 
-#: src/views/preference/BasicSettings.vue:38
-#: src/views/preference/BasicSettings.vue:50
+#: src/views/preference/BasicSettings.vue:33
+#: src/views/preference/CertSettings.vue:19
 msgid "The url is invalid"
 msgstr "網址無效"
 
@@ -2180,7 +2218,11 @@ msgid ""
 "This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
 msgstr "這將在 %{nodeNames} 上升級或重新安裝 Nginx UI 到 %{version}。"
 
-#: src/views/preference/AuthSettings.vue:67
+#: src/views/preference/AuthSettings.vue:98
+msgid "Throttle"
+msgstr ""
+
+#: src/views/preference/AuthSettings.vue:118
 #: src/views/preference/components/AddPasskey.vue:71
 #: src/views/preference/LogrotateSettings.vue:11
 msgid "Tips"
@@ -2224,7 +2266,7 @@ msgstr ""
 msgid "Token is not valid"
 msgstr "令牌無效"
 
-#: src/views/other/Login.vue:82
+#: src/views/other/Login.vue:80
 msgid "Too many login failed attempts, please try again later"
 msgstr "登錄失敗次數過多,請稍後再試"
 
@@ -2242,7 +2284,7 @@ msgstr "TOTP 是一種使用基於時間的一次性密碼算法的多重因素
 msgid "Trash"
 msgstr "垃圾桶"
 
-#: src/components/TwoFA/use2FAModal.ts:71
+#: src/components/TwoFA/use2FAModal.ts:66
 msgid "Two-factor authentication required"
 msgstr "需要多重因素驗證"
 
@@ -2313,11 +2355,11 @@ msgstr "使用恢復碼"
 msgid "User"
 msgstr "使用者名稱"
 
-#: src/views/other/Login.vue:85
+#: src/views/other/Login.vue:83
 msgid "User is banned"
 msgstr "用戶被禁止"
 
-#: src/views/other/Login.vue:198 src/views/user/userColumns.tsx:9
+#: src/views/other/Login.vue:196 src/views/user/userColumns.tsx:9
 msgid "Username"
 msgstr "使用者名稱"
 
@@ -2373,6 +2415,10 @@ msgstr ""
 "我們將從該檔案中刪除 HTTPChallenge 設定並重新載入 Nginx 設定檔案。你確定你要"
 "繼續嗎?"
 
+#: src/views/preference/AuthSettings.vue:71
+msgid "Webauthn"
+msgstr ""
+
 #: src/views/certificate/ACMEUser.vue:78
 msgid ""
 "When Enabled, Nginx UI will automatically re-register users upon startup. "
@@ -2393,8 +2439,8 @@ msgstr "將憑證私鑰寫入磁碟"
 msgid "Writing certificate to disk"
 msgstr "將憑證寫入磁碟"
 
-#: src/views/preference/AuthSettings.vue:103
-#: src/views/preference/BasicSettings.vue:100
+#: src/views/preference/AuthSettings.vue:137
+#: src/views/preference/CertSettings.vue:69
 #: src/views/site/ngx_conf/directive/DirectiveEditorItem.vue:89
 #: src/views/site/ngx_conf/LocationEditor.vue:89
 msgid "Yes"
@@ -2418,6 +2464,17 @@ msgstr ""
 msgid "Your passkeys"
 msgstr ""
 
+#~ msgid "File not found"
+#~ msgstr "找不到檔案"
+
+#~ msgid "Server Name"
+#~ msgstr "伺服器名稱"
+
+#~ msgid ""
+#~ "The server name should only contain letters, unicode, numbers, hyphens, "
+#~ "dashes, and dots."
+#~ msgstr "伺服器名稱應僅包含字母、Unicode、數字、連字符、破折號和點。"
+
 #~ msgid "Enable 2FA"
 #~ msgstr "啟用多因素身份驗證"
 
@@ -2425,9 +2482,6 @@ msgstr ""
 #~ msgid "Rename "
 #~ msgstr "使用者名稱"
 
-#~ msgid "Auto Cert"
-#~ msgstr "自動憑證"
-
 #~ msgid "Certificate has expired"
 #~ msgstr "此憑證已過期"
 

+ 1 - 3
app/src/lib/http/index.ts

@@ -1,6 +1,5 @@
 import type { AxiosRequestConfig } from 'axios'
 import axios from 'axios'
-import { useCookies } from '@vueuse/integrations/useCookies'
 import { storeToRefs } from 'pinia'
 import NProgress from 'nprogress'
 import { useSettingsStore, useUserStore } from '@/pinia'
@@ -62,10 +61,9 @@ instance.interceptors.response.use(
     NProgress.done()
 
     const otpModal = use2FAModal()
-    const cookies = useCookies(['nginx-ui-2fa'])
     switch (error.response.status) {
       case 401:
-        cookies.remove('secure_session_id')
+        secureSessionId.value = ''
         await otpModal.open()
         break
       case 403:

+ 60 - 30
app/src/pinia/moudule/user.ts

@@ -1,34 +1,64 @@
 import { defineStore } from 'pinia'
+import { useCookies } from '@vueuse/integrations/useCookies'
+import type { CookieChangeOptions } from 'universal-cookie'
 
-export const useUserStore = defineStore('user', {
-  state: () => ({
-    token: '',
-    unreadCount: 0,
-    secureSessionId: '',
-    passkeyRawId: '',
-  }),
-  getters: {
-    isLogin(state): boolean {
-      return !!state.token
-    },
-    passkeyLoginAvailable(state): boolean {
-      return !!state.passkeyRawId
-    },
-  },
-  actions: {
-    passkeyLogin(rawId: string, token: string) {
-      this.passkeyRawId = rawId
-      this.login(token)
-    },
-    login(token: string) {
-      this.token = token
-    },
-    logout() {
-      this.token = ''
-      this.passkeyRawId = ''
-      this.secureSessionId = ''
-      this.unreadCount = 0
-    },
-  },
+export const useUserStore = defineStore('user', () => {
+  const cookies = useCookies(['nginx-ui'])
+
+  const token = ref('')
+
+  watch(token, v => {
+    cookies.set('token', v, { maxAge: 86400 })
+  })
+
+  const secureSessionId = ref('')
+
+  watch(secureSessionId, v => {
+    cookies.set('secure_session_id', v, { maxAge: 60 * 3 })
+  })
+
+  function handleCookieChange({ name, value }: CookieChangeOptions) {
+    if (name === 'token')
+      token.value = value
+    else if (name === 'secure_session_id')
+      secureSessionId.value = value
+  }
+
+  cookies.addChangeListener(handleCookieChange)
+
+  const passkeyRawId = ref('')
+
+  const unreadCount = ref(0)
+  const isLogin = computed(() => !!token.value)
+  const passkeyLoginAvailable = computed(() => !!passkeyRawId.value)
+
+  function passkeyLogin(rawId: string, tokenValue: string) {
+    passkeyRawId.value = rawId
+    login(tokenValue)
+  }
+
+  function login(tokenValue: string) {
+    token.value = tokenValue
+  }
+
+  function logout() {
+    token.value = ''
+    passkeyRawId.value = ''
+    secureSessionId.value = ''
+    unreadCount.value = 0
+  }
+
+  return {
+    token,
+    unreadCount,
+    secureSessionId,
+    passkeyRawId,
+    isLogin,
+    passkeyLoginAvailable,
+    passkeyLogin,
+    login,
+    logout,
+  }
+}, {
   persist: true,
 })

+ 5 - 5
app/src/views/certificate/ACMEUser.vue

@@ -12,7 +12,7 @@ const columns: Column[] = [
   {
     title: () => $gettext('Name'),
     dataIndex: 'name',
-    sortable: true,
+    sorter: true,
     pithy: true,
     edit: {
       type: input,
@@ -23,7 +23,7 @@ const columns: Column[] = [
   }, {
     title: () => $gettext('Email'),
     dataIndex: 'email',
-    sortable: true,
+    sorter: true,
     pithy: true,
     edit: {
       type: input,
@@ -34,7 +34,7 @@ const columns: Column[] = [
   }, {
     title: () => $gettext('CA Dir'),
     dataIndex: 'ca_dir',
-    sortable: true,
+    sorter: true,
     pithy: true,
     edit: {
       type: input,
@@ -66,7 +66,7 @@ const columns: Column[] = [
 
       return <Tag color="red">{$gettext('Invalid')}</Tag>
     },
-    sortable: true,
+    sorter: true,
     pithy: true,
   }, {
     title: () => $gettext('Register On Startup'),
@@ -82,7 +82,7 @@ const columns: Column[] = [
     title: () => $gettext('Updated at'),
     dataIndex: 'updated_at',
     customRender: datetime,
-    sortable: true,
+    sorter: true,
     pithy: true,
   }, {
     title: () => $gettext('Action'),

+ 4 - 4
app/src/views/certificate/CertificateList/certColumns.tsx

@@ -9,7 +9,7 @@ import { PrivateKeyTypeMask } from '@/constants'
 const columns: Column[] = [{
   title: () => $gettext('Name'),
   dataIndex: 'name',
-  sortable: true,
+  sorter: true,
   pithy: true,
   customRender: (args: customRender) => {
     const { text, record } = args
@@ -48,13 +48,13 @@ const columns: Column[] = [{
 
     return h('div', template)
   },
-  sortable: true,
+  sorter: true,
   pithy: true,
 }, {
   title: () => $gettext('Key Type'),
   dataIndex: 'key_type',
   customRender: mask(PrivateKeyTypeMask),
-  sortable: true,
+  sorter: true,
   pithy: true,
 }, {
   title: () => $gettext('Status'),
@@ -83,7 +83,7 @@ const columns: Column[] = [{
   title: () => $gettext('Not After'),
   dataIndex: ['certificate_info', 'not_after'],
   customRender: datetime,
-  sortable: true,
+  sorter: true,
   pithy: true,
 }, {
   title: () => $gettext('Action'),

+ 3 - 3
app/src/views/certificate/DNSCredential.vue

@@ -10,7 +10,7 @@ import type { Column } from '@/components/StdDesign/types'
 const columns: Column[] = [{
   title: () => $gettext('Name'),
   dataIndex: 'name',
-  sortable: true,
+  sorter: true,
   pithy: true,
   edit: {
     type: input,
@@ -21,13 +21,13 @@ const columns: Column[] = [{
   customRender: (args: customRender) => {
     return args.record.provider
   },
-  sortable: true,
+  sorter: true,
   pithy: true,
 }, {
   title: () => $gettext('Updated at'),
   dataIndex: 'updated_at',
   customRender: datetime,
-  sortable: true,
+  sorter: true,
   pithy: true,
 }, {
   title: () => $gettext('Action'),

+ 6 - 6
app/src/views/environment/envColumns.tsx

@@ -8,7 +8,7 @@ import { datetime } from '@/components/StdDesign/StdDataDisplay/StdTableTransfor
 const columns: Column[] = [{
   title: () => $gettext('Name'),
   dataIndex: 'name',
-  sortable: true,
+  sorter: true,
   pithy: true,
   edit: {
     type: input,
@@ -18,7 +18,7 @@ const columns: Column[] = [{
 {
   title: () => $gettext('URL'),
   dataIndex: 'url',
-  sortable: true,
+  sorter: true,
   pithy: true,
   edit: {
     type: input,
@@ -35,7 +35,7 @@ const columns: Column[] = [{
 {
   title: () => 'NodeSecret',
   dataIndex: 'token',
-  sortable: true,
+  sorter: true,
   hiddenInTable: true,
   edit: {
     type: input,
@@ -97,7 +97,7 @@ const columns: Column[] = [{
 
     return h('div', template)
   },
-  sortable: true,
+  sorter: true,
   pithy: true,
 },
 {
@@ -117,14 +117,14 @@ const columns: Column[] = [{
   edit: {
     type: switcher,
   },
-  sortable: true,
+  sorter: true,
   pithy: true,
 },
 {
   title: () => $gettext('Updated at'),
   dataIndex: 'updated_at',
   customRender: datetime,
-  sortable: true,
+  sorter: true,
   pithy: true,
 },
 {

+ 2 - 2
app/src/views/notification/notificationColumns.tsx

@@ -30,7 +30,7 @@ const columns: Column[] = [{
     </Tag>
     }
   },
-  sortable: true,
+  sorter: true,
   pithy: true,
 }, {
   title: () => $gettext('Title'),
@@ -47,7 +47,7 @@ const columns: Column[] = [{
 }, {
   title: () => $gettext('Created at'),
   dataIndex: 'created_at',
-  sortable: true,
+  sorter: true,
   customRender: datetime,
   pithy: true,
 }, {

+ 3 - 5
app/src/views/other/Login.vue

@@ -1,7 +1,6 @@
 <script setup lang="ts">
 import { KeyOutlined, LockOutlined, UserOutlined } from '@ant-design/icons-vue'
 import { Form, message } from 'ant-design-vue'
-import { useCookies } from '@vueuse/integrations/useCookies'
 import { startAuthentication } from '@simplewebauthn/browser'
 import { useUserStore } from '@/pinia'
 import auth from '@/api/auth'
@@ -60,13 +59,12 @@ const onSubmit = () => {
 
     await auth.login(modelRef.username, modelRef.password, passcode.value, recoveryCode.value).then(async r => {
       const next = (route.query?.next || '').toString() || '/'
-      const cookies = useCookies(['nginx-ui-2fa'])
       switch (r.code) {
         case 200:
           message.success($gettext('Login successful'), 1)
           login(r.token)
+          await nextTick()
           secureSessionId.value = r.secure_session_id
-          cookies.set('secure_session_id', r.secure_session_id, { maxAge: 60 * 3 })
           await router.push(next)
           break
         case 199:
@@ -159,7 +157,7 @@ async function handlePasskeyLogin() {
   passkeyLoginLoading.value = true
   try {
     const begin = await auth.begin_passkey_login()
-    const asseResp = await startAuthentication(begin.options.publicKey)
+    const asseResp = await startAuthentication({ optionsJSON: begin.options.publicKey })
 
     const r = await auth.finish_passkey_login({
       session_id: begin.session_id,
@@ -170,7 +168,7 @@ async function handlePasskeyLogin() {
       const next = (route.query?.next || '').toString() || '/'
 
       passkeyLogin(asseResp.rawId, r.token)
-
+      secureSessionId.value = r.secure_session_id
       await router.push(next)
     }
   }

+ 43 - 9
app/src/views/preference/AuthSettings.vue

@@ -3,10 +3,9 @@ import { message } from 'ant-design-vue'
 import type { Ref } from 'vue'
 import dayjs from 'dayjs'
 import PasskeyRegistration from './components/Passkey.vue'
-import type { BannedIP } from '@/api/settings'
+import type { BannedIP, Settings } from '@/api/settings'
 import setting from '@/api/settings'
 import type { customRender } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
-import type { Settings } from '@/views/preference/typedef'
 import TOTP from '@/views/preference/components/TOTP.vue'
 
 const data: Settings = inject('data') as Settings
@@ -62,13 +61,41 @@ function removeBannedIP(ip: string) {
       <h2>
         {{ $gettext('Authentication Settings') }}
       </h2>
-      <AAlert
+      <div
+        v-if="data.webauthn.rpid
+          && data.webauthn.rp_display_name
+          && data.webauthn.rp_origins?.length > 0"
         class="mb-4"
-        :message="$gettext('Tips')"
-        :description="$gettext('If the number of login failed attempts from a ip reach the max attempts in ban threshold minutes,'
-          + ' the ip will be banned for a period of time.')"
-        type="info"
-      />
+      >
+        <h3>
+          {{ $gettext('Webauthn') }}
+        </h3>
+        <div class="mb-4">
+          <h4>
+            {{ $gettext('RPID') }}
+          </h4>
+          <p>{{ data.webauthn.rpid }}</p>
+        </div>
+        <div class="mb-4">
+          <h4>
+            {{ $gettext('RP Display Name') }}
+          </h4>
+          <p>{{ data.webauthn.rp_display_name }}</p>
+        </div>
+        <div>
+          <h4>
+            {{ $gettext('RP Origins') }}
+          </h4>
+          <div
+            v-for="origin in data.webauthn.rp_origins"
+            :key="origin"
+            class="mb-4"
+          >
+            {{ origin }}
+          </div>
+        </div>
+      </div>
+      <h3>{{ $gettext('Throttle') }}</h3>
       <AForm
         layout="horizontal"
         style="width:90%;max-width: 500px"
@@ -86,7 +113,14 @@ function removeBannedIP(ip: string) {
           />
         </AFormItem>
       </AForm>
-      <h3>
+      <AAlert
+        class="mb-6"
+        :message="$gettext('Tips')"
+        :description="$gettext('If the number of login failed attempts from a ip reach the max attempts in ban threshold minutes,'
+          + ' the ip will be banned for a period of time.')"
+        type="info"
+      />
+      <h3 class="mb-4">
         {{ $gettext('Banned IPs') }}
       </h3>
       <div class="mb-6">

+ 15 - 90
app/src/views/preference/BasicSettings.vue

@@ -1,7 +1,5 @@
 <script setup lang="ts">
-import Draggable from 'vuedraggable'
-import { DeleteOutlined, HolderOutlined } from '@ant-design/icons-vue'
-import type { Settings } from '@/views/preference/typedef'
+import type { Settings } from '@/api/settings'
 import SensitiveString from '@/components/SensitiveString/SensitiveString.vue'
 
 const data: Settings = inject('data') as Settings
@@ -11,116 +9,43 @@ const errors: Record<string, Record<string, string>> = inject('errors') as Recor
 <template>
   <AForm layout="vertical">
     <AFormItem :label="$gettext('HTTP Host')">
-      <p>{{ data.server.http_host }}</p>
+      <p>{{ data.server.host }}</p>
     </AFormItem>
     <AFormItem :label="$gettext('HTTP Port')">
-      <p>{{ data.server.http_port }}</p>
+      <p>{{ data.server.port }}</p>
     </AFormItem>
     <AFormItem :label="$gettext('Run Mode')">
       <p>{{ data.server.run_mode }}</p>
     </AFormItem>
     <AFormItem :label="$gettext('Jwt Secret')">
-      <SensitiveString :value="data.server.jwt_secret" />
+      <SensitiveString :value="data.app.jwt_secret" />
     </AFormItem>
     <AFormItem :label="$gettext('Node Secret')">
-      <SensitiveString :value="data.server.node_secret" />
+      <SensitiveString :value="data.node.secret" />
     </AFormItem>
     <AFormItem :label="$gettext('Terminal Start Command')">
-      <p>{{ data.server.start_cmd }}</p>
-    </AFormItem>
-    <AFormItem :label="$gettext('HTTP Challenge Port')">
-      <AInputNumber v-model:value="data.server.http_challenge_port" />
+      <p>{{ data.terminal.start_cmd }}</p>
     </AFormItem>
     <AFormItem
       :label="$gettext('Github Proxy')"
-      :validate-status="errors?.server?.github_proxy ? 'error' : ''"
-      :help="errors?.server?.github_proxy === 'url'
+      :validate-status="errors?.http?.github_proxy ? 'error' : ''"
+      :help="errors?.http?.github_proxy === 'url'
         ? $gettext('The url is invalid')
         : ''"
     >
       <AInput
-        v-model:value="data.server.github_proxy"
+        v-model:value="data.http.github_proxy"
         :placeholder="$gettext('For Chinese user: https://mirror.ghproxy.com/')"
       />
     </AFormItem>
     <AFormItem
-      :label="$gettext('CADir')"
-      :validate-status="errors?.server?.ca_dir ? 'error' : ''"
-      :help="errors?.server?.ca_dir === 'url'
-        ? $gettext('The url is invalid')
-        : ''"
-    >
-      <AInput v-model:value="data.server.ca_dir" />
-    </AFormItem>
-    <AFormItem :label="$gettext('Certificate Renewal Interval')">
-      <AInputNumber
-        v-model:value="data.server.cert_renewal_interval"
-        :min="7"
-        :max="21"
-        :addon-after="$gettext('Days')"
-      />
-    </AFormItem>
-    <AFormItem
-      :help="$gettext('Set the recursive nameservers to override the systems nameservers '
-        + 'for the step of DNS challenge.')"
-    >
-      <template #label>
-        {{ $gettext('Recursive Nameservers') }}
-        <AButton
-          type="link"
-          @click="data.server.recursive_nameservers.push('')"
-        >
-          {{ $gettext('Add') }}
-        </AButton>
-      </template>
-
-      <Draggable
-        :list="data.server.recursive_nameservers"
-        item-key="name"
-        class="list-group"
-        ghost-class="ghost"
-        handle=".anticon-holder"
-      >
-        <template #item="{ index }">
-          <ARow>
-            <ACol :span="2">
-              <HolderOutlined class="p-2" />
-            </ACol>
-            <ACol :span="20">
-              <AInput
-                v-model:value="data.server.recursive_nameservers[index]"
-                :status="errors?.server?.recursive_nameservers?.[index] ? 'error' : undefined"
-                placeholder="8.8.8.8:53"
-                class="mb-4"
-              />
-            </ACol>
-            <ACol :span="2">
-              <APopconfirm
-                :title="$gettext('Are you sure you want to remove this item?')"
-                :ok-text="$gettext('Yes')"
-                :cancel-text="$gettext('No')"
-                @confirm="data.server.recursive_nameservers.splice(index, 1)"
-              >
-                <AButton
-                  type="link"
-                  danger
-                >
-                  <DeleteOutlined />
-                </AButton>
-              </APopconfirm>
-            </ACol>
-          </ARow>
-        </template>
-      </Draggable>
-    </AFormItem>
-    <AFormItem
-      :label="$gettext('Server Name')"
-      :validate-status="errors?.server?.name ? 'error' : ''"
-      :help="errors?.server?.name.includes('safety_text')
-        ? $gettext('The server name should only contain letters, unicode, numbers, hyphens, dashes, and dots.')
-        : $gettext('Customize the name of local server to be displayed in the environment indicator.')"
+      :label="$gettext('Node name')"
+      :validate-status="errors?.node?.name ? 'error' : ''"
+      :help="errors?.node?.name.includes('safety_text')
+        ? $gettext('The node name should only contain letters, unicode, numbers, hyphens, dashes, and dots.')
+        : $gettext('Customize the name of local node to be displayed in the environment indicator.')"
     >
-      <AInput v-model:value="data.server.name" />
+      <AInput v-model:value="data.node.name" />
     </AFormItem>
   </AForm>
 </template>

+ 90 - 0
app/src/views/preference/CertSettings.vue

@@ -0,0 +1,90 @@
+<script setup lang="ts">
+import Draggable from 'vuedraggable'
+import { DeleteOutlined, HolderOutlined } from '@ant-design/icons-vue'
+import type { Settings } from '@/api/settings'
+
+const data: Settings = inject('data') as Settings
+const errors: Record<string, Record<string, string>> = inject('errors') as Record<string, Record<string, string>>
+</script>
+
+<template>
+  <AForm layout="vertical">
+    <AFormItem :label="$gettext('HTTP Challenge Port')">
+      <AInputNumber v-model:value="data.cert.http_challenge_port" />
+    </AFormItem>
+    <AFormItem
+      :label="$gettext('CADir')"
+      :validate-status="errors?.cert?.ca_dir ? 'error' : ''"
+      :help="errors?.cert?.ca_dir === 'url'
+        ? $gettext('The url is invalid')
+        : ''"
+    >
+      <AInput v-model:value="data.cert.ca_dir" />
+    </AFormItem>
+    <AFormItem :label="$gettext('Certificate Renewal Interval')">
+      <AInputNumber
+        v-model:value="data.cert.renewal_interval"
+        :min="7"
+        :max="21"
+        :addon-after="$gettext('Days')"
+      />
+    </AFormItem>
+    <AFormItem
+      :help="$gettext('Set the recursive nameservers to override the systems nameservers '
+        + 'for the step of DNS challenge.')"
+    >
+      <template #label>
+        {{ $gettext('Recursive Nameservers') }}
+        <AButton
+          type="link"
+          @click="data.cert.recursive_nameservers.push('')"
+        >
+          {{ $gettext('Add') }}
+        </AButton>
+      </template>
+
+      <Draggable
+        :list="data.cert.recursive_nameservers"
+        item-key="name"
+        class="list-group"
+        ghost-class="ghost"
+        handle=".anticon-holder"
+      >
+        <template #item="{ index }">
+          <ARow>
+            <ACol :span="2">
+              <HolderOutlined class="p-2" />
+            </ACol>
+            <ACol :span="20">
+              <AInput
+                v-model:value="data.cert.recursive_nameservers[index]"
+                :status="errors?.cert?.recursive_nameservers?.[index] ? 'error' : undefined"
+                placeholder="8.8.8.8:53"
+                class="mb-4"
+              />
+            </ACol>
+            <ACol :span="2">
+              <APopconfirm
+                :title="$gettext('Are you sure you want to remove this item?')"
+                :ok-text="$gettext('Yes')"
+                :cancel-text="$gettext('No')"
+                @confirm="data.cert.recursive_nameservers.splice(index, 1)"
+              >
+                <AButton
+                  type="link"
+                  danger
+                >
+                  <DeleteOutlined />
+                </AButton>
+              </APopconfirm>
+            </ACol>
+          </ARow>
+        </template>
+      </Draggable>
+    </AFormItem>
+  </AForm>
+</template>
+
+<style lang="less" scoped>
+
+</style>

+ 1 - 1
app/src/views/preference/LogrotateSettings.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import type { Settings } from '@/views/preference/typedef'
+import type { Settings } from '@/api/settings'
 
 const data: Settings = inject('data')!
 </script>

+ 24 - 16
app/src/views/preference/NginxSettings.vue

@@ -1,30 +1,38 @@
 <script setup lang="ts">
-import type { Settings } from '@/views/preference/typedef'
+import type { Settings } from '@/api/settings'
 
 const data: Settings = inject('data')!
-const errors: Record<string, Record<string, string>> = inject('errors') as Record<string, Record<string, string>>
 </script>
 
 <template>
   <AForm layout="vertical">
-    <AFormItem
-      :label="$gettext('Nginx Access Log Path')"
-      :validate-status="errors?.nginx?.access_log_path ? 'error' : ''"
-      :help="errors?.nginx?.access_log_path === 'file'
-        ? $gettext('File not found')
-        : ''"
-    >
+    <AFormItem :label="$gettext('Nginx Access Log Path')">
       {{ data.nginx.access_log_path }}
     </AFormItem>
-    <AFormItem
-      :label="$gettext('Nginx Error Log Path')"
-      :validate-status="errors?.nginx?.error_log_path ? 'error' : ''"
-      :help="errors?.nginx?.error_log_path === 'file'
-        ? $gettext('File not found')
-        : ''"
-    >
+    <AFormItem :label="$gettext('Nginx Error Log Path')">
       {{ data.nginx.error_log_path }}
     </AFormItem>
+    <AFormItem :label="$gettext('Nginx Configurations Directory')">
+      {{ data.nginx.config_dir }}
+    </AFormItem>
+    <AFormItem :label="$gettext('Nginx Log Directory Whitelist')">
+      <div
+        v-for="dir in data.nginx.log_dir_white_list"
+        :key="dir"
+        class="mb-2"
+      >
+        {{ dir }}
+      </div>
+    </AFormItem>
+    <AFormItem :label="$gettext('Nginx PID Path')">
+      {{ data.nginx.pid_path }}
+    </AFormItem>
+    <AFormItem :label="$gettext('Nginx Reload Command')">
+      {{ data.nginx.reload_cmd }}
+    </AFormItem>
+    <AFormItem :label="$gettext('Nginx Restart Command')">
+      {{ data.nginx.restart_cmd }}
+    </AFormItem>
   </AForm>
 </template>
 

+ 1 - 1
app/src/views/preference/OpenAISettings.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import type { Settings } from '@/views/preference/typedef'
+import type { Settings } from '@/api/settings'
 
 const data: Settings = inject('data')!
 const errors: Record<string, Record<string, string>> = inject('errors') as Record<string, Record<string, string>>

+ 57 - 20
app/src/views/preference/Preference.vue

@@ -7,55 +7,86 @@ import settings from '@/api/settings'
 import BasicSettings from '@/views/preference/BasicSettings.vue'
 import OpenAISettings from '@/views/preference/OpenAISettings.vue'
 import NginxSettings from '@/views/preference/NginxSettings.vue'
-import type { Settings } from '@/views/preference/typedef'
+import type { Settings } from '@/api/settings'
 import LogrotateSettings from '@/views/preference/LogrotateSettings.vue'
 import { useSettingsStore } from '@/pinia'
 import AuthSettings from '@/views/preference/AuthSettings.vue'
 import use2FAModal from '@/components/TwoFA/use2FAModal'
+import CertSettings from '@/views/preference/CertSettings.vue'
 
 const data = ref<Settings>({
+  app: {
+    page_size: 10,
+    jwt_secret: '',
+  },
   server: {
-    http_host: '0.0.0.0',
-    http_port: '9000',
+    host: '0.0.0.0',
+    port: 9000,
     run_mode: 'debug',
-    jwt_secret: '',
-    start_cmd: '',
+  },
+  database: {
+    name: '',
+  },
+  auth: {
+    ip_white_list: [],
+    ban_threshold_minutes: 10,
+    max_attempts: 10,
+  },
+  casdoor: {
+    endpoint: '',
+    client_id: '',
+    client_secret: '',
+    certificate_path: '',
+    organization: '',
+    application: '',
+    redirect_uri: '',
+  },
+  cert: {
     email: '',
-    http_challenge_port: '9180',
-    github_proxy: '',
     ca_dir: '',
-    node_secret: '',
-    cert_renewal_interval: 7,
+    renewal_interval: 7,
     recursive_nameservers: [],
-    name: '',
+    http_challenge_port: '9180',
+  },
+  http: {
+    github_proxy: '',
+    insecure_skip_verify: false,
+  },
+  logrotate: {
+    enabled: false,
+    cmd: '',
+    interval: 1440,
   },
   nginx: {
     access_log_path: '',
     error_log_path: '',
     config_dir: '',
+    log_dir_white_list: [],
     pid_path: '',
     reload_cmd: '',
     restart_cmd: '',
   },
+  node: {
+    name: '',
+    secret: '',
+  },
   openai: {
     model: '',
     base_url: '',
     proxy: '',
     token: '',
   },
-  logrotate: {
-    enabled: false,
-    cmd: '',
-    interval: 1440,
+  terminal: {
+    start_cmd: '',
   },
-  auth: {
-    ip_white_list: [],
-    ban_threshold_minutes: 10,
-    max_attempts: 10,
+  webauthn: {
+    rp_display_name: '',
+    rpid: '',
+    rp_origins: [],
   },
 })
 
-settings.get<Settings>().then(r => {
+settings.get().then(r => {
   data.value = r
 })
 
@@ -66,7 +97,7 @@ const refAuthSettings = ref()
 
 async function save() {
   // fix type
-  data.value.server.http_challenge_port = data.value.server.http_challenge_port.toString()
+  data.value.cert.http_challenge_port = data.value.cert.http_challenge_port.toString()
 
   const otpModal = use2FAModal()
 
@@ -123,6 +154,12 @@ onMounted(() => {
         >
           <AuthSettings ref="refAuthSettings" />
         </ATabPane>
+        <ATabPane
+          key="cert"
+          :tab="$gettext('Cert')"
+        >
+          <CertSettings />
+        </ATabPane>
         <ATabPane
           key="nginx"
           :tab="$gettext('Nginx')"

+ 0 - 41
app/src/views/preference/typedef.ts

@@ -1,41 +0,0 @@
-export interface Settings {
-  server: {
-    http_host: string
-    http_port: string
-    run_mode: string
-    jwt_secret: string
-    node_secret: string
-    start_cmd: string
-    http_challenge_port: string
-    github_proxy: string
-    email: string
-    ca_dir: string
-    cert_renewal_interval: number
-    recursive_nameservers: string[]
-    name: string
-  }
-  nginx: {
-    access_log_path: string
-    error_log_path: string
-    config_dir: string
-    pid_path: string
-    reload_cmd: string
-    restart_cmd: string
-  }
-  openai: {
-    model: string
-    base_url: string
-    proxy: string
-    token: string
-  }
-  logrotate: {
-    enabled: boolean
-    cmd: string
-    interval: number
-  }
-  auth: {
-    ip_white_list: string[]
-    ban_threshold_minutes: number
-    max_attempts: number
-  }
-}

+ 3 - 3
app/src/views/site/SiteList.vue

@@ -12,7 +12,7 @@ import type { Column, JSXElements } from '@/components/StdDesign/types'
 const columns: Column[] = [{
   title: () => $gettext('Name'),
   dataIndex: 'name',
-  sortable: true,
+  sorter: true,
   pithy: true,
   edit: {
     type: input,
@@ -42,13 +42,13 @@ const columns: Column[] = [{
       false: $gettext('Disabled'),
     },
   },
-  sortable: true,
+  sorter: true,
   pithy: true,
 }, {
   title: () => $gettext('Updated at'),
   dataIndex: 'modified_at',
   customRender: datetime,
-  sortable: true,
+  sorter: true,
   pithy: true,
 }, {
   title: () => $gettext('Action'),

+ 3 - 3
app/src/views/stream/StreamList.vue

@@ -12,7 +12,7 @@ import StreamDuplicate from '@/views/stream/components/StreamDuplicate.vue'
 const columns: Column[] = [{
   title: () => $gettext('Name'),
   dataIndex: 'name',
-  sortable: true,
+  sorter: true,
   pithy: true,
   edit: {
     type: input,
@@ -35,13 +35,13 @@ const columns: Column[] = [{
 
     return h('div', template)
   },
-  sortable: true,
+  sorter: true,
   pithy: true,
 }, {
   title: () => $gettext('Updated at'),
   dataIndex: 'modified_at',
   customRender: datetime,
-  sortable: true,
+  sorter: true,
   pithy: true,
 }, {
   title: () => $gettext('Action'),

+ 5 - 5
app/src/views/user/userColumns.tsx

@@ -8,7 +8,7 @@ import { datetime } from '@/components/StdDesign/StdDataDisplay/StdTableTransfor
 const columns: Column[] = [{
   title: () => $gettext('Username'),
   dataIndex: 'name',
-  sortable: true,
+  sorter: true,
   pithy: true,
   edit: {
     type: input,
@@ -17,7 +17,7 @@ const columns: Column[] = [{
 }, {
   title: () => $gettext('Password'),
   dataIndex: 'password',
-  sortable: true,
+  sorter: true,
   pithy: true,
   edit: {
     type: password,
@@ -42,19 +42,19 @@ const columns: Column[] = [{
 
     return h('div', template)
   },
-  sortable: true,
+  sorter: true,
   pithy: true,
 }, {
   title: () => $gettext('Created at'),
   dataIndex: 'created_at',
   customRender: datetime,
-  sortable: true,
+  sorter: true,
   pithy: true,
 }, {
   title: () => $gettext('Updated at'),
   dataIndex: 'updated_at',
   customRender: datetime,
-  sortable: true,
+  sorter: true,
   pithy: true,
 }, {
   title: () => $gettext('Action'),

+ 8 - 8
cmd/generate/generate.go

@@ -4,7 +4,7 @@ import (
 	"flag"
 	"fmt"
 	"github.com/0xJacky/Nginx-UI/model"
-	"github.com/0xJacky/Nginx-UI/settings"
+	"github.com/uozi-tech/cosy/settings"
 	"gorm.io/driver/sqlite"
 	"gorm.io/gen"
 	"gorm.io/gorm"
@@ -21,26 +21,26 @@ func main() {
 		Mode:    gen.WithoutContext | gen.WithDefaultQuery,
 		//if you want the nullable field generation property to be pointer type, set FieldNullable true
 		FieldNullable: true,
-		//if you want to assign field which has default value in `Create` API, set FieldCoverable true, reference: https://gorm.io/docs/create.html#Default-Values
+		//if you want to assign field which has the default value in `Create` API, set FieldCoverable true, reference: https://gorm.io/docs/create.html#Default-Values
 		FieldCoverable: true,
-		// if you want to generate field with unsigned integer type, set FieldSignable true
+		// if you want to generate field with an unsigned integer type, set FieldSignable true
 		/* FieldSignable: true,*/
-		//if you want to generate index tags from database, set FieldWithIndexTag true
+		//if you want to generate index tags from the database, set FieldWithIndexTag true
 		/* FieldWithIndexTag: true,*/
-		//if you want to generate type tags from database, set FieldWithTypeTag true
+		//if you want to generate type tags from the database, set FieldWithTypeTag true
 		/* FieldWithTypeTag: true,*/
 		//if you need unit tests for query code, set WithUnitTest true
 		/* WithUnitTest: true, */
 	})
 
 	// reuse the database connection in Project or create a connection here
-	// if you want to use GenerateModel/GenerateModelAs, UseDB is necessary or it will panic
+	// if you want to use GenerateModel/GenerateModelAs, UseDB is necessary, or it will panic
 	var confPath string
 	flag.StringVar(&confPath, "config", "app.ini", "Specify the configuration file")
 	flag.Parse()
 
 	settings.Init(confPath)
-	dbPath := path.Join(path.Dir(settings.ConfPath), fmt.Sprintf("%s.db", settings.ServerSettings.Database))
+	dbPath := path.Join(path.Dir(confPath), fmt.Sprintf("%s.db", settings.DataBaseSettings.Name))
 
 	var err error
 	db, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{
@@ -56,7 +56,7 @@ func main() {
 	g.UseDB(db)
 
 	// apply basic crud api on structs or table models which is specified by table name with function
-	// GenerateModel/GenerateModelAs. And generator will generate table models' code when calling Excute.
+	// GenerateModel/GenerateModelAs. And the generator will generate table models' code when calling Excute.
 	g.ApplyBasic(model.GenerateAllModel()...)
 
 	// apply diy interfaces on structs or table models

+ 21 - 14
docker-compose-demo.yml

@@ -1,17 +1,24 @@
-version: '3'
 services:
-    nginx-demo-1:
-        image: uozi/nginx-ui-demo:latest
-        restart: always
-        networks:
-            - nginx-ui-network
-        ports:
-            - "9003:80"
+  nginx-demo-1:
+    image: uozi/nginx-ui-demo:latest
+    restart: always
+    networks:
+      - nginx-ui-network
+    environment:
+      - NGINX_UI_NODE_DEMO=true
+    ports:
+      - "9003:80"
+
+  nginx-demo-2:
+    image: uozi/nginx-ui-demo:latest
+    restart: always
+    environment:
+      - NGINX_UI_NODE_DEMO=true
+    networks:
+      - nginx-ui-network
 
-    nginx-demo-2:
-        image: uozi/nginx-ui-demo:latest
-        restart: always
-        networks:
-            - nginx-ui-network
 networks:
-    nginx-ui-network:
+  nginx-ui-network:
+    driver: bridge
+    driver_opts:
+      com.docker.network.bridge.enable_ip_masquerade: 'false'

+ 10 - 4
docs/.vitepress/config/en.ts

@@ -34,14 +34,20 @@ export const enConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
           text: 'Configuration',
           collapsed: false,
           items: [
+            {text: 'App', link: '/guide/config-app'},
             {text: 'Server', link: '/guide/config-server'},
-            {text: 'Nginx', link: '/guide/config-nginx'},
-            {text: 'Open AI', link: '/guide/config-openai'},
+            {text: 'Database', link: '/guide/config-database'},
+            {text: 'Auth', link: '/guide/config-auth'},
             {text: 'Casdoor', link: '/guide/config-casdoor'},
-            {text: 'Logrotate', link: '/guide/config-logrotate'},
+            {text: 'Cert', link: '/guide/config-cert'},
             {text: 'Cluster', link: '/guide/config-cluster'},
-            {text: 'Auth', link: '/guide/config-auth'},
             {text: 'Crypto', link: '/guide/config-crypto'},
+            {text: 'Http', link: '/guide/config-http'},
+            {text: 'Logrotate', link: '/guide/config-logrotate'},
+            {text: 'Nginx', link: '/guide/config-nginx'},
+            {text: 'Node', link: '/guide/config-node'},
+            {text: 'Open AI', link: '/guide/config-openai'},
+            {text: 'Terminal', link: '/guide/config-terminal'},
             {text: 'Webauthn', link: '/guide/config-webauthn'}
           ]
         },

+ 13 - 7
docs/.vitepress/config/zh_CN.ts

@@ -39,15 +39,21 @@ export const zhCNConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
           text: '配置',
           collapsed: false,
           items: [
-            {text: '服务端', link: '/zh_CN/guide/config-server'},
-            {text: 'Nginx', link: '/zh_CN/guide/config-nginx'},
-            {text: 'Open AI', link: '/zh_CN/guide/config-openai'},
+            {text: 'App', link: '/zh_CN/guide/config-app'},
+            {text: 'Server', link: '/zh_CN/guide/config-server'},
+            {text: 'Database', link: '/zh_CN/guide/config-database'},
+            {text: 'Auth', link: '/zh_CN/guide/config-auth'},
             {text: 'Casdoor', link: '/zh_CN/guide/config-casdoor'},
+            {text: 'Cert', link: '/zh_CN/guide/config-cert'},
+            {text: 'Cluster', link: '/zh_CN/guide/config-cluster'},
+            {text: 'Crypto', link: '/zh_CN/guide/config-crypto'},
+            {text: 'Http', link: '/zh_CN/guide/config-http'},
             {text: 'Logrotate', link: '/zh_CN/guide/config-logrotate'},
-            {text: '集群', link: '/zh_CN/guide/config-cluster'},
-            {text: '认证', link: '/zh_CN/guide/config-auth'},
-            {text: '加密', link: '/zh_CN/guide/config-crypto'},
-            {text: 'Webauthn', link: '/zh_CN/guide/config-webauthn'},
+            {text: 'Nginx', link: '/zh_CN/guide/config-nginx'},
+            {text: 'Node', link: '/zh_CN/guide/config-node'},
+            {text: 'Open AI', link: '/zh_CN/guide/config-openai'},
+            {text: 'Terminal', link: '/zh_CN/guide/config-terminal'},
+            {text: 'Webauthn', link: '/zh_CN/guide/config-webauthn'}
           ]
         },
         {

+ 13 - 7
docs/.vitepress/config/zh_TW.ts

@@ -39,15 +39,21 @@ export const zhTWConfig: LocaleSpecificConfig<DefaultTheme.Config> = {
           text: '配置',
           collapsed: false,
           items: [
-            {text: '服務端', link: '/zh_TW/guide/config-server'},
-            {text: 'Nginx', link: '/zh_TW/guide/config-nginx'},
-            {text: 'Open AI', link: '/zh_TW/guide/config-openai'},
+            {text: 'App', link: '/zh_TW/guide/config-app'},
+            {text: 'Server', link: '/zh_TW/guide/config-server'},
+            {text: 'Database', link: '/zh_TW/guide/config-database'},
+            {text: 'Auth', link: '/zh_TW/guide/config-auth'},
             {text: 'Casdoor', link: '/zh_TW/guide/config-casdoor'},
+            {text: 'Cert', link: '/zh_TW/guide/config-cert'},
+            {text: 'Cluster', link: '/zh_TW/guide/config-cluster'},
+            {text: 'Crypto', link: '/zh_TW/guide/config-crypto'},
+            {text: 'Http', link: '/zh_TW/guide/config-http'},
             {text: 'Logrotate', link: '/zh_TW/guide/config-logrotate'},
-            {text: '集群', link: '/zh_TW/guide/config-cluster'},
-            {text: '認證', link: '/zh_TW/guide/config-auth'},
-            {text: '加密', link: '/zh_TW/guide/config-crypto'},
-            {text: 'Webauthn', link: '/zh_TW/guide/config-webauthn'},
+            {text: 'Nginx', link: '/zh_TW/guide/config-nginx'},
+            {text: 'Node', link: '/zh_TW/guide/config-node'},
+            {text: 'Open AI', link: '/zh_TW/guide/config-openai'},
+            {text: 'Terminal', link: '/zh_TW/guide/config-terminal'},
+            {text: 'Webauthn', link: '/zh_TW/guide/config-webauthn'}
           ]
         },
         {

+ 20 - 0
docs/guide/config-app.md

@@ -0,0 +1,20 @@
+# App
+
+## PageSize
+
+- Type: `int`
+- Default: 10
+- Version: `>=v2.0.0-beta.37`
+
+This option is used to set the page size of list pagination in the Nginx UI. Adjusting the page size can help in
+managing large amounts of data more effectively, but a too large number can increase the load on the server.
+
+## JwtSecret
+- Type: `string`
+- Version: `>=v2.0.0-beta.37`
+
+This option is used to configure the key used by the Nginx UI server to generate JWT.
+
+JWT is a standard for verifying user identity. It can generate a token after the user logs in, and then use the token to verify the user's identity in subsequent requests.
+
+If you use the one-click installation script to deploy Nginx UI, the script will generate a UUID value and set it as the value of this option.

+ 43 - 0
docs/guide/config-cert.md

@@ -0,0 +1,43 @@
+# Cert
+
+## CADir
+- Type: `string`
+- Version:`>= v2.0.0-beta.37`
+
+When applying for a Let's Encrypt certificate, we use the default CA address of Let's Encrypt. If you need to debug or
+obtain certificates from other providers, you can set CADir to their address.
+
+::: tip
+Please note that the address provided by
+CADir needs to comply with the `RFC 8555` standard.
+:::
+
+## RecursiveNameservers
+
+- Version:`>= v2.0.0-beta.37`
+- Type: `[]string`
+- Example: `8.8.8.8:53,1.1.1.1:53`
+
+This option is used to set the recursive nameservers used by
+Nginx UI in the DNS challenge step of applying for a certificate.
+If this option is not configured, Nginx UI will use the nameservers settings of the operating system.
+
+
+## CertRenewalInterval
+
+- Version:`>= v2.0.0-beta.37`
+- Type: `int`
+- Default value: `7`
+
+This option is used to set the automatic renewal interval of the Let's Encrypt certificate.
+By default, Nginx UI will automatically renew the certificate every 7 days.
+
+## HTTPChallengePort
+
+- Version:`>= v2.0.0-beta.37`
+- Type: `int`
+- Default: `9180`
+
+This option is used to set the port for backend listening in the HTTP01 challenge mode when obtaining Let's Encrypt
+certificates. The HTTP01 challenge is a domain validation method used by Let's Encrypt to verify that you control the
+domain for which you're requesting a certificate.

+ 8 - 0
docs/guide/config-database.md

@@ -0,0 +1,8 @@
+# Database
+
+## Name
+- Type: `string`
+- Default: `database`
+- Version: `>=v2.0.0-beta.37`
+
+This option is used to set the name of the sqlite database used by Nginx UI to store its data.

+ 18 - 0
docs/guide/config-http.md

@@ -0,0 +1,18 @@
+# Http
+
+## GithubProxy
+
+- Type: `string`
+- Version: `>= v2.0.0-beta.37`
+- Suggestion: `https://mirror.ghproxy.com/`
+
+For users who may experience difficulties downloading resources from GitHub (such as in mainland China), this option
+allows them to set a proxy for github.com to improve accessibility.
+
+## InsecureSkipVerify
+
+- Version:`>= v2.0.0-beta.37`
+- Type: `bool`
+
+This option is used to skip the verification of the certificate of servers when Nginx UI sends requests to them.
+

+ 16 - 0
docs/guide/config-node.md

@@ -0,0 +1,16 @@
+# Node
+
+## Name
+
+- Version:`>= v2.0.0-beta.37`
+- Type: `string`
+
+Use this option to customize the name of local server to be displayed in the environment indicator.
+
+
+## Secret
+- Type: `string`
+- Version: `>= v2.0.0-beta.37`
+
+This secret is used to authenticate the communication between the Nginx UI servers.
+Also, you can use this secret to access the Nginx UI API without a password.

+ 98 - 11
docs/guide/config-server.md

@@ -3,19 +3,20 @@
 The server section of the Nginx UI configuration deals with various settings that control the behavior and operation of
 the Nginx UI server. In this section, we will discuss the available options, their default values, and their purpose.
 
-## HttpHost
+## Host
 - Type: `string`
+- Version: `>= v2.0.0-beta.37`
 - Default:`0.0.0.0`
 
 The hostname on which the Nginx UI server listens for incoming HTTP requests.
 Changing the default hostname can be useful for improving the security of Nginx UI.
 
-## HttpPort
-
-- Type: `int`
+## Port
+- Type: `uint`
+- Version: `>= v2.0.0-beta.37`
 - Default: `9000`
 
-Nginx UI server listen port. This option is used to configure the port on which the Nginx UI server listens for incoming
+This option is used to configure the port on which the Nginx UI server listens for incoming
 HTTP requests. Changing the default port can be useful for avoiding port conflicts or enhancing security.
 
 ## RunMode
@@ -32,20 +33,62 @@ When using the `debug` mode, Nginx UI will print SQL and its execution time and
 
 When using the `release` mode, Nginx UI will not print the execution time and caller of SQL on the console, and only the log of `Info` level or higher will be printed.
 
+## HttpHost
+- Type: `string`
+- Default:`0.0.0.0`
+
+::: warning
+Deprecated in `v2.0.0-beta.37`, please use `Host` instead.
+:::
+
+The hostname on which the Nginx UI server listens for incoming HTTP requests.
+Changing the default hostname can be useful for improving the security of Nginx UI.
+
+## HttpPort
+- Type: `int`
+- Default: `9000`
+
+::: warning
+Deprecated in `v2.0.0-beta.37`, please use `Port` instead.
+:::
+
+This option is used to configure the port on which the Nginx UI server listens for incoming
+HTTP requests. Changing the default port can be useful for avoiding port conflicts or enhancing security.
+
+
 ## JwtSecret
 - Type: `string`
 
+::: warning
+Deprecated in `v2.0.0-beta.37`, please use `App.JwtSecret` instead.
+:::
+
 This option is used to configure the key used by the Nginx UI server to generate JWT.
 
 JWT is a standard for verifying user identity. It can generate a token after the user logs in, and then use the token to verify the user's identity in subsequent requests.
 
 If you use the one-click installation script to deploy Nginx UI, the script will generate a UUID value and set it as the value of this option.
 
+## NodeSecret
+- Type: `string`
+- Version: `>= v2.0.0-beta.24, <= 2.0.0-beta.36`
+
+::: warning
+Deprecated in `v2.0.0-beta.37`, please use `Node.Secret` instead.
+:::
+
+This secret is used to authenticate the communication between the Nginx UI servers.
+Also, you can use this secret to access the Nginx UI API without a password.
+
 ## HTTPChallengePort
 
 - Type: `int`
 - Default: `9180`
 
+::: warning
+Deprecated in `v2.0.0-beta.37`, please use `Cert.HTTPChallengePort` instead.
+:::
+
 This option is used to set the port for backend listening in the HTTP01 challenge mode when obtaining Let's Encrypt
 certificates. The HTTP01 challenge is a domain validation method used by Let's Encrypt to verify that you control the
 domain for which you're requesting a certificate.
@@ -53,6 +96,10 @@ domain for which you're requesting a certificate.
 ## Email
 - Type: `string`
 
+::: warning
+Deprecated in `v2.0.0-beta.37`, please use `Cert.Email` instead.
+:::
+
 When obtaining a Let's Encrypt certificate, this option is used to set your email address.
 Let's Encrypt will use your email address to notify you of the expiration date of your certificate.
 
@@ -61,6 +108,10 @@ Let's Encrypt will use your email address to notify you of the expiration date o
 - Type: `string`
 - Default: `database`
 
+::: warning
+Deprecated in `v2.0.0-beta.37`, please use `Database.Name` instead.
+:::
+
 This option is used to set the name of the sqlite database used by Nginx UI to store its data.
 
 ## StartCmd
@@ -68,6 +119,10 @@ This option is used to set the name of the sqlite database used by Nginx UI to s
 - Type: `string`
 - Default: `login`
 
+::: warning
+Deprecated in `v2.0.0-beta.37`, please use `Terminal.StartCmd` instead.
+:::
+
 This option is used to set the start command of the web terminal.
 
 ::: warning
@@ -81,6 +136,10 @@ terminal, please set it to `bash` or `zsh` (if installed).
 - Type: `int`
 - Default: 10
 
+::: warning
+Deprecated in `v2.0.0-beta.37`, please use `App.PageSize` instead.
+:::
+
 This option is used to set the page size of list pagination in the Nginx UI. Adjusting the page size can help in
 managing large amounts of data more effectively, but a too large number can increase the load on the server.
 
@@ -88,6 +147,10 @@ managing large amounts of data more effectively, but a too large number can incr
 
 - Type: `string`
 
+::: warning
+Deprecated in `v2.0.0-beta.37`, please use `Cert.CADir` instead.
+:::
+
 When applying for a Let's Encrypt certificate, we use the default CA address of Let's Encrypt. If you need to debug or
 obtain certificates from other providers, you can set CADir to their address.
 
@@ -101,37 +164,53 @@ CADir needs to comply with the `RFC 8555` standard.
 - Type: `string`
 - Suggestion: `https://mirror.ghproxy.com/`
 
+::: warning
+Deprecated in `v2.0.0-beta.37`, please use `Http.GithubProxy` instead.
+:::
+
 For users who may experience difficulties downloading resources from GitHub (such as in mainland China), this option
 allows them to set a proxy for github.com to improve accessibility.
 
 ## CertRenewalInterval
 
-- Version:`>= v2.0.0-beta.22`
+- Version:`>= v2.0.0-beta.22, <= 2.0.0-beta.36`
 - Type: `int`
 - Default value: `7`
 
+::: warning
+Deprecated in `v2.0.0-beta.37`, please use `Cert.CertRenewalInterval` instead.
+:::
+
 This option is used to set the automatic renewal interval of the Let's Encrypt certificate.
 By default, Nginx UI will automatically renew the certificate every 7 days.
 
 ## RecursiveNameservers
 
-- Version:`>= v2.0.0-beta.22`
+- Version:`>= v2.0.0-beta.22, <= 2.0.0-beta.36`
 - Type: `[]string`
 - Example: `8.8.8.8:53,1.1.1.1:53`
 
+::: warning
+Deprecated in `v2.0.0-beta.37`, please use `Cert.RecursiveNameservers` instead.
+:::
+
 This option is used to set the recursive nameservers used by
 Nginx UI in the DNS challenge step of applying for a certificate.
 If this option is not configured, Nginx UI will use the nameservers settings of the operating system.
 
 ## SkipInstallation
 
-- Version:`>= v2.0.0-beta.23`
+- Version:`>= v2.0.0-beta.23, <= 2.0.0-beta.36`
 - Type: `bool`
 - Default value: `false`
 
+::: warning
+Deprecated in `v2.0.0-beta.37`, please use `Node.SkipInstallation` instead.
+:::
+
 You can skip the installation of the Nginx UI server by setting this option to `true`.
 This is useful when you want to deploy Nginx UI to multiple servers with
-a same configuration file or environment variables.
+the same configuration file or environment variables.
 
 By default, if you enabled the skip installation mode without setting the `JWTSecret` and `NodeSecret` options
 in the server section, Nginx UI will generate a random UUID value for these two options.
@@ -141,14 +220,22 @@ Nginx UI will not create a system initial acme user, this means you can't apply
 
 ## Name
 
-- Version:`>= v2.0.0-beta.23`
+- Version:`>= v2.0.0-beta.23, <= 2.0.0-beta.36`
 - Type: `string`
 
+::: warning
+Deprecated in `v2.0.0-beta.37`, please use `Http.InsecureSkipVerify` instead.
+:::
+
 Use this option to customize the name of local server to be displayed in the environment indicator.
 
 ## InsecureSkipVerify
 
-- Version:`>= v2.0.0-beta.30`
+- Version:`>= v2.0.0-beta.30, <= 2.0.0-beta.36`
 - Type: `bool`
 
+::: warning
+Deprecated in `v2.0.0-beta.37`, please use `Http.InsecureSkipVerify` instead.
+:::
+
 This option is used to skip the verification of the certificate of servers when Nginx UI sends requests to them.

+ 15 - 0
docs/guide/config-terminal.md

@@ -0,0 +1,15 @@
+# Terminal
+
+## StartCmd
+
+- Type: `string`
+- Default: `login`
+- Version: `>= v2.0.0-beta.37`
+
+This option is used to set the start command of the web terminal.
+
+::: warning
+For security reason, we use `login` as the start command, so you have to log in via the default authentication method of
+the Linux. If you don't want to enter your username and password for verification every time you access the web
+terminal, please set it to `bash` or `zsh` (if installed).
+:::

+ 75 - 44
docs/guide/env.md

@@ -1,53 +1,34 @@
 # Environment Variables
 
-Applicable for version v2.0.0-beta.23 and above.
+Applicable for version v2.0.0-beta.37 and above.
+
+## App
+| Configuration Setting | Environment Variable    |
+|-----------------------|-------------------------|
+| PageSize              | NGINX_UI_APP_PAGE_SIZE  |
+| JwtSecret             | NGINX_UI_APP_JWT_SECRET |
 
-## Server
 
+## Server
 | Configuration Setting | Environment Variable                  |
 |-----------------------|---------------------------------------|
-| HttpPort              | NGINX_UI_SERVER_HTTP_PORT             |
+| Host                  | NGINX_UI_SERVER_HOST                  |
+| Port                  | NGINX_UI_SERVER_PORT                  |
 | RunMode               | NGINX_UI_SERVER_RUN_MODE              |
-| JwtSecret             | NGINX_UI_SERVER_JWT_SECRET            |
-| HTTPChallengePort     | NGINX_UI_SERVER_HTTP_CHALLENGE_PORT   |
-| StartCmd              | NGINX_UI_SERVER_START_CMD             |
-| Database              | NGINX_UI_SERVER_DATABASE              |
-| CADir                 | NGINX_UI_SERVER_CA_DIR                |
-| GithubProxy           | NGINX_UI_SERVER_GITHUB_PROXY          |
-| NodeSecret            | NGINX_UI_SERVER_NODE_SECRET           |
-| Demo                  | NGINX_UI_SERVER_DEMO                  |
-| PageSize              | NGINX_UI_SERVER_PAGE_SIZE             |
-| HttpHost              | NGINX_UI_SERVER_HTTP_HOST             |
-| CertRenewalInterval   | NGINX_UI_SERVER_CERT_RENEWAL_INTERVAL |
-| RecursiveNameservers  | NGINX_UI_SERVER_RECURSIVE_NAMESERVERS |
-| SkipInstallation      | NGINX_UI_SERVER_SKIP_INSTALLATION     |
-| Name                  | NGINX_UI_SERVER_NAME                  |
-| InsecureSkipVerify    | NGINX_UI_SERVER_INSECURE_SKIP_VERIFY  |
-
-## Nginx
-
-| Configuration Setting | Environment Variable              |
-|-----------------------|-----------------------------------|
-| AccessLogPath         | NGINX_UI_NGINX_ACCESS_LOG_PATH    |
-| ErrorLogPath          | NGINX_UI_NGINX_ERROR_LOG_PATH     |
-| ConfigDir             | NGINX_UI_NGINX_CONFIG_DIR         |
-| PIDPath               | NGINX_UI_NGINX_PID_PATH           |
-| TestConfigCmd         | NGINX_UI_NGINX_TEST_CONFIG_CMD    |
-| ReloadCmd             | NGINX_UI_NGINX_RELOAD_CMD         |
-| RestartCmd            | NGINX_UI_NGINX_RESTART_CMD        |
-| LogDirWhiteList       | NGINX_UI_NGINX_LOG_DIR_WHITE_LIST |
 
-## OpenAI
+## Database
+| Configuration Setting | Environment Variable |
+|-----------------------|----------------------|
+| Name                  | NGINX_UI_DB_NAME     |
 
-| Configuration Setting | Environment Variable     |
-|-----------------------|--------------------------|
-| Model                 | NGINX_UI_OPENAI_MODEL    |
-| BaseUrl               | NGINX_UI_OPENAI_BASE_URL |
-| Proxy                 | NGINX_UI_OPENAI_PROXY    |
-| Token                 | NGINX_UI_OPENAI_TOKEN    |
+## Auth
+| Configuration Setting | Environment Variable                |
+|-----------------------|-------------------------------------|
+| IPWhiteList           | NGINX_UI_AUTH_IP_WHITE_LIST         |
+| BanThresholdMinutes   | NGINX_UI_AUTH_BAN_THRESHOLD_MINUTES |
+| MaxAttempts           | NGINX_UI_AUTH_MAX_ATTEMPTS          |
 
 ## Casdoor
-
 | Configuration Setting | Environment Variable              |
 |-----------------------|-----------------------------------|
 | Endpoint              | NGINX_UI_CASDOOR_ENDPOINT         |
@@ -58,19 +39,69 @@ Applicable for version v2.0.0-beta.23 and above.
 | Application           | NGINX_UI_CASDOOR_APPLICATION      |
 | RedirectUri           | NGINX_UI_CASDOOR_REDIRECT_URI     |
 
-## Logrotate
+## Cert
+| Configuration Setting | Environment Variable                |
+|-----------------------|-------------------------------------|
+| Email                 | NGINX_UI_CERT_EMAIL                 |
+| CADir                 | NGINX_UI_CERT_CA_DIR                |
+| RenewalInterval       | NGINX_UI_CERT_RENEWAL_INTERVAL      |
+| RecursiveNameservers  | NGINX_UI_CERT_RECURSIVE_NAMESERVERS |
+| HTTPChallengePort     | NGINX_UI_CERT_HTTP_CHALLENGE_PORT   |
+
+## Cluster
+| Configuration Setting | Environment Variable  |
+|-----------------------|-----------------------|
+| Node                  | NGINX_UI_CLUSTER_NODE |
+
+## Crypto
+| Configuration Setting | Environment Variable    |
+|-----------------------|-------------------------|
+| Secret                | NGINX_UI_CRYPTO_SECRET  |
+
+## Http
+| Configuration Setting | Environment Variable               |
+|-----------------------|------------------------------------|
+| GithubProxy           | NGINX_UI_HTTP_GITHUB_PROXY         |
+| InsecureSkipVerify    | NGINX_UI_HTTP_INSECURE_SKIP_VERIFY |
 
+## Logrotate
 | Configuration Setting | Environment Variable        |
 |-----------------------|-----------------------------|
 | Enabled               | NGINX_UI_LOGROTATE_ENABLED  |
 | CMD                   | NGINX_UI_LOGROTATE_CMD      |
 | Interval              | NGINX_UI_LOGROTATE_INTERVAL |
 
-## Auth
+## Nginx
+| Configuration Setting | Environment Variable              |
+|-----------------------|-----------------------------------|
+| AccessLogPath         | NGINX_UI_NGINX_ACCESS_LOG_PATH    |
+| ErrorLogPath          | NGINX_UI_NGINX_ERROR_LOG_PATH     |
+| ConfigDir             | NGINX_UI_NGINX_CONFIG_DIR         |
+| PIDPath               | NGINX_UI_NGINX_PID_PATH           |
+| TestConfigCmd         | NGINX_UI_NGINX_TEST_CONFIG_CMD    |
+| ReloadCmd             | NGINX_UI_NGINX_RELOAD_CMD         |
+| RestartCmd            | NGINX_UI_NGINX_RESTART_CMD        |
+| LogDirWhiteList       | NGINX_UI_NGINX_LOG_DIR_WHITE_LIST |
+
+## Node
+| Configuration Setting | Environment Variable            |
+|-----------------------|---------------------------------|
+| Name                  | NGINX_UI_NODE_NAME              |
+| Secret                | NGINX_UI_NODE_SECRET            |
+| SkipInstallation      | NGINX_UI_NODE_SKIP_INSTALLATION |
+
+## OpenAI
+| Configuration Setting | Environment Variable     |
+|-----------------------|--------------------------|
+| Model                 | NGINX_UI_OPENAI_MODEL    |
+| BaseUrl               | NGINX_UI_OPENAI_BASE_URL |
+| Proxy                 | NGINX_UI_OPENAI_PROXY    |
+| Token                 | NGINX_UI_OPENAI_TOKEN    |
 
-| Configuration Setting | Environment Variable      |
-|-----------------------|---------------------------|
-| IPWhiteList           | NGINX_UI_AUTH_IPWhiteList |
+## Terminal
+| Configuration Setting | Environment Variable                |
+|-----------------------|-------------------------------------|
+| StartCmd              | NGINX_UI_TERMINAL_START_CMD         |
 
 ## Webauthn
 

+ 19 - 0
docs/zh_CN/guide/config-app.md

@@ -0,0 +1,19 @@
+# App
+
+## PageSize
+
+- 类型: `int`
+- 默认值: 10
+- 版本: `>=v2.0.0-beta.37`
+
+此选项用于设置 Nginx UI 中列表分页的页面大小。调整页面大小可以更有效地管理大量数据,但过大的数字会增加服务器的负载。
+
+## JwtSecret
+- 类型: `string`
+- 版本: `>=v2.0.0-beta.37`
+
+此选项用于配置 Nginx UI 服务器生成 JWT 的密钥。
+
+JWT 是一种验证用户身份的标准。用户登录后可以生成一个令牌,然后在后续请求中使用该令牌验证用户身份。
+
+如果您使用一键安装脚本部署 Nginx UI,脚本将生成一个 UUID 值并将其设置为此选项的值。

+ 2 - 2
docs/zh_CN/guide/config-auth.md

@@ -19,12 +19,12 @@ IPWhiteList = 2001:0000:130F:0000:0000:09C0:876A:130B
 
 ## BanThresholdMinutes
 - Type: `int`
-- Default: `10`
+- 默认值:`10`
 
 默认情况下,如果用户在 10 分钟内登录失败 10 次,用户将被禁止登录 10 分钟。
 
 ## MaxAttempts
 - Type: `int`
-- Default: `10`
+- 默认值:`10`
 
 默认情况下,用户可以在 10 分钟内尝试登录 10 次。

+ 37 - 0
docs/zh_CN/guide/config-cert.md

@@ -0,0 +1,37 @@
+# Cert
+
+## CADir
+- 类型: `string`
+- 版本:`>= v2.0.0-beta.37`
+
+在申请 Let's Encrypt 证书时,我们使用 Let's Encrypt 的默认 CA 地址。
+如果您需要调试或从其他提供商获取证书,您可以将 CADir 设置为他们的地址。
+
+::: tip 提示
+请注意,CADir 提供的地址需要符合 `RFC 8555` 标准。
+:::
+
+## RecursiveNameservers
+
+- 版本:`>= v2.0.0-beta.37`
+- 类型: `[]string`
+- 示例: `8.8.8.8:53,1.1.1.1:53`
+
+此选项用于设置 Nginx UI 在申请证书的 DNS 挑战步骤所使用的递归域名服务器。在不配置此项目的情况下,Nginx UI 使用操作系统的域名服务器设置。
+
+## CertRenewalInterval
+
+- 版本:`>= v2.0.0-beta.37`
+- 类型: `int`
+- 默认值: `7`
+
+此选项用于设置 Let's Encrypt 证书的自动续签间隔。默认情况下,Nginx UI 每隔 7 天会自动续签证书。
+
+## HTTPChallengePort
+
+- 版本:`>= v2.0.0-beta.37`
+- 类型: `int`
+- 默认值: `9180`
+
+在获取 Let's Encrypt 证书时,此选项用于在 HTTP01 挑战模式中设置后端监听端口。
+HTTP01 挑战是 Let's Encrypt 用于验证您控制请求证书的域的域验证方法。

+ 1 - 1
docs/zh_CN/guide/config-crypto.md

@@ -1,6 +1,6 @@
 # Crypto
 
 ## Secret
-- Type: `string`
+- 类型: `string`
 
 如果这个值为空,Nginx UI 将会自动生成一个随机的密钥。这个密钥用于加密存储在数据库中的敏感数据。

+ 8 - 0
docs/zh_CN/guide/config-database.md

@@ -0,0 +1,8 @@
+# Database
+
+## Name
+- 类型: `string`
+- 默认值: `database`
+- 版本: `>=v2.0.0-beta.37`
+
+此选项用于设置 Nginx UI 用于存储其数据的 sqlite 数据库的名称。

+ 15 - 0
docs/zh_CN/guide/config-http.md

@@ -0,0 +1,15 @@
+# Http
+
+## GithubProxy
+- 版本: `>= v2.0.0-beta.37`
+- 类型:`string`
+- 建议:`https://mirror.ghproxy.com/`
+
+- 对于可能在从 Github 下载资源时遇到困难的用户(如在中国大陆),此选项允许他们为 github.com 设置代理,以提高可访问性。
+
+## InsecureSkipVerify
+
+- 版本:`>= v2.0.0-beta.37`
+- 类型: `bool`
+
+此选项用于配置 Nginx UI 服务器在与其他服务器建立 TLS 连接时是否跳过证书验证。

+ 16 - 0
docs/zh_CN/guide/config-node.md

@@ -0,0 +1,16 @@
+# Node
+
+## Name
+
+- 版本:`>= v2.0.0-beta.37`
+- 类型:`string`
+
+使用此选项自定义本地服务器的名称,以在环境指示器中显示。
+
+
+## Secret
+- 类型: `string`
+- 版本: `>= v2.0.0-beta.37`
+
+此密钥用于验证 Nginx UI 服务器之间的通信。
+此外,您可以使用此密钥在不使用密码的情况下访问 Nginx UI API。

+ 101 - 17
docs/zh_CN/guide/config-server.md

@@ -1,19 +1,20 @@
-# 服务端
+# Server
 
 Nginx UI 配置的服务端部分涉及控制 Nginx UI 服务器的各种设置。在页面中,我们将讨论可用的选项、它们的默认值以及它们的目的。
 
-## HttpHost
+## Host
 - 类型: `string`
-- 默认值:`0.0.0.0`
+- 版本: `>= v2.0.0-beta.37`
+- Default:`0.0.0.0`
 
 Nginx UI 服务器监听的主机名。此选项用于配置 Nginx UI 服务器监听传入 HTTP 请求的主机名。 更改默认主机名可能有助于提升安全性。
 
-## HttpPort
-
-- 类型:`int`
+## Port
+- Type: `uint`
+- 版本: `>= v2.0.0-beta.37`
 - 默认值:`9000`
 
-Nginx UI 服务器监听端口。此选项用于配置 Nginx UI 服务器监听传入 HTTP 请求的端口。更改默认端口对于避免端口冲突或增强安全性可能很有用。
+此选项用于配置 Nginx UI 服务器监听传入 HTTP 请求的端口。更改默认端口对于避免端口冲突或增强安全性可能很有用。
 
 ## RunMode
 
@@ -29,8 +30,32 @@ Nginx UI 的日志分为 6 个级别,分别为 `Debug`、`Info`、`Warn`、`Er
 
 当使用 `release` 模式时,Nginx UI 将不会在控制台打印 SQL 的执行时间和调用者, 只有 `Info` 级别或更高等级的日志才会被打印。
 
+## HttpHost
+- 类型: `string`
+- Default:`0.0.0.0`
+
+::: warning 警告
+已在 `v2.0.0-beta.37` 中废弃,请使用 `Host` 替代。
+:::
+
+Nginx UI 服务器监听的主机名。此选项用于配置 Nginx UI 服务器监听传入 HTTP 请求的主机名。 更改默认主机名可能有助于提升安全性。
+
+## HttpPort
+- Type: `int`
+- 默认值:`9000`
+
+::: warning 警告
+已在 `v2.0.0-beta.37` 中废弃,请使用 `Port` 替代。
+:::
+
+此选项用于配置 Nginx UI 服务器监听传入 HTTP 请求的端口。更改默认端口对于避免端口冲突或增强安全性可能很有用。
+
 ## JwtSecret
-- 类型:`string`
+- 类型: `string`
+
+::: warning 警告
+已在 `v2.0.0-beta.37` 中废弃,请使用 `App.JwtSecret` 替代。
+:::
 
 此选项用于配置 Nginx UI 服务器用于生成 JWT 的密钥。
 
@@ -38,17 +63,36 @@ JWT 是一种用于验证用户身份的标准,它可以在用户登录后生
 
 如果您使用一键安装脚本来部署 Nginx UI,脚本将会生成一个 UUID 值并将它设置为此选项的值。
 
+## NodeSecret
+- 类型: `string`
+- 版本: `>= v2.0.0-beta.24, <= 2.0.0-beta.36`
+
+::: warning 警告
+已在 `v2.0.0-beta.37` 中废弃,请使用 `Node.Secret` 替代。
+:::
+
+此密钥用于验证 Nginx UI 服务器之间的通信。
+此外,您可以使用此密钥在不使用密码的情况下访问 Nginx UI API。
+
 ## HTTPChallengePort
 
 - 类型:`int`
 - 默认值:`9180`
 
+::: warning 警告
+已在 `v2.0.0-beta.37` 中废弃,请使用 `Cert.HTTPChallengePort` 替代。
+:::
+
 在获取 Let's Encrypt 证书时,此选项用于在 HTTP01 挑战模式中设置后端监听端口。HTTP01 挑战是 Let's Encrypt
 用于验证您控制请求证书的域的域验证方法。
 
 ## Email
 - 类型:`string`
 
+::: warning 警告
+已在 `v2.0.0-beta.37` 中废弃,请使用 `Cert.Email` 替代。
+:::
+
 在获取 Let's Encrypt 证书时,此选项用于设置您的电子邮件地址。Let's Encrypt 会将您的电子邮件地址用于通知您证书的到期时间。
 
 ## Database
@@ -56,6 +100,10 @@ JWT 是一种用于验证用户身份的标准,它可以在用户登录后生
 - 类型:`string`
 - 默认值:`database`
 
+::: warning 警告
+已在 `v2.0.0-beta.37` 中废弃,请使用 `Database.Name` 替代。
+:::
+
 此选项用于设置 Nginx UI 用于存储其数据的 sqlite 数据库的名称。
 
 ## StartCmd
@@ -63,6 +111,10 @@ JWT 是一种用于验证用户身份的标准,它可以在用户登录后生
 - 类型:`string`
 - 默认值:`login`
 
+::: warning 警告
+已在 `v2.0.0-beta.37` 中废弃,请使用 `Terminal.StartCmd` 替代。
+:::
+
 此选项用于设置 Web 终端的启动命令。
 
 ::: warning 警告
@@ -75,11 +127,19 @@ JWT 是一种用于验证用户身份的标准,它可以在用户登录后生
 - 类型:`int`
 - 默认值:`10`
 
+::: warning 警告
+已在 `v2.0.0-beta.37` 中废弃,请使用 `App.PageSize` 替代。
+:::
+
 此选项用于设置 Nginx UI 中列表分页的页面大小。调整页面大小有助于更有效地管理大量数据,但是过大的数量可能会增加服务器的压力。
 
 ## CADir
 
-- 类型:`string`
+- 类型: `string`
+
+::: warning 警告
+已在 `v2.0.0-beta.37` 中废弃,请使用 `Cert.CADir` 替代。
+:::
 
 在申请 Let's Encrypt 证书时,我们使用 Let's Encrypt 的默认 CA 地址。如果您需要调试或从其他提供商获取证书,您可以将 CADir
 设置为他们的地址。
@@ -93,29 +153,45 @@ JWT 是一种用于验证用户身份的标准,它可以在用户登录后生
 - 类型:`string`
 - 建议:`https://mirror.ghproxy.com/`
 
+::: warning 警告
+已在 `v2.0.0-beta.37` 中废弃,请使用 `Http.GithubProxy` 替代。
+:::
+
 对于可能在从 Github 下载资源时遇到困难的用户(如在中国大陆),此选项允许他们为 github.com 设置代理,以提高可访问性。
 
 ## CertRenewalInterval
 
-- 版本:`>= v2.0.0-beta.22`
+- 版本:`>= v2.0.0-beta.22, <= 2.0.0-beta.36`
 - 类型:`int`
 - 默认值: `7`
 
+::: warning 警告
+已在 `v2.0.0-beta.37` 中废弃,请使用 `Cert.CertRenewalInterval` 替代。
+:::
+
 此选项用于设置 Let's Encrypt 证书的自动续签间隔。默认情况下,Nginx UI 每隔 7 天会自动续签证书。
 
 ## RecursiveNameservers
 
-- 版本:`>= v2.0.0-beta.22`
+- 版本:`>= v2.0.0-beta.22, <= 2.0.0-beta.36`
 - 类型: `[]string`
 - 示例: `8.8.8.8:53,1.1.1.1:53`
 
+::: warning 警告
+已在 `v2.0.0-beta.37` 中废弃,请使用 `Cert.RecursiveNameservers` 替代。
+:::
+
 此选项用于设置 Nginx UI 在申请证书的 DNS 挑战步骤所使用的递归域名服务器。在不配置此项目的情况下,Nginx UI 使用操作系统的域名服务器设置。
 
 ## SkipInstallation
 
-- 版本:`>= v2.0.0-beta.23`
-- 类型:`bool`
-- 默认值:`false`
+- 版本:`>= v2.0.0-beta.23, <= 2.0.0-beta.36`
+- 类型: `bool`
+- 默认值: `false`
+
+::: warning 警告
+已在 `v2.0.0-beta.37` 中废弃,请使用 `Node.SkipInstallation` 替代。
+:::
 
 通过将此选项设置为 `true`,您可以跳过 Nginx UI 服务器的安装。
 当您希望使用相同的配置文件或环境变量将 Nginx UI 部署到多个服务器时,这非常有用。
@@ -128,14 +204,22 @@ Nginx UI 将不会创建系统初始的 acme 用户,这意味着您无法在
 
 ## Name
 
-- 版本:`>= v2.0.0-beta.23`
-- 类型:`string`
+- 版本:`>= v2.0.0-beta.23, <= 2.0.0-beta.36`
+- 类型: `string`
+
+::: warning 警告
+已在 `v2.0.0-beta.37` 中废弃,请使用 `Http.InsecureSkipVerify` 替代。
+:::
 
 使用此选项自定义本地服务器的名称,以在环境指示器中显示。
 
 ## InsecureSkipVerify
 
-- 版本:`>= v2.0.0-beta.30`
+- 版本:`>= v2.0.0-beta.30, <= 2.0.0-beta.36`
 - 类型: `bool`
 
+::: warning 警告
+已在 `v2.0.0-beta.37` 中废弃,请使用 `Http.InsecureSkipVerify` 替代。
+:::
+
 此选项用于配置 Nginx UI 服务器在与其他服务器建立 TLS 连接时是否跳过证书验证。

+ 14 - 0
docs/zh_CN/guide/config-terminal.md

@@ -0,0 +1,14 @@
+# Terminal
+
+## StartCmd
+
+- 类型: `string`
+- 默认值: `login`
+- 版本: `>= v2.0.0-beta.37`
+
+此选项用于设置 Web 终端的启动命令。
+
+::: warning 警告
+出于安全原因,我们将启动命令设置为 `login`,因此您必须通过 Linux 的默认身份验证方法登录。
+如果您不想每次访问 Web 终端时都输入用户名和密码进行验证,请将其设置为 `bash` 或 `zsh`(如果已安装)。
+:::

+ 105 - 61
docs/zh_CN/guide/env.md

@@ -1,84 +1,128 @@
 # 环境变量
 
-适用于 v2.0.0-beta.23 及以上版本
+适用于 v2.0.0-beta.37 及以上版本。
+
+## App
+
+| 配置        | 环境变量                    |
+|-----------|-------------------------|
+| PageSize  | NGINX_UI_APP_PAGE_SIZE  |
+| JwtSecret | NGINX_UI_APP_JWT_SECRET |
 
 ## Server
 
-| Configuration Setting | Environment Variable                  |
-|-----------------------|---------------------------------------|
-| HttpPort              | NGINX_UI_SERVER_HTTP_PORT             |
-| RunMode               | NGINX_UI_SERVER_RUN_MODE              |
-| JwtSecret             | NGINX_UI_SERVER_JWT_SECRET            |
-| HTTPChallengePort     | NGINX_UI_SERVER_HTTP_CHALLENGE_PORT   |
-| StartCmd              | NGINX_UI_SERVER_START_CMD             |
-| Database              | NGINX_UI_SERVER_DATABASE              |
-| CADir                 | NGINX_UI_SERVER_CA_DIR                |
-| GithubProxy           | NGINX_UI_SERVER_GITHUB_PROXY          |
-| NodeSecret            | NGINX_UI_SERVER_NODE_SECRET           |
-| Demo                  | NGINX_UI_SERVER_DEMO                  |
-| PageSize              | NGINX_UI_SERVER_PAGE_SIZE             |
-| HttpHost              | NGINX_UI_SERVER_HTTP_HOST             |
-| CertRenewalInterval   | NGINX_UI_SERVER_CERT_RENEWAL_INTERVAL |
-| RecursiveNameservers  | NGINX_UI_SERVER_RECURSIVE_NAMESERVERS |
-| SkipInstallation      | NGINX_UI_SERVER_SKIP_INSTALLATION     |
-| Name                  | NGINX_UI_SERVER_NAME                  |
-| InsecureSkipVerify    | NGINX_UI_SERVER_INSECURE_SKIP_VERIFY  |
+| 配置      | 环境变量                     |
+|---------|--------------------------|
+| Host    | NGINX_UI_SERVER_HOST     |
+| Port    | NGINX_UI_SERVER_PORT     |
+| RunMode | NGINX_UI_SERVER_RUN_MODE |
 
-## Nginx
+## Database
 
-| Configuration Setting | Environment Variable              |
-|-----------------------|-----------------------------------|
-| AccessLogPath         | NGINX_UI_NGINX_ACCESS_LOG_PATH    |
-| ErrorLogPath          | NGINX_UI_NGINX_ERROR_LOG_PATH     |
-| ConfigDir             | NGINX_UI_NGINX_CONFIG_DIR         |
-| PIDPath               | NGINX_UI_NGINX_PID_PATH           |
-| TestConfigCmd         | NGINX_UI_NGINX_TEST_CONFIG_CMD    |
-| ReloadCmd             | NGINX_UI_NGINX_RELOAD_CMD         |
-| RestartCmd            | NGINX_UI_NGINX_RESTART_CMD        |
-| LogDirWhiteList       | NGINX_UI_NGINX_LOG_DIR_WHITE_LIST |
+| 配置   | 环境变量             |
+|------|------------------|
+| Name | NGINX_UI_DB_NAME |
 
-## OpenAI
+## Auth
 
-| Configuration Setting | Environment Variable     |
-|-----------------------|--------------------------|
-| Model                 | NGINX_UI_OPENAI_MODEL    |
-| BaseUrl               | NGINX_UI_OPENAI_BASE_URL |
-| Proxy                 | NGINX_UI_OPENAI_PROXY    |
-| Token                 | NGINX_UI_OPENAI_TOKEN    |
+| 配置                  | 环境变量                                |
+|---------------------|-------------------------------------|
+| IPWhiteList         | NGINX_UI_AUTH_IP_WHITE_LIST         |
+| BanThresholdMinutes | NGINX_UI_AUTH_BAN_THRESHOLD_MINUTES |
+| MaxAttempts         | NGINX_UI_AUTH_MAX_ATTEMPTS          |
 
 ## Casdoor
 
-| Configuration Setting | Environment Variable              |
-|-----------------------|-----------------------------------|
-| Endpoint              | NGINX_UI_CASDOOR_ENDPOINT         |
-| ClientId              | NGINX_UI_CASDOOR_CLIENT_ID        |
-| ClientSecret          | NGINX_UI_CASDOOR_CLIENT_SECRET    |
-| CertificatePath       | NGINX_UI_CASDOOR_CERTIFICATE_PATH |
-| Organization          | NGINX_UI_CASDOOR_ORGANIZATION     |
-| Application           | NGINX_UI_CASDOOR_APPLICATION      |
-| RedirectUri           | NGINX_UI_CASDOOR_REDIRECT_URI     |
+| 配置              | 环境变量                              |
+|-----------------|-----------------------------------|
+| Endpoint        | NGINX_UI_CASDOOR_ENDPOINT         |
+| ClientId        | NGINX_UI_CASDOOR_CLIENT_ID        |
+| ClientSecret    | NGINX_UI_CASDOOR_CLIENT_SECRET    |
+| CertificatePath | NGINX_UI_CASDOOR_CERTIFICATE_PATH |
+| Organization    | NGINX_UI_CASDOOR_ORGANIZATION     |
+| Application     | NGINX_UI_CASDOOR_APPLICATION      |
+| RedirectUri     | NGINX_UI_CASDOOR_REDIRECT_URI     |
+
+## Cert
+
+| 配置                   | 环境变量                                |
+|----------------------|-------------------------------------|
+| Email                | NGINX_UI_CERT_EMAIL                 |
+| CADir                | NGINX_UI_CERT_CA_DIR                |
+| RenewalInterval      | NGINX_UI_CERT_RENEWAL_INTERVAL      |
+| RecursiveNameservers | NGINX_UI_CERT_RECURSIVE_NAMESERVERS |
+| HTTPChallengePort    | NGINX_UI_CERT_HTTP_CHALLENGE_PORT   |
+
+## Cluster
+
+| 配置   | 环境变量                  |
+|------|-----------------------|
+| Node | NGINX_UI_CLUSTER_NODE |
+
+## Crypto
+
+| 配置     | 环境变量                   |
+|--------|------------------------|
+| Secret | NGINX_UI_CRYPTO_SECRET |
+
+## Http
+
+| 配置                 | 环境变量                               |
+|--------------------|------------------------------------|
+| GithubProxy        | NGINX_UI_HTTP_GITHUB_PROXY         |
+| InsecureSkipVerify | NGINX_UI_HTTP_INSECURE_SKIP_VERIFY |
 
 ## Logrotate
 
-| Configuration Setting | Environment Variable        |
-|-----------------------|-----------------------------|
-| Enabled               | NGINX_UI_LOGROTATE_ENABLED  |
-| CMD                   | NGINX_UI_LOGROTATE_CMD      |
-| Interval              | NGINX_UI_LOGROTATE_INTERVAL |
+| 配置       | 环境变量                        |
+|----------|-----------------------------|
+| Enabled  | NGINX_UI_LOGROTATE_ENABLED  |
+| CMD      | NGINX_UI_LOGROTATE_CMD      |
+| Interval | NGINX_UI_LOGROTATE_INTERVAL |
 
-## Auth
+## Nginx
+
+| 配置              | 环境变量                              |
+|-----------------|-----------------------------------|
+| AccessLogPath   | NGINX_UI_NGINX_ACCESS_LOG_PATH    |
+| ErrorLogPath    | NGINX_UI_NGINX_ERROR_LOG_PATH     |
+| ConfigDir       | NGINX_UI_NGINX_CONFIG_DIR         |
+| PIDPath         | NGINX_UI_NGINX_PID_PATH           |
+| TestConfigCmd   | NGINX_UI_NGINX_TEST_CONFIG_CMD    |
+| ReloadCmd       | NGINX_UI_NGINX_RELOAD_CMD         |
+| RestartCmd      | NGINX_UI_NGINX_RESTART_CMD        |
+| LogDirWhiteList | NGINX_UI_NGINX_LOG_DIR_WHITE_LIST |
+
+## Node
+
+| 配置               | 环境变量                            |
+|------------------|---------------------------------|
+| Name             | NGINX_UI_NODE_NAME              |
+| Secret           | NGINX_UI_NODE_SECRET            |
+| SkipInstallation | NGINX_UI_NODE_SKIP_INSTALLATION |
+
+## OpenAI
+
+| 配置      | 环境变量                     |
+|---------|--------------------------|
+| Model   | NGINX_UI_OPENAI_MODEL    |
+| BaseUrl | NGINX_UI_OPENAI_BASE_URL |
+| Proxy   | NGINX_UI_OPENAI_PROXY    |
+| Token   | NGINX_UI_OPENAI_TOKEN    |
+
+## Terminal
 
-| Configuration Setting | Environment Variable      |
-|-----------------------|---------------------------|
-| IPWhiteList           | NGINX_UI_AUTH_IPWhiteList |
+| 配置       | 环境变量                        |
+|----------|-----------------------------|
+| StartCmd | NGINX_UI_TERMINAL_START_CMD |
 
 ## Webauthn
 
-| Configuration Setting | Environment Variable              |
-|-----------------------|-----------------------------------|
-| RPDisplayName         | NGINX_UI_WEBAUTHN_RP_DISPLAY_NAME |
-| RPID                  | NGINX_UI_WEBAUTHN_RPID            |
-| RPOrigins             | NGINX_UI_WEBAUTHN_RP_ORIGINS      |
+| 配置            | 环境变量                              |
+|---------------|-----------------------------------|
+| RPDisplayName | NGINX_UI_WEBAUTHN_RP_DISPLAY_NAME |
+| RPID          | NGINX_UI_WEBAUTHN_RPID            |
+| RPOrigins     | NGINX_UI_WEBAUTHN_RP_ORIGINS      |
 
 ## 预定义用户
 

+ 1 - 1
docs/zh_CN/guide/nginx-ui-template.md

@@ -4,7 +4,7 @@ Nginx UI Template 提供了一种开箱即用的配置模板机制。在 NgxConf
 在本篇指南中,我们将绍这种配置模板的文件格式和语法规则。
 配置模板文件存储在 `template/block` 目录中,我们欢迎并期待您通过提交 [PR](https://github.com/0xJacky/nginx-ui/pulls) 的形式分享您编写的配置模板。
 
-::: tip
+::: tip 提示
 请注意,每次修改或添加新的配置文件后,需要重新编译后端以生效。
 :::
 

+ 20 - 0
docs/zh_TW/guide/config-app.md

@@ -0,0 +1,20 @@
+# App
+
+## PageSize
+
+- 類型: `int`
+- 預設值: 10
+- 版本: `>=v2.0.0-beta.37`
+
+此選項用於設置 Nginx UI 中列表分頁的頁面大小。調整頁面大小可以更有效地管理大量數據,但過大的數字會增加伺服器的負載。
+
+## JwtSecret
+
+- 類型: `string`
+- 版本: `>=v2.0.0-beta.37`
+
+此選項用於配置 Nginx UI 伺服器生成 JWT 的密鑰。
+
+JWT 是一種驗證用戶身份的標準。用戶登錄後可以生成一個令牌,然後在後續請求中使用該令牌驗證用戶身份。
+
+如果您使用一鍵安裝腳本部署 Nginx UI,腳本將生成一個 UUID 值並將其設置為此選項的值。

+ 35 - 0
docs/zh_TW/guide/config-cert.md

@@ -0,0 +1,35 @@
+## CADir
+- 類型: `string`
+- 版本:`>= v2.0.0-beta.37`
+
+在申請 Let's Encrypt 證書時,我們使用 Let's Encrypt 的默認 CA 地址。
+如果您需要調試或從其他提供商獲取證書,您可以將 CADir 設置為他們的地址。
+
+::: tip 提示
+請注意,CADir 提供的地址需要符合 `RFC 8555` 標準。
+:::
+
+## RecursiveNameservers
+
+- 版本:`>= v2.0.0-beta.37`
+- 類型: `[]string`
+- 示例: `8.8.8.8:53,1.1.1.1:53`
+
+此選項用於設置 Nginx UI 在申請證書的 DNS 挑戰步驟所使用的遞歸域名伺服器。在不配置此項目的情況下,Nginx UI 使用操作系統的域名伺服器設置。
+
+## CertRenewalInterval
+
+- 版本:`>= v2.0.0-beta.37`
+- 類型: `int`
+- 默認值: `7`
+
+此選項用於設置 Let's Encrypt 證書的自動續簽間隔。默認情況下,Nginx UI 每隔 7 天會自動續簽證書。
+
+## HTTPChallengePort
+
+- 版本:`>= v2.0.0-beta.37`
+- 類型: `int`
+- 默認值: `9180`
+
+在獲取 Let's Encrypt 證書時,此選項用於在 HTTP01 挑戰模式中設置後端監聽端口。
+HTTP01 挑戰是 Let's Encrypt 用於驗證您控制請求證書的域的域驗證方法。

+ 8 - 0
docs/zh_TW/guide/config-database.md

@@ -0,0 +1,8 @@
+# Database
+
+## Name
+- 類型: `string`
+- 預設值: `database`
+- 版本: `>=v2.0.0-beta.37`
+
+此選項用於設置 Nginx UI 用於存儲其數據的 sqlite 數據庫的名稱。

+ 20 - 0
docs/zh_TW/guide/config-http.md

@@ -0,0 +1,20 @@
+# Http
+
+## GithubProxy
+- 版本:`>= v2.0.0-beta.37`
+- 類型:`string`
+- 建議:`https://mirror.ghproxy.com/`
+
+對於可能在從 Github 下載資源時遇到困難的用戶(如在中國大陸),此選項允許他們為 github.com 設置代理,以提高可訪問性。
+
+## InsecureSkipVerify
+
+- 版本:`>= v2.0.0-beta.37`
+- 類型:`bool`
+
+此選項用於配置 Nginx UI 伺服器在與其他伺服器建立 TLS 連接時是否跳過證書驗證。
+
+- 版本:`>= v2.0.0-beta.37`
+- 类型: `bool`
+
+此选项用于配置 Nginx UI 服务器在与其他服务器建立 TLS 连接时是否跳过证书验证。

+ 16 - 0
docs/zh_TW/guide/config-node.md

@@ -0,0 +1,16 @@
+# Node
+
+## Name
+
+- 版本:`>= v2.0.0-beta.37`
+- 類型:`string`
+
+使用此選項自定義本地伺服器的名稱,以在環境指示器中顯示。
+
+## Secret
+
+- 類型: `string`
+- 版本: `>= v2.0.0-beta.37`
+
+此密鑰用於驗證 Nginx UI 伺服器之間的通信。
+此外,您可以使用此密鑰在不使用密碼的情況下訪問 Nginx UI API。

+ 141 - 61
docs/zh_TW/guide/config-server.md

@@ -1,89 +1,145 @@
-# 服務端
+# Server
 
-Nginx UI 配置的服務端部分涉及控制 Nginx UI 服務器的各種設置。在頁面中,我們將討論可用的選項、它們的預設值以及它們的目的。
+Nginx UI 配置的服務端部分涉及控制 Nginx UI 伺服器的各種設定。在頁面中,我們將討論可用的選項、它們的預設值以及它們的目的。
 
-## HttpHost
+## Host
 - 類型: `string`
-- 預設值:`0.0.0.0`
-
-Nginx UI 服務器監聽的主機名。此選項用於配置 Nginx UI 服務器監聽傳入 HTTP 請求的主機名。 更改預設主機名可能有助於提升安全性。
+- 版本: `>= v2.0.0-beta.37`
+- 預設值: `0.0.0.0`
 
-## HttpPort
+Nginx UI 伺服器監聽的主機名稱。此選項用於配置 Nginx UI 伺服器監聽傳入 HTTP 請求的主機名稱。更改預設主機名稱可能有助於提升安全性。
 
-- 類型:`int`
-- 預設值:`9000`
+## Port
+- 類型: `uint`
+- 版本: `>= v2.0.0-beta.37`
+- 預設值: `9000`
 
-Nginx UI 服務器監聽端口。此選項用於配置 Nginx UI 服務器監聽傳入 HTTP 請求的端口。更改預設端口對於避免端口衝突或增強安全性可能很有用。
+此選項用於配置 Nginx UI 服器監聽傳入 HTTP 請求的端口。更改預設端口對於避免端口衝突或增強安全性可能很有用。
 
 ## RunMode
 
-- 類型:`string`
-- 支援的值:`release`,`debug`
-- 預設值:`debug`
+- 類型: `string`
+- 支援的值: `release`,`debug`
+- 預設值: `debug`
+
+此選項用於配置 Nginx UI 伺服器的運行模式,主要影響日誌輸出的級別。
+
+Nginx UI 的日誌分為 6 個級別,分別為 `Debug`、`Info`、`Warn`、`Error`、`Panic` 和 `Fatal`,這些日誌級別按照嚴重程度遞增。
+
+當使用 `debug` 模式時,Nginx UI 將在控制台打印 SQL 及其執行的時間和調用者,`Debug` 級別或更高級別的日誌也會被打印。
+
+當使用 `release` 模式時,Nginx UI 將不會在控制台打印 SQL 的執行時間和調用者,只有 `Info` 級別或更高級別的日誌才會被打印。
+
+## HttpHost
+- 類型: `string`
+- 預設值: `0.0.0.0`
 
-此選項用於配置 Nginx UI 服務器的運行模式,主要影響日誌打印的級別。
+::: warning 警告
+已在 `v2.0.0-beta.37` 中廢棄,請使用 `Host` 取代。
+:::
 
-Nginx UI 的日誌分為 6 個級別,分別為 `Debug`、`Info`、`Warn`、`Error`、`Panic` 和 `Fatal`,這些日誌級別按照嚴重程度遞增,
+Nginx UI 伺服器監聽的主機名稱。此選項用於配置 Nginx UI 伺服器監聽傳入 HTTP 請求的主機名稱。更改預設主機名稱可能有助於提升安全性。
 
-當使用 `debug` 模式時,Nginx UI 將在控制台打印 SQL 及其執行的時間和調用者,`Debug` 級別或更高等級的日誌也會被打印。
+## HttpPort
+- 類型: `int`
+- 預設值: `9000`
 
-當使用 `release` 模式時,Nginx UI 將不會在控制台打印 SQL 的執行時間和調用者, 只有 `Info` 級別或更高等級的日誌才會被打印。
+::: warning 警告
+已在 `v2.0.0-beta.37` 中廢棄,請使用 `Port` 取代。
+:::
+
+此選項用於配置 Nginx UI 伺服器監聽傳入 HTTP 請求的端口。更改預設端口對於避免端口衝突或增強安全性可能很有用。
 
 ## JwtSecret
-- 類型:`string`
+- 類型: `string`
 
-此選項用於配置 Nginx UI 服務器用於生成 JWT 的密鑰。
+::: warning 警告
+已在 `v2.0.0-beta.37` 中廢棄,請使用 `App.JwtSecret` 取代。
+:::
+
+此選項用於配置 Nginx UI 伺服器用於生成 JWT 的密鑰。
+
+JWT 是一種用於驗證用戶身份的標準,它可以在用戶登入後生成一個 token,然後在後續的請求中使用該 token 來驗證用戶身份。
+
+如果您使用一鍵安裝腳本來部署 Nginx UI,腳本將會生成一個 UUID 值並將它設定為此選項的值。
 
-JWT 是一種用於驗證用戶身份的標準,它可以在用戶登錄後生成一個 token,然後在後續的請求中使用該 token 來驗證用戶身份。
+## NodeSecret
+- 類型: `string`
+- 版本: `>= v2.0.0-beta.24, <= 2.0.0-beta.36`
+
+::: warning 警告
+已在 `v2.0.0-beta.37` 中廢棄,請使用 `Node.Secret` 取代。
+:::
 
-如果您使用一鍵安裝腳本來部署 Nginx UI,腳本將會生成一個 UUID 值並將它設置為此選項的值。
+此密鑰用於驗證 Nginx UI 伺服器之間的通信。
+此外,您可以使用此密鑰在不使用密碼的情況下訪問 Nginx UI API。
 
 ## HTTPChallengePort
 
-- 類型:`int`
-- 預設值`9180`
+- 類型: `int`
+- 預設值: `9180`
 
-在獲取 Let's Encrypt 證書時,此選項用於在 HTTP01
+::: warning 警告
+已在 `v2.0.0-beta.37` 中廢棄,請使用 `Cert.HTTPChallengePort` 取代。
+:::
 
-挑戰模式中設置後端監聽端口。HTTP01 挑戰是 Let's Encrypt 用於驗證您控制請求證書的域的域驗證方法。
+在獲取 Let's Encrypt 證書時,此選項用於在 HTTP01 挑戰模式中設定後端監聽端口。HTTP01 挑戰是 Let's Encrypt 用於驗證您控制請求證書的域的域驗證方法。
 
 ## Email
-- 類型:`string`
+- 類型: `string`
+
+::: warning 警告
+已在 `v2.0.0-beta.37` 中廢棄,請使用 `Cert.Email` 取代。
+:::
 
-在獲取 Let's Encrypt 證書時,此選項用於設置您的電子郵件地址。Let's Encrypt 會將您的電子郵件地址用於通知您證書的到期時間。
+在獲取 Let's Encrypt 證書時,此選項用於設您的電子郵件地址。Let's Encrypt 會將您的電子郵件地址用於通知您證書的到期時間。
 
 ## Database
 
-- 類型:`string`
-- 預設值:`database`
+- 類型: `string`
+- 預設值: `database`
+
+::: warning 警告
+已在 `v2.0.0-beta.37` 中廢棄,請使用 `Database.Name` 取代。
+:::
 
-此選項用於設置 Nginx UI 用於存儲其數據的 sqlite 數據庫的名稱。
+此選項用於設 Nginx UI 用於存儲其數據的 sqlite 數據庫的名稱。
 
 ## StartCmd
 
-- 類型`string`
-- 預設值`login`
+- 類型: `string`
+- 預設值: `login`
 
-此選項用於設置 Web 終端的啟動命令。
+::: warning 警告
+已在 `v2.0.0-beta.37` 中廢棄,請使用 `Terminal.StartCmd` 取代。
+:::
+
+此選項用於設定 Web 終端的啟動命令。
 
 ::: warning 警告
-出於安全原因,我們將啟動命令設置為 `login`,因此您必須通過 Linux 的預設身份驗證方法登錄。如果您不想每次訪問 Web
-終端時都輸入用戶名和密碼進行驗證,請將其設置為 `bash` 或 `zsh`(如果已安裝)。
+出於安全原因,我們將啟動命令設置為 `login`,因此您必須通過 Linux 的預設身份驗證方法登入。如果您不想每次訪問 Web 終端時都輸入用戶名和密碼進行驗證,請將其設定為 `bash` 或 `zsh`(如果已安裝)。
 :::
 
 ## PageSize
 
-- 類型:`int`
-- 預設值:`10`
+- 類型: `int`
+- 預設值: `10`
+
+::: warning 警告
+已在 `v2.0.0-beta.37` 中廢棄,請使用 `App.PageSize` 取代。
+:::
 
-此選項用於設置 Nginx UI 中列表分頁的頁面大小。調整頁面大小有助於更有效地管理大量數據,但是過大的數量可能會增加服務器的壓力。
+此選項用於設 Nginx UI 中列表分頁的頁面大小。調整頁面大小有助於更有效地管理大量數據,但是過大的數量可能會增加服器的壓力。
 
 ## CADir
 
-- 類型`string`
+- 類型: `string`
 
-在申請 Let's Encrypt 證書時,我們使用 Let's Encrypt 的預設 CA 地址。如果您需要調試或從其他提供商獲取證書,您可以將 CADir
-設置為他們的地址。
+::: warning 警告
+已在 `v2.0.0-beta.37` 中廢棄,請使用 `Cert.CADir` 取代。
+:::
+
+在申請 Let's Encrypt 證書時,我們使用 Let's Encrypt 的預設 CA 地址。如果您需要調試或從其他提供商獲取證書,您可以將 CADir 設定為他們的地址。
 
 ::: tip 提示
 請注意,CADir 提供的地址需要符合 `RFC 8555` 標準。
@@ -91,52 +147,76 @@ JWT 是一種用於驗證用戶身份的標準,它可以在用戶登錄後生
 
 ## GithubProxy
 
-- 類型`string`
-- 建議`https://mirror.ghproxy.com/`
+- 類型: `string`
+- 建議: `https://mirror.ghproxy.com/`
 
-對於可能在從 Github 下載資源時遇到困難的用戶(如在中國大陸),此選項允許他們為 github.com 設置代理,以提高可訪問性。
+::: warning 警告
+已在 `v2.0.0-beta.37` 中廢棄,請使用 `Http.GithubProxy` 取代。
+:::
+
+對於可能在從 Github 下載資源時遇到困難的用戶(如在中國大陸),此選項允許他們為 github.com 設定代理,以提高可訪問性。
 
 ## CertRenewalInterval
 
-- 版本:`>= v2.0.0-beta.22`
-- 類型`int`
+- 版本: `>= v2.0.0-beta.22, <= 2.0.0-beta.36`
+- 類型: `int`
 - 預設值: `7`
 
+::: warning 警告
+已在 `v2.0.0-beta.37` 中廢棄,請使用 `Cert.CertRenewalInterval` 取代。
+:::
+
 此選項用於設定 Let's Encrypt 證書的自動續簽間隔。預設情況下,Nginx UI 每隔 7 天會自動續簽證書。
 
 ## RecursiveNameservers
 
-- 版本:`>= v2.0.0-beta.22`
+- 版本: `>= v2.0.0-beta.22, <= 2.0.0-beta.36`
 - 類型: `[]string`
-- 例: `8.8.8.8:53,1.1.1.1:53`
+- 例: `8.8.8.8:53,1.1.1.1:53`
 
-此選項用於設定 Nginx UI 在申請證書的 DNS 挑戰步驟所使用的遞迴域名伺服器。在不配置此項目的情況下,Nginx UI 使用作業系統的域名伺服器設定。
+::: warning 警告
+已在 `v2.0.0-beta.37` 中廢棄,請使用
+
+`Cert.RecursiveNameservers` 取代。
+:::
+
+此選項用於設定 Nginx UI 在申請證書的 DNS 挑戰步驟中所使用的遞歸域名伺服器。在不配置此項目的情況下,Nginx UI 使用操作系統的域名伺服器設置。
 
 ## SkipInstallation
 
-- 版本:`>= v2.0.0-beta.23`
-- 類型:`bool`
-- 預設值:`false`
+- 版本: `>= v2.0.0-beta.23, <= 2.0.0-beta.36`
+- 類型: `bool`
+- 預設值: `false`
 
-透過將此選項設定為 `true`,您可以跳過 Nginx UI 伺服器的安裝。
-當您希望使用相同的配置文件或環境變數將 Nginx UI 部署到多個伺服器時,這非常有用。
+::: warning 警告
+已在 `v2.0.0-beta.37` 中廢棄,請使用 `Node.SkipInstallation` 取代。
+:::
 
-預設情況下,如果您啟用了跳過安裝模式,而沒有在伺服器部分設定 `JWTSecret` 和 `NodeSecret` 選項,
-Nginx UI 將為這兩個選項生成一個隨機的 UUID 值
+通過將此選項設置為 `true`,您可以跳過 Nginx UI 伺服器的安裝。
+當您希望使用相同的配置文件或環境變量將 Nginx UI 部署到多個伺服器時,這非常有用
 
-此外,如果您也沒有在伺服器部分設定 `Email` 選項,
-Nginx UI 將不會創建系統初始的 acme 使用者,這意味著您無法在此伺服器上申請 SSL 證書。
+預設情況下,如果您啟用了跳過安裝模式,而沒有在伺服器部分設置 `JWTSecret` 和 `NodeSecret` 選項,Nginx UI 將為這兩個選項生成一個隨機的 UUID 值。
+
+此外,如果您也沒有在伺服器部分設置 `Email` 選項,Nginx UI 將不會創建系統初始的 acme 用戶,這意味著您無法在此伺服器上申請 SSL 證書。
 
 ## Name
 
-- 版本:`>= v2.0.0-beta.23`
-- 類型:`string`
+- 版本: `>= v2.0.0-beta.23, <= 2.0.0-beta.36`
+- 類型: `string`
+
+::: warning 警告
+已在 `v2.0.0-beta.37` 中廢棄,請使用 `Http.InsecureSkipVerify` 取代。
+:::
 
 使用此選項自定義本地伺服器的名稱,以在環境指示器中顯示。
 
 ## InsecureSkipVerify
 
-- 版本:`>= v2.0.0-beta.30`
+- 版本: `>= v2.0.0-beta.30, <= 2.0.0-beta.36`
 - 類型: `bool`
 
+::: warning 警告
+已在 `v2.0.0-beta.37` 中廢棄,請使用 `Http.InsecureSkipVerify` 取代。
+:::
+
 此選項用於配置 Nginx UI 伺服器在與其他伺服器建立 TLS 連接時是否跳過證書驗證。

+ 14 - 0
docs/zh_TW/guide/config-terminal.md

@@ -0,0 +1,14 @@
+# Terminal
+
+## StartCmd
+
+- 類型: `string`
+- 預設值: `login`
+- 版本: `>= v2.0.0-beta.37`
+
+此選項用於設置 Web 終端的啟動命令。
+
+::: warning 警告
+出於安全原因,我們將啟動命令設置為 `login`,因此您必須通過 Linux 的預設身份驗證方法登錄。
+如果您不想每次訪問 Web 終端時都輸入用戶名和密碼進行驗證,請將其設置為 `bash` 或 `zsh`(如果已安裝)。
+:::

+ 107 - 63
docs/zh_TW/guide/env.md

@@ -1,88 +1,132 @@
 # 環境變量
 
-適用於 v2.0.0-beta.23 及以上版本
+適用於 v2.0.0-beta.37 及以上版本。
+
+## App
+
+| 配置        | 環境變量                    |
+|-----------|-------------------------|
+| PageSize  | NGINX_UI_APP_PAGE_SIZE  |
+| JwtSecret | NGINX_UI_APP_JWT_SECRET |
 
 ## Server
 
-| Configuration Setting | Environment Variable                  |
-|-----------------------|---------------------------------------|
-| HttpPort              | NGINX_UI_SERVER_HTTP_PORT             |
-| RunMode               | NGINX_UI_SERVER_RUN_MODE              |
-| JwtSecret             | NGINX_UI_SERVER_JWT_SECRET            |
-| HTTPChallengePort     | NGINX_UI_SERVER_HTTP_CHALLENGE_PORT   |
-| StartCmd              | NGINX_UI_SERVER_START_CMD             |
-| Database              | NGINX_UI_SERVER_DATABASE              |
-| CADir                 | NGINX_UI_SERVER_CA_DIR                |
-| GithubProxy           | NGINX_UI_SERVER_GITHUB_PROXY          |
-| NodeSecret            | NGINX_UI_SERVER_NODE_SECRET           |
-| Demo                  | NGINX_UI_SERVER_DEMO                  |
-| PageSize              | NGINX_UI_SERVER_PAGE_SIZE             |
-| HttpHost              | NGINX_UI_SERVER_HTTP_HOST             |
-| CertRenewalInterval   | NGINX_UI_SERVER_CERT_RENEWAL_INTERVAL |
-| RecursiveNameservers  | NGINX_UI_SERVER_RECURSIVE_NAMESERVERS |
-| SkipInstallation      | NGINX_UI_SERVER_SKIP_INSTALLATION     |
-| Name                  | NGINX_UI_SERVER_NAME                  |
-| InsecureSkipVerify    | NGINX_UI_SERVER_INSECURE_SKIP_VERIFY  |
+| 配置      | 環境變量                     |
+|---------|--------------------------|
+| Host    | NGINX_UI_SERVER_HOST     |
+| Port    | NGINX_UI_SERVER_PORT     |
+| RunMode | NGINX_UI_SERVER_RUN_MODE |
 
-## Nginx
+## Database
 
-| Configuration Setting | Environment Variable              |
-|-----------------------|-----------------------------------|
-| AccessLogPath         | NGINX_UI_NGINX_ACCESS_LOG_PATH    |
-| ErrorLogPath          | NGINX_UI_NGINX_ERROR_LOG_PATH     |
-| ConfigDir             | NGINX_UI_NGINX_CONFIG_DIR         |
-| PIDPath               | NGINX_UI_NGINX_PID_PATH           |
-| TestConfigCmd         | NGINX_UI_NGINX_TEST_CONFIG_CMD    |
-| ReloadCmd             | NGINX_UI_NGINX_RELOAD_CMD         |
-| RestartCmd            | NGINX_UI_NGINX_RESTART_CMD        |
-| LogDirWhiteList       | NGINX_UI_NGINX_LOG_DIR_WHITE_LIST |
+| 配置   | 環境變量             |
+|------|------------------|
+| Name | NGINX_UI_DB_NAME |
 
-## OpenAI
+## Auth
 
-| Configuration Setting | Environment Variable     |
-|-----------------------|--------------------------|
-| Model                 | NGINX_UI_OPENAI_MODEL    |
-| BaseUrl               | NGINX_UI_OPENAI_BASE_URL |
-| Proxy                 | NGINX_UI_OPENAI_PROXY    |
-| Token                 | NGINX_UI_OPENAI_TOKEN    |
+| 配置                  | 環境變量                                |
+|---------------------|-------------------------------------|
+| IPWhiteList         | NGINX_UI_AUTH_IP_WHITE_LIST         |
+| BanThresholdMinutes | NGINX_UI_AUTH_BAN_THRESHOLD_MINUTES |
+| MaxAttempts         | NGINX_UI_AUTH_MAX_ATTEMPTS          |
 
 ## Casdoor
 
-| Configuration Setting | Environment Variable              |
-|-----------------------|-----------------------------------|
-| Endpoint              | NGINX_UI_CASDOOR_ENDPOINT         |
-| ClientId              | NGINX_UI_CASDOOR_CLIENT_ID        |
-| ClientSecret          | NGINX_UI_CASDOOR_CLIENT_SECRET    |
-| CertificatePath       | NGINX_UI_CASDOOR_CERTIFICATE_PATH |
-| Organization          | NGINX_UI_CASDOOR_ORGANIZATION     |
-| Application           | NGINX_UI_CASDOOR_APPLICATION      |
-| RedirectUri           | NGINX_UI_CASDOOR_REDIRECT_URI     |
+| 配置              | 環境變量                              |
+|-----------------|-----------------------------------|
+| Endpoint        | NGINX_UI_CASDOOR_ENDPOINT         |
+| ClientId        | NGINX_UI_CASDOOR_CLIENT_ID        |
+| ClientSecret    | NGINX_UI_CASDOOR_CLIENT_SECRET    |
+| CertificatePath | NGINX_UI_CASDOOR_CERTIFICATE_PATH |
+| Organization    | NGINX_UI_CASDOOR_ORGANIZATION     |
+| Application     | NGINX_UI_CASDOOR_APPLICATION      |
+| RedirectUri     | NGINX_UI_CASDOOR_REDIRECT_URI     |
+
+## Cert
+
+| 配置                   | 環境變量                                |
+|----------------------|-------------------------------------|
+| Email                | NGINX_UI_CERT_EMAIL                 |
+| CADir                | NGINX_UI_CERT_CA_DIR                |
+| RenewalInterval      | NGINX_UI_CERT_RENEWAL_INTERVAL      |
+| RecursiveNameservers | NGINX_UI_CERT_RECURSIVE_NAMESERVERS |
+| HTTPChallengePort    | NGINX_UI_CERT_HTTP_CHALLENGE_PORT   |
+
+## Cluster
+
+| 配置   | 環境變量                  |
+|------|-----------------------|
+| Node | NGINX_UI_CLUSTER_NODE |
+
+## Crypto
+
+| 配置     | 環境變量                   |
+|--------|------------------------|
+| Secret | NGINX_UI_CRYPTO_SECRET |
+
+## Http
+
+| 配置                 | 環境變量                               |
+|--------------------|------------------------------------|
+| GithubProxy        | NGINX_UI_HTTP_GITHUB_PROXY         |
+| InsecureSkipVerify | NGINX_UI_HTTP_INSECURE_SKIP_VERIFY |
 
 ## Logrotate
 
-| Configuration Setting | Environment Variable        |
-|-----------------------|-----------------------------|
-| Enabled               | NGINX_UI_LOGROTATE_ENABLED  |
-| CMD                   | NGINX_UI_LOGROTATE_CMD      |
-| Interval              | NGINX_UI_LOGROTATE_INTERVAL |
+| 配置       | 環境變量                        |
+|----------|-----------------------------|
+| Enabled  | NGINX_UI_LOGROTATE_ENABLED  |
+| CMD      | NGINX_UI_LOGROTATE_CMD      |
+| Interval | NGINX_UI_LOGROTATE_INTERVAL |
 
-## Auth
+## Nginx
+
+| 配置              | 環境變量                              |
+|-----------------|-----------------------------------|
+| AccessLogPath   | NGINX_UI_NGINX_ACCESS_LOG_PATH    |
+| ErrorLogPath    | NGINX_UI_NGINX_ERROR_LOG_PATH     |
+| ConfigDir       | NGINX_UI_NGINX_CONFIG_DIR         |
+| PIDPath         | NGINX_UI_NGINX_PID_PATH           |
+| TestConfigCmd   | NGINX_UI_NGINX_TEST_CONFIG_CMD    |
+| ReloadCmd       | NGINX_UI_NGINX_RELOAD_CMD         |
+| RestartCmd      | NGINX_UI_NGINX_RESTART_CMD        |
+| LogDirWhiteList | NGINX_UI_NGINX_LOG_DIR_WHITE_LIST |
+
+## Node
+
+| 配置               | 環境變量                            |
+|------------------|---------------------------------|
+| Name             | NGINX_UI_NODE_NAME              |
+| Secret           | NGINX_UI_NODE_SECRET            |
+| SkipInstallation | NGINX_UI_NODE_SKIP_INSTALLATION |
+
+## OpenAI
+
+| 配置      | 環境變量                     |
+|---------|--------------------------|
+| Model   | NGINX_UI_OPENAI_MODEL    |
+| BaseUrl | NGINX_UI_OPENAI_BASE_URL |
+| Proxy   | NGINX_UI_OPENAI_PROXY    |
+| Token   | NGINX_UI_OPENAI_TOKEN    |
+
+## Terminal
 
-| Configuration Setting | Environment Variable      |
-|-----------------------|---------------------------|
-| IPWhiteList           | NGINX_UI_AUTH_IPWhiteList |
+| 配置       | 環境變量                        |
+|----------|-----------------------------|
+| StartCmd | NGINX_UI_TERMINAL_START_CMD |
 
 ## Webauthn
 
-| Configuration Setting | Environment Variable              |
-|-----------------------|-----------------------------------|
-| RPDisplayName         | NGINX_UI_WEBAUTHN_RP_DISPLAY_NAME |
-| RPID                  | NGINX_UI_WEBAUTHN_RPID            |
-| RPOrigins             | NGINX_UI_WEBAUTHN_RP_ORIGINS      |
+| 配置            | 環境變量                              |
+|---------------|-----------------------------------|
+| RPDisplayName | NGINX_UI_WEBAUTHN_RP_DISPLAY_NAME |
+| RPID          | NGINX_UI_WEBAUTHN_RPID            |
+| RPOrigins     | NGINX_UI_WEBAUTHN_RP_ORIGINS      |
 
-## 預定義使用者
+## 預定義用戶
 
-在跳過安裝模式下,您可以設置以下環境變量以創建預定義使用者:
+在跳過安裝模式下,您可以設定以下環境變量以創建預定義用戶
 
 - NGINX_UI_PREDEFINED_USER_NAME
 - NGINX_UI_PREDEFINED_USER_PASSWORD

+ 25 - 15
go.mod

@@ -10,7 +10,8 @@ require (
 	github.com/creack/pty v1.1.23
 	github.com/dgraph-io/ristretto v1.0.0
 	github.com/dustin/go-humanize v1.0.1
-	github.com/fatih/color v1.17.0
+	github.com/elliotchance/orderedmap/v2 v2.4.0
+	github.com/fatih/color v1.18.0
 	github.com/gin-contrib/static v1.1.2
 	github.com/gin-gonic/gin v1.10.0
 	github.com/go-acme/lego/v4 v4.19.2
@@ -24,20 +25,19 @@ require (
 	github.com/jpillora/overseer v1.1.6
 	github.com/lib/pq v1.10.9
 	github.com/minio/selfupdate v0.6.0
-	github.com/mitchellh/mapstructure v1.5.0
 	github.com/pkg/errors v0.9.1
 	github.com/pquerna/otp v1.4.0
 	github.com/pretty66/websocketproxy v0.0.0-20220507015215-930b3a686308
 	github.com/samber/lo v1.47.0
-	github.com/sashabaranov/go-openai v1.32.2
+	github.com/sashabaranov/go-openai v1.32.3
 	github.com/shirou/gopsutil/v3 v3.24.5
-	github.com/shopspring/decimal v1.4.0
 	github.com/spf13/cast v1.7.0
 	github.com/stretchr/testify v1.9.0
 	github.com/tufanbarisyildirim/gonginx v0.0.0-20241013191809-e73b7dd454e8
+	github.com/uozi-tech/cosy v1.9.4
+	github.com/uozi-tech/cosy-driver-sqlite v0.2.0
 	go.uber.org/zap v1.27.0
 	golang.org/x/crypto v0.28.0
-	gopkg.in/guregu/null.v4 v4.0.0
 	gopkg.in/ini.v1 v1.67.0
 	gorm.io/driver/sqlite v1.5.6
 	gorm.io/gen v0.3.26
@@ -72,7 +72,7 @@ require (
 	github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 // indirect
 	github.com/StackExchange/wmi v1.2.1 // indirect
 	github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 // indirect
-	github.com/aliyun/alibaba-cloud-sdk-go v1.63.32 // indirect
+	github.com/aliyun/alibaba-cloud-sdk-go v1.63.34 // indirect
 	github.com/aws/aws-sdk-go-v2 v1.32.2 // indirect
 	github.com/aws/aws-sdk-go-v2/config v1.28.0 // indirect
 	github.com/aws/aws-sdk-go-v2/credentials v1.17.41 // indirect
@@ -90,8 +90,9 @@ require (
 	github.com/aws/smithy-go v1.22.0 // indirect
 	github.com/benbjohnson/clock v1.3.5 // indirect
 	github.com/boombuler/barcode v1.0.2 // indirect
+	github.com/bsm/redislock v0.9.4 // indirect
 	github.com/bytedance/sonic v1.12.3 // indirect
-	github.com/bytedance/sonic/loader v0.2.0 // indirect
+	github.com/bytedance/sonic/loader v0.2.1 // indirect
 	github.com/cenkalti/backoff/v4 v4.3.0 // indirect
 	github.com/cespare/xxhash/v2 v2.3.0 // indirect
 	github.com/civo/civogo v0.3.84 // indirect
@@ -100,6 +101,7 @@ require (
 	github.com/cloudwego/iasm v0.2.0 // indirect
 	github.com/cpu/goacmedns v0.1.1 // indirect
 	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
+	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
 	github.com/dimchansky/utfbom v1.1.1 // indirect
 	github.com/dnsimple/dnsimple-go v1.7.0 // indirect
 	github.com/exoscale/egoscale/v3 v3.1.7 // indirect
@@ -110,6 +112,7 @@ require (
 	github.com/gabriel-vasile/mimetype v1.4.6 // indirect
 	github.com/ghodss/yaml v1.0.0 // indirect
 	github.com/gin-contrib/sse v0.1.0 // indirect
+	github.com/go-co-op/gocron/v2 v2.12.1 // indirect
 	github.com/go-errors/errors v1.5.1 // indirect
 	github.com/go-jose/go-jose/v4 v4.0.4 // indirect
 	github.com/go-logr/logr v1.4.2 // indirect
@@ -144,9 +147,12 @@ require (
 	github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df // indirect
 	github.com/infobloxopen/infoblox-go-client v1.1.1 // indirect
 	github.com/itchyny/timefmt-go v0.1.6 // indirect
+	github.com/jackc/pgio v1.0.0 // indirect
+	github.com/jackc/pgtype v1.14.4 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/now v1.1.5 // indirect
 	github.com/jmespath/go-jmespath v0.4.0 // indirect
+	github.com/jonboulle/clockwork v0.4.0 // indirect
 	github.com/jpillora/s3 v1.1.4 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
 	github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 // indirect
@@ -167,6 +173,7 @@ require (
 	github.com/miekg/dns v1.1.62 // indirect
 	github.com/mimuret/golang-iij-dpf v0.9.1 // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
+	github.com/mitchellh/mapstructure v1.5.0 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 // indirect
@@ -190,6 +197,7 @@ require (
 	github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
 	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
 	github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
+	github.com/redis/go-redis/v9 v9.7.0 // indirect
 	github.com/robfig/cron/v3 v3.0.1 // indirect
 	github.com/sacloud/api-client-go v0.2.10 // indirect
 	github.com/sacloud/go-http v0.1.8 // indirect
@@ -201,18 +209,20 @@ require (
 	github.com/selectel/domains-go v1.1.0 // indirect
 	github.com/selectel/go-selvpcclient/v3 v3.1.1 // indirect
 	github.com/shoenig/go-m1cpu v0.1.6 // indirect
+	github.com/shopspring/decimal v1.4.0 // indirect
 	github.com/sirupsen/logrus v1.9.3 // indirect
 	github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect
 	github.com/softlayer/softlayer-go v1.1.6 // indirect
 	github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e // indirect
 	github.com/sony/gobreaker v1.0.0 // indirect
+	github.com/sony/sonyflake v1.2.0 // indirect
 	github.com/sourcegraph/conc v0.3.0 // indirect
 	github.com/spf13/afero v1.11.0 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
 	github.com/spf13/viper v1.19.0 // indirect
 	github.com/subosito/gotenv v1.6.0 // indirect
-	github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1026 // indirect
-	github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1026 // indirect
+	github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1028 // indirect
+	github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1028 // indirect
 	github.com/tjfoc/gmsm v1.4.1 // indirect
 	github.com/tklauser/go-sysconf v0.3.14 // indirect
 	github.com/tklauser/numcpus v0.9.0 // indirect
@@ -223,8 +233,8 @@ require (
 	github.com/vinyldns/go-vinyldns v0.9.16 // indirect
 	github.com/vultr/govultr/v3 v3.10.0 // indirect
 	github.com/x448/float16 v0.8.4 // indirect
-	github.com/yandex-cloud/go-genproto v0.0.0-20241018072940-69706eaae3be // indirect
-	github.com/yandex-cloud/go-sdk v0.0.0-20241018073342-0142f4806660 // indirect
+	github.com/yandex-cloud/go-genproto v0.0.0-20241021132621-28bb61d00c2f // indirect
+	github.com/yandex-cloud/go-sdk v0.0.0-20241021153520-213d4c625eca // indirect
 	github.com/yusufpapurcu/wmi v1.2.4 // indirect
 	go.mongodb.org/mongo-driver v1.17.1 // indirect
 	go.opencensus.io v0.24.0 // indirect
@@ -246,12 +256,13 @@ require (
 	golang.org/x/time v0.7.0 // indirect
 	golang.org/x/tools v0.26.0 // indirect
 	google.golang.org/api v0.201.0 // indirect
-	google.golang.org/genproto v0.0.0-20241015192408-796eee8c2d53 // indirect
-	google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect
+	google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 // indirect
 	google.golang.org/grpc v1.67.1 // indirect
 	google.golang.org/protobuf v1.35.1 // indirect
 	gopkg.in/fsnotify.v1 v1.4.7 // indirect
+	gopkg.in/guregu/null.v4 v4.0.0 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/ns1/ns1-go.v2 v2.12.2 // indirect
 	gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
@@ -259,7 +270,6 @@ require (
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 	gorm.io/datatypes v1.2.4 // indirect
 	gorm.io/driver/mysql v1.5.7 // indirect
-	gorm.io/driver/postgres v1.5.6 // indirect
 	gorm.io/hints v1.1.2 // indirect
 	k8s.io/api v0.31.1 // indirect
 	k8s.io/apimachinery v0.31.1 // indirect

+ 157 - 127
go.sum

@@ -40,7 +40,6 @@ cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFO
 cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I=
 cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY=
 cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE=
-cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U=
 cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4=
 cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw=
 cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E=
@@ -102,8 +101,6 @@ cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVo
 cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo=
 cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0=
 cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E=
-cloud.google.com/go/auth v0.9.7 h1:ha65jNwOfI48YmUzNfMaUDfqt5ykuYIUnSartpU1+BA=
-cloud.google.com/go/auth v0.9.7/go.mod h1:Xo0n7n66eHyOWWCnitop6870Ilwo3PiZyodVkkH1xWM=
 cloud.google.com/go/auth v0.9.8 h1:+CSJ0Gw9iVeSENVCKJoLHhdUykDgXSc4Qn+gu2BRtR8=
 cloud.google.com/go/auth v0.9.8/go.mod h1:xxA5AqpDrvS+Gkmo9RqrGGRh6WSNKKOXhY3zNOr38tI=
 cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY=
@@ -617,16 +614,12 @@ github.com/AdamSLevy/jsonrpc2/v14 v14.1.0 h1:Dy3M9aegiI7d7PF1LUdjbVigJReo+QOceYs
 github.com/AdamSLevy/jsonrpc2/v14 v14.1.0/go.mod h1:ZakZtbCXxCz82NJvq7MoREtiQesnDfrtF6RFUGzQfLo=
 github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=
 github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 h1:nyQWyZvwGTvunIMxi1Y9uXkcyr+I7TeNrr/foo4Kpk8=
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0=
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.15.0 h1:eXzkOEXbSTOa7cJ7EqeCVi/OFi/ppDrUtQuttCWy74c=
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.15.0/go.mod h1:YL1xnZ6QejvQHWJrX/AvhFl4WW4rqHVoKspWNVwFk0M=
 github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0 h1:JZg6HRh6W6U4OLl6lk7BZ7BLisIzM9dG1R50zUk9C/M=
 github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0/go.mod h1:YL1xnZ6QejvQHWJrX/AvhFl4WW4rqHVoKspWNVwFk0M=
-github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc=
-github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg=
 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 h1:B/dfvscEQtew9dVuoxqxrUKKv8Ih2f55PydknDamU+g=
 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0/go.mod h1:fiPSssYvltE08HJchL04dOy+RD4hgrjph0cwGGMntdI=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0 h1:+m0M/LFxN43KvULkDNfdXOgrjtg6UYJPFBJyuEcRCAw=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0/go.mod h1:PwOyop78lveYMRs6oCxjiVyBdyCgIYH6XHIVZO9/SFQ=
 github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
 github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0 h1:lpOxwrQ919lCZoNCd69rVt8u1eLZuMORrGXqy8sNf3c=
@@ -663,6 +656,8 @@ github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+Z
 github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
 github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
 github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
+github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM=
+github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE=
 github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU=
 github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
@@ -672,6 +667,7 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
 github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
 github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
 github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=
+github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
 github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 h1:xPMsUicZ3iosVPSIP7bW5EcGUzjiiMl1OYTe14y/R24=
 github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87/go.mod h1:iGLljf5n9GjT6kc0HBvyI1nOKnGQbNB66VzSNbK5iks=
@@ -689,12 +685,10 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
-github.com/aliyun/alibaba-cloud-sdk-go v1.63.23 h1:qVHm1EZhZ4JGfB9RMHREtbcNcPDDFyCKA+0/nMk6JP8=
-github.com/aliyun/alibaba-cloud-sdk-go v1.63.23/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ=
-github.com/aliyun/alibaba-cloud-sdk-go v1.63.28 h1:sfIgg5sLKlJQJonmnY43YHCU3mvTOyFSQgE3FNCl63U=
-github.com/aliyun/alibaba-cloud-sdk-go v1.63.28/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ=
 github.com/aliyun/alibaba-cloud-sdk-go v1.63.32 h1:aBtZr6N7HXVpJCMybTSBuinHauehf/R0LNMB03TkrE0=
 github.com/aliyun/alibaba-cloud-sdk-go v1.63.32/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ=
+github.com/aliyun/alibaba-cloud-sdk-go v1.63.34 h1:eZM2MHY/p4TFO1pGf9O5HiuYE59hwrrkf3HvCtkL5Ok=
+github.com/aliyun/alibaba-cloud-sdk-go v1.63.34/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ=
 github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
 github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
 github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0=
@@ -705,58 +699,32 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV
 github.com/armon/go-metrics v0.4.0/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
 github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
 github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
-github.com/aws/aws-sdk-go-v2 v1.32.0 h1:GuHp7GvMN74PXD5C97KT5D87UhIy4bQPkflQKbfkndg=
-github.com/aws/aws-sdk-go-v2 v1.32.0/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo=
 github.com/aws/aws-sdk-go-v2 v1.32.2 h1:AkNLZEyYMLnx/Q/mSKkcMqwNFXMAvFto9bNsHqcTduI=
 github.com/aws/aws-sdk-go-v2 v1.32.2/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo=
-github.com/aws/aws-sdk-go-v2/config v1.27.41 h1:esG3WpmEuNJ6F4kVFLumN8nCfA5VBav1KKb3JPx83O4=
-github.com/aws/aws-sdk-go-v2/config v1.27.41/go.mod h1:haUg09ebP+ClvPjU3EB/xe0HF9PguO19PD2fdjM2X14=
-github.com/aws/aws-sdk-go-v2/config v1.27.43 h1:p33fDDihFC390dhhuv8nOmX419wjOSDQRb+USt20RrU=
-github.com/aws/aws-sdk-go-v2/config v1.27.43/go.mod h1:pYhbtvg1siOOg8h5an77rXle9tVG8T+BWLWAo7cOukc=
 github.com/aws/aws-sdk-go-v2/config v1.28.0 h1:FosVYWcqEtWNxHn8gB/Vs6jOlNwSoyOCA/g/sxyySOQ=
 github.com/aws/aws-sdk-go-v2/config v1.28.0/go.mod h1:pYhbtvg1siOOg8h5an77rXle9tVG8T+BWLWAo7cOukc=
-github.com/aws/aws-sdk-go-v2/credentials v1.17.39 h1:tmVexAhoGqJxNE2oc4/SJqL+Jz1x1iCPt5ts9XcqZCU=
-github.com/aws/aws-sdk-go-v2/credentials v1.17.39/go.mod h1:zgOdbDI9epE608PdboJ87CYvPIejAgFevazeJW6iauQ=
 github.com/aws/aws-sdk-go-v2/credentials v1.17.41 h1:7gXo+Axmp+R4Z+AK8YFQO0ZV3L0gizGINCOWxSLY9W8=
 github.com/aws/aws-sdk-go-v2/credentials v1.17.41/go.mod h1:u4Eb8d3394YLubphT4jLEwN1rLNq2wFOlT6OuxFwPzU=
-github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.15 h1:kGjlNc2IXXcxPDcfMyCshNCjVgxUhC/vTJv7NvC9wKk=
-github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.15/go.mod h1:rk/HmqPo+dX0Uv0Q1+4w3QKFdICEGSsTYz1hRWvH8UI=
 github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.17 h1:TMH3f/SCAWdNtXXVPPu5D6wrr4G5hI1rAxbcocKfC7Q=
 github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.17/go.mod h1:1ZRXLdTpzdJb9fwTMXiLipENRxkGMTn1sfKexGllQCw=
-github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.19 h1:Q/k5wCeJkSWs+62kDfOillkNIJ5NqmE3iOfm48g/W8c=
-github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.19/go.mod h1:Wns1C66VvtA2Bv/cUBuKZKQKdjo7EVMhp90aAa+8oTI=
 github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 h1:UAsR3xA31QGf79WzpG/ixT9FZvQlh5HY1NRqSHBNOCk=
 github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21/go.mod h1:JNr43NFf5L9YaG3eKTm7HQzls9J+A9YYcGI5Quh1r2Y=
-github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.19 h1:AYLE0lUfKvN6icFTR/p+NmD1amYKTbqHQ1Nm+jwE6BM=
-github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.19/go.mod h1:1giLakj64GjuH1NBzF/DXqly5DWHtMTaOzRZ53nFX0I=
 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 h1:6jZVETqmYCadGFvrYEQfC5fAQmlo80CeL5psbno6r0s=
 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21/go.mod h1:1SR0GbLlnN3QUmYaflZNiH1ql+1qrSiB2vwcJ+4UM60=
 github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ=
 github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g=
 github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ=
-github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.0 h1:AdbiDUgQZmM28rDIZbiSwFxz8+3B94aOXxzs6oH+EA0=
-github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.0/go.mod h1:uV476Bd80tiDTX4X2redMtagQUg65aU/gzPojSJ4kSI=
 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 h1:s7NA1SOw8q/5c0wr8477yOPp0z+uBaXBnLE0XYb0POA=
 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2/go.mod h1:fnjjWyAW/Pj5HYOxl9LJqWtEwS7W2qgcRLWP+uWbss0=
-github.com/aws/aws-sdk-go-v2/service/lightsail v1.42.0 h1:vUdg9qrgYd8ShPj8FhE3qfBx+UoOH2ZJW1Te/V4Hn+I=
-github.com/aws/aws-sdk-go-v2/service/lightsail v1.42.0/go.mod h1:TWMPrc4+ZJRzkrDBUNOQzhVqhhUqv7DRkgoboTn4PGk=
 github.com/aws/aws-sdk-go-v2/service/lightsail v1.42.2 h1:KACHg9TlCAph5Brs8RqVrm1SK0FVLBiDPhkZApIG5x4=
 github.com/aws/aws-sdk-go-v2/service/lightsail v1.42.2/go.mod h1:eZZLyXEbSmrhlNXeGnZUyBUQXUwnzaJqT8tFoQGxSRA=
-github.com/aws/aws-sdk-go-v2/service/route53 v1.45.0 h1:rwDRzOudNWFLRmpHIC6zZjGKovvgdfobPgXn/aXTdcs=
-github.com/aws/aws-sdk-go-v2/service/route53 v1.45.0/go.mod h1:NAmFsZ4aGISCGa2nX+EGxPQGukb/z+XwriLW0i+EHKs=
 github.com/aws/aws-sdk-go-v2/service/route53 v1.45.2 h1:P4ElvGTPph12a87YpxPDIqCvVICeYJFV32UMMS/TIPc=
 github.com/aws/aws-sdk-go-v2/service/route53 v1.45.2/go.mod h1:zLKE53MjadFH0VYrDerAx25brxLYiSg4Vk3C+qPY4BQ=
-github.com/aws/aws-sdk-go-v2/service/sso v1.24.0 h1:71FvP6XFj53NK+YiAEGVzeiccLVeFnHOCvMig0zOHsE=
-github.com/aws/aws-sdk-go-v2/service/sso v1.24.0/go.mod h1:UVJqtKXSd9YppRKgdBIkyv7qgbSGv5DchM3yX0BN2mU=
 github.com/aws/aws-sdk-go-v2/service/sso v1.24.2 h1:bSYXVyUzoTHoKalBmwaZxs97HU9DWWI3ehHSAMa7xOk=
 github.com/aws/aws-sdk-go-v2/service/sso v1.24.2/go.mod h1:skMqY7JElusiOUjMJMOv1jJsP7YUg7DrhgqZZWuzu1U=
-github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.0 h1:Uco4o19bi3AmBapImNzuMk+rfzlui52BDyVK1UfJeRA=
-github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.0/go.mod h1:+HLFhCpnG08hBee8bUdfd1mBK+rFKPt4O5igR9lXDfk=
 github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.2 h1:AhmO1fHINP9vFYUE0LHzCWg/LfUWUF+zFPEcY9QXb7o=
 github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.2/go.mod h1:o8aQygT2+MVP0NaV6kbdE1YnnIM8RRVQzoeUH45GOdI=
-github.com/aws/aws-sdk-go-v2/service/sts v1.32.0 h1:GiQUjZM2KUZX68o/LpZ1xqxYMuvoxpRrOwYARYog3vc=
-github.com/aws/aws-sdk-go-v2/service/sts v1.32.0/go.mod h1:dKnu7M4MAS2SDlng1ytxd03H+y0LoUfEQ5E2VaaSw/4=
 github.com/aws/aws-sdk-go-v2/service/sts v1.32.2 h1:CiS7i0+FUe+/YY1GvIBLLrR/XNGZ4CtM1Ll0XavNuVo=
 github.com/aws/aws-sdk-go-v2/service/sts v1.32.2/go.mod h1:HtaiBI8CjYoNVde8arShXb94UbQQi9L4EMr6D+xGBwo=
 github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM=
@@ -774,19 +742,21 @@ github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBW
 github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
 github.com/boombuler/barcode v1.0.2 h1:79yrbttoZrLGkL/oOI8hBrUKucwOL0oOjUgEguGMcJ4=
 github.com/boombuler/barcode v1.0.2/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
+github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
+github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
+github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
+github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
+github.com/bsm/redislock v0.9.4 h1:X/Wse1DPpiQgHbVYRE9zv6m070UcKoOGekgvpNhiSvw=
+github.com/bsm/redislock v0.9.4/go.mod h1:Epf7AJLiSFwLCiZcfi6pWFO/8eAYrYpQXFxEDPoDeAk=
 github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU=
 github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
 github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
-github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM=
-github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
+github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E=
+github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
 github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw=
 github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdfpU9wwHfY=
 github.com/caarlos0/env/v11 v11.2.2 h1:95fApNrUyueipoZN/EhA8mMxiNxrBwDa+oAZrMWl3Kg=
 github.com/caarlos0/env/v11 v11.2.2/go.mod h1:JBfcdeQiBoI3Zh1QRAWfe+tpiNTmDtcCj/hHHHMx0vc=
-github.com/casdoor/casdoor-go-sdk v0.52.0 h1:UKcZfczO3U5H7md6bTtI6zIJzeorBrbg/WE8Q4qsczE=
-github.com/casdoor/casdoor-go-sdk v0.52.0/go.mod h1:cMnkCQJgMYpgAlgEx8reSt1AVaDIQLcJ1zk5pzBaz+4=
-github.com/casdoor/casdoor-go-sdk v1.1.0 h1:QW1pMoGG18X+GrcMolKKaTXCLDOpoYCu2kbfUZZQ+5A=
-github.com/casdoor/casdoor-go-sdk v1.1.0/go.mod h1:cMnkCQJgMYpgAlgEx8reSt1AVaDIQLcJ1zk5pzBaz+4=
 github.com/casdoor/casdoor-go-sdk v1.2.0 h1:DHLO8joZwgrAgdhhEZCPdrtLHdV89cXAa9UKxT7kwXg=
 github.com/casdoor/casdoor-go-sdk v1.2.0/go.mod h1:cMnkCQJgMYpgAlgEx8reSt1AVaDIQLcJ1zk5pzBaz+4=
 github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
@@ -805,13 +775,9 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
 github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
 github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
-github.com/civo/civogo v0.3.83 h1:GPLbSA4jJqCXCY291QO0jtr/k7jhkL+MgBT5bsgfPgc=
-github.com/civo/civogo v0.3.83/go.mod h1:7UCYX+qeeJbrG55E1huv+0ySxcHTqq/26FcHLVelQJM=
 github.com/civo/civogo v0.3.84 h1:jf5IT7VJFPaReO6g8B0zqKhsYCIizaGo4PjDLY7Sl6Y=
 github.com/civo/civogo v0.3.84/go.mod h1:7UCYX+qeeJbrG55E1huv+0ySxcHTqq/26FcHLVelQJM=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/cloudflare/cloudflare-go v0.106.0 h1:q41gC5Wc1nfi0D1ZhSHokWcd9mGMbqC7RE7qiP+qE00=
-github.com/cloudflare/cloudflare-go v0.106.0/go.mod h1:pfUQ4PIG4ISI0/Mmc21Bp86UnFU0ktmPf3iTgbSL+cM=
 github.com/cloudflare/cloudflare-go v0.107.0 h1:cMDIw2tzt6TXCJyMFVyP+BPOVkIfMvcKjhMNSNvuEPc=
 github.com/cloudflare/cloudflare-go v0.107.0/go.mod h1:5cYGzVBqNTLxMYSLdVjuSs5LJL517wJDSvMPWUrzHzc=
 github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
@@ -831,16 +797,19 @@ github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWH
 github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
 github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
 github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
 github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
 github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
 github.com/cpu/goacmedns v0.1.1 h1:DM3H2NiN2oam7QljgGY5ygy4yDXhK5Z4JUnqaugs2C4=
 github.com/cpu/goacmedns v0.1.1/go.mod h1:MuaouqEhPAHxsbqjgnck5zeghuwBP1dLnPoobeGqugQ=
 github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
 github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0=
 github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
@@ -853,6 +822,8 @@ github.com/dgraph-io/ristretto v1.0.0/go.mod h1:jTi2FiYEhQ1NsMmA7DeBykizjOuY88Nh
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y=
 github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
+github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
+github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
 github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
 github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
 github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
@@ -862,6 +833,8 @@ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3
 github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
 github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
 github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
+github.com/elliotchance/orderedmap/v2 v2.4.0 h1:6tUmMwD9F998FNpwFxA5E6NQvSpk2PVw7RKsVq3+2Cw=
+github.com/elliotchance/orderedmap/v2 v2.4.0/go.mod h1:85lZyVbpGaGvHvnKa7Qhx7zncAdBIBq6u56Hb1PRU5Q=
 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -884,6 +857,8 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL
 github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
 github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
 github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
+github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
+github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
 github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
 github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
 github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
@@ -901,8 +876,6 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
 github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
 github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
 github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
-github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4=
-github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4=
 github.com/gabriel-vasile/mimetype v1.4.6 h1:3+PzJTKLkvgjeTbts6msPJt4DixhT4YtFNf1gtGe3zc=
 github.com/gabriel-vasile/mimetype v1.4.6/go.mod h1:JX1qVKqZd40hUPpAfiNTe0Sne7hdfKSbOqqmkq8GCXc=
 github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
@@ -918,6 +891,8 @@ github.com/go-acme/lego/v4 v4.19.2/go.mod h1:wtDe3dDkmV4/oI2nydpNXSJpvV10J9RCyZ6
 github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s=
 github.com/go-co-op/gocron v1.37.0 h1:ZYDJGtQ4OMhTLKOKMIch+/CY70Brbb1dGdooLEhh7b0=
 github.com/go-co-op/gocron v1.37.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY=
+github.com/go-co-op/gocron/v2 v2.12.1 h1:dCIIBFbzhWKdgXeEifBjHPzgQ1hoWhjS4289Hjjy1uw=
+github.com/go-co-op/gocron/v2 v2.12.1/go.mod h1:xY7bJxGazKam1cz04EebrlP4S9q4iWdiAylMGP3jY9w=
 github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
 github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
 github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
@@ -984,6 +959,7 @@ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x
 github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
 github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E=
 github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=
+github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
@@ -1193,10 +1169,6 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J
 github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4=
 github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.116 h1:2xdw38EHrdkciWjRdwd75p6a+cXe4PxWSgHMNYMbQnI=
-github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.116/go.mod h1:JWz2ujO9X3oU5wb6kXp+DpR2UuDj2SldDbX8T0FSuhI=
-github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.117 h1:TUiy5+4+Q7AWNfvKjQQL6lXOylnp7HL47JyYJ+HgN+I=
-github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.117/go.mod h1:JWz2ujO9X3oU5wb6kXp+DpR2UuDj2SldDbX8T0FSuhI=
 github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.118 h1:YHcixaT7Le4PxuxN07KQ5j9nPeH4ZdyXtMTSgA+Whh8=
 github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.118/go.mod h1:JWz2ujO9X3oU5wb6kXp+DpR2UuDj2SldDbX8T0FSuhI=
 github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
@@ -1210,14 +1182,62 @@ github.com/infobloxopen/infoblox-go-client v1.1.1 h1:728A6LbLjptj/7kZjHyIxQnm768
 github.com/infobloxopen/infoblox-go-client v1.1.1/go.mod h1:BXiw7S2b9qJoM8MS40vfgCNB2NLHGusk1DtO16BD9zI=
 github.com/itchyny/timefmt-go v0.1.6 h1:ia3s54iciXDdzWzwaVKXZPbiXzxxnv1SPGFfM/myJ5Q=
 github.com/itchyny/timefmt-go v0.1.6/go.mod h1:RRDZYC5s9ErkjQvTvvU7keJjxUYzIISJGxm9/mAERQg=
+github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
+github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
+github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
+github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
+github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
+github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
+github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
+github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
+github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
+github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
+github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
+github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w=
+github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM=
+github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
+github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
+github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
+github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
+github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
 github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
 github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
-github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA=
-github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
-github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
-github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
-github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
-github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
+github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=
+github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
+github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
+github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
+github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
+github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
+github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag=
+github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
+github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
+github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
+github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
+github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
+github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
+github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
+github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
+github.com/jackc/pgtype v1.14.4 h1:fKuNiCumbKTAIxQwXfB/nsrnkEI6bPJrrSiMKgbJ2j8=
+github.com/jackc/pgtype v1.14.4/go.mod h1:aKeozOde08iifGosdJpz9MBZonJOUJxqNpPBcMJTlVA=
+github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
+github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
+github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
+github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
+github.com/jackc/pgx/v4 v4.18.2 h1:xVpYkNR5pk5bMCZGfClbO962UIqVABcAGt7ha1s/FeU=
+github.com/jackc/pgx/v4 v4.18.2/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw=
+github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
+github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
+github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0=
+github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
+github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
 github.com/jarcoal/httpmock v1.0.8/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
 github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww=
 github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
@@ -1230,6 +1250,8 @@ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHW
 github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
 github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
+github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
 github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
 github.com/jpillora/overseer v1.1.6 h1:3ygYfNcR3FfOr22miu3vR1iQcXKMHbmULBh98rbkIyo=
 github.com/jpillora/overseer v1.1.6/go.mod h1:aPXQtxuVb9PVWRWTXpo+LdnC/YXQ0IBLNXqKMJmgk88=
@@ -1252,6 +1274,8 @@ github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E
 github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 h1:qGQQKEcAR99REcMpsXCp3lJ03zYT1PkRd3kQGPn9GVg=
 github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
+github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs=
+github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw=
 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
@@ -1265,6 +1289,7 @@ github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgSh
 github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00=
 github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
@@ -1275,6 +1300,7 @@ github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NB
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
 github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
@@ -1286,6 +1312,10 @@ github.com/labbsr0x/goh v1.0.1 h1:97aBJkDjpyBZGPbQuOK5/gHcSFbcr5aRsq3RSRJFpPk=
 github.com/labbsr0x/goh v1.0.1/go.mod h1:8K2UhVoaWXcCU7Lxoa2omWnC8gyW8px7/lmO61c027w=
 github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
 github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
+github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
 github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/linode/linodego v1.41.0 h1:GcP7JIBr9iLRJ9FwAtb9/WCT1DuPJS/xUApapfdjtiY=
@@ -1307,6 +1337,7 @@ github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPK
 github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
 github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
 github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
 github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
 github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
@@ -1316,6 +1347,8 @@ github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb
 github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
 github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
 github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
 github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
 github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
 github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
@@ -1423,10 +1456,6 @@ github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo=
 github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0=
 github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A=
 github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU=
-github.com/oracle/oci-go-sdk/v65 v65.75.1 h1:c7U7WQWeWZdPpzbsxf8dNRd4jXkyTNCNKaCAndvjTqw=
-github.com/oracle/oci-go-sdk/v65 v65.75.1/go.mod h1:IBEV9l1qBzUpo7zgGaRUhbB05BVfcDGYRFBCPlTcPp0=
-github.com/oracle/oci-go-sdk/v65 v65.75.2 h1:Qw3Eotrq7SJ5LquOc//Iq6xzcBJSi8AD3cXps9IBN7g=
-github.com/oracle/oci-go-sdk/v65 v65.75.2/go.mod h1:IBEV9l1qBzUpo7zgGaRUhbB05BVfcDGYRFBCPlTcPp0=
 github.com/oracle/oci-go-sdk/v65 v65.76.0 h1:mecdD9at/CMaQNEkcC5aMUR9aBF3brdiEyVkDRu/qVc=
 github.com/oracle/oci-go-sdk/v65 v65.76.0/go.mod h1:IBEV9l1qBzUpo7zgGaRUhbB05BVfcDGYRFBCPlTcPp0=
 github.com/ovh/go-ovh v1.6.0 h1:ixLOwxQdzYDx296sXcgS35TOPEahJkpjMGtzPadCjQI=
@@ -1493,6 +1522,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
 github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
 github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E=
+github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
 github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
 github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
 github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
@@ -1504,6 +1535,9 @@ github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4
 github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
 github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
 github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
+github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
+github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
+github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
@@ -1525,12 +1559,11 @@ github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6g
 github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
 github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc=
 github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU=
-github.com/sashabaranov/go-openai v1.31.0 h1:rGe77x7zUeCjtS2IS7NCY6Tp4bQviXNMhkQM6hz/UC4=
-github.com/sashabaranov/go-openai v1.31.0/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
-github.com/sashabaranov/go-openai v1.32.1 h1:JmdOa6d+cQwvGpBJigQf+dq40Qc20b+1HcXRGVOmqFw=
-github.com/sashabaranov/go-openai v1.32.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
 github.com/sashabaranov/go-openai v1.32.2 h1:8z9PfYaLPbRzmJIYpwcWu6z3XU8F+RwVMF1QRSeSF2M=
 github.com/sashabaranov/go-openai v1.32.2/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
+github.com/sashabaranov/go-openai v1.32.3 h1:6xZ393PbZFoJrgwveBXVZggmyH7zdp4joUdnCy7FFD8=
+github.com/sashabaranov/go-openai v1.32.3/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
+github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
 github.com/scaleway/scaleway-sdk-go v1.0.0-beta.30 h1:yoKAVkEVwAqbGbR8n87rHQ1dulL25rKloGadb3vm770=
 github.com/scaleway/scaleway-sdk-go v1.0.0-beta.30/go.mod h1:sH0u6fq6x4R5M7WxkoQFY/o7UaiItec0o1LinLCJNq8=
 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
@@ -1544,10 +1577,13 @@ github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFt
 github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
 github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
 github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
+github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
+github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
 github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
 github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
 github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
 github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
@@ -1568,6 +1604,8 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k
 github.com/sony/gobreaker v0.5.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
 github.com/sony/gobreaker v1.0.0 h1:feX5fGGXSl3dYd4aHZItw+FpHLvvoaqkawKjVNiFMNQ=
 github.com/sony/gobreaker v1.0.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
+github.com/sony/sonyflake v1.2.0 h1:Pfr3A+ejSg+0SPqpoAmQgEtNDAhc2G1SUYk205qVMLQ=
+github.com/sony/sonyflake v1.2.0/go.mod h1:LORtCywH/cq10ZbyfhKrHYgAUGH7mOBa76enV9txy/Y=
 github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
 github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
@@ -1598,6 +1636,7 @@ github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
 github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
 github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
 github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
@@ -1621,18 +1660,14 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69
 github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
 github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
 github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
-github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1015 h1:O60uxxfWztVPVUBQjlJaop2Dw/J7CXGK9fSErMdWw+Y=
-github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1015/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
-github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1021 h1:PziIST/T1MUZHQwCKpF+CX9FmBeTd3J6EJNbhtB31xI=
-github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1021/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1026 h1:6iBtl1CunsfWcT6IyCuRdgefJ/Zmsp5MTDujnolyuQs=
 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1026/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
-github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1015 h1:D+umrlpUPSDOiSLGIgPECIJ8Rrary9m7aFYnznbE/lM=
-github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1015/go.mod h1:QpUpIeygPrCIBKYX2gWvRFo7fdGHs3faTNFlmePVo3g=
-github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1021 h1:dijBHnKKmOoE6lDKGwmT4mPtmC/JVX8TrJkcyH5ioDU=
-github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1021/go.mod h1:zAlqm80JiBwcsJXEczgRtCvJxoT2HC3ZndyvKjP/uis=
+github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1028 h1:3rMKraYsxf5bQ4KglyzQ91vXZUXpUhn2Cdz9HkL125o=
+github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1028/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1026 h1:W6wPKS41uNKs7RBcJP5iB0HrcglXNSFUmnQaBEorVpg=
 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1026/go.mod h1:aqLJU0aRU1k7l+TPyYCao+KQHrFEF6lNQqK04FIiLJw=
+github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1028 h1:brTlgS0nWHFzw8aI67OEqEwpXhyeT781FDXV3bIEj/w=
+github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1028/go.mod h1:7dV6qKKfZ+x2iNcq4Drb5Pb1P/gNHg12R4xPy6+bo0M=
 github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
 github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
 github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU=
@@ -1653,14 +1688,18 @@ github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVK
 github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
 github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
 github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
-github.com/ultradns/ultradns-go-sdk v1.7.0-20240913052650-970ca9a h1:R6IR+Vj/RnGZLnX8PpPQsbbQthctO7Ah2q4tj5eoe2o=
-github.com/ultradns/ultradns-go-sdk v1.7.0-20240913052650-970ca9a/go.mod h1:BZr7Qs3ku1ckpqed8tCRSqTlp8NAeZfAVpfx4OzXMss=
 github.com/ultradns/ultradns-go-sdk v1.8.0-20241010134910-243eeec h1:2s/ghQ8wKE+UzD/hf3P4Gd1j0JI9ncbxv+nsypPoUYI=
 github.com/ultradns/ultradns-go-sdk v1.8.0-20241010134910-243eeec/go.mod h1:BZr7Qs3ku1ckpqed8tCRSqTlp8NAeZfAVpfx4OzXMss=
+github.com/uozi-tech/cosy v1.9.4 h1:oG5TbrS8XUpZnQ++9gxI5if0++uJ7h9nMPZPNeDgly0=
+github.com/uozi-tech/cosy v1.9.4/go.mod h1:aQI/OU3EVF125K5ECgSg3+CTfG4cp5XOkr++DEP/Fas=
+github.com/uozi-tech/cosy-driver-mysql v0.2.2 h1:22S/XNIvuaKGqxQPsYPXN8TZ8hHjCQdcJKVQ83Vzxoo=
+github.com/uozi-tech/cosy-driver-mysql v0.2.2/go.mod h1:EZnRIbSj1V5U0gEeTobrXai/d1SV11lkl4zP9NFEmyE=
+github.com/uozi-tech/cosy-driver-postgres v0.2.1 h1:OICakGuT+omva6QOJCxTJ5Lfr7CGXLmk/zD+aS51Z2o=
+github.com/uozi-tech/cosy-driver-postgres v0.2.1/go.mod h1:eAy1A89yHbAEfjkhNAifaJQk172NqrNoRyRtFcZc9Go=
+github.com/uozi-tech/cosy-driver-sqlite v0.2.0 h1:eTpIMyGoFUK4JcaiKfJHD5AyiM6vtCwN98c7Bz5n25o=
+github.com/uozi-tech/cosy-driver-sqlite v0.2.0/go.mod h1:87a6mzn5IuEtIR4z7U4Ey8eKLGfNEOSkv7kPQlbNQgM=
 github.com/vinyldns/go-vinyldns v0.9.16 h1:GZJStDkcCk1F1AcRc64LuuMh+ENL8pHA0CVd4ulRMcQ=
 github.com/vinyldns/go-vinyldns v0.9.16/go.mod h1:5qIJOdmzAnatKjurI+Tl4uTus7GJKJxb+zitufjHs3Q=
-github.com/vultr/govultr/v3 v3.9.1 h1:uxSIb8Miel7tqTs3ee+z3t+JelZikwqBBsZzCOPBy/8=
-github.com/vultr/govultr/v3 v3.9.1/go.mod h1:Rd8ebpXm7jxH3MDmhnEs+zrlYW212ouhx+HeUMfHm2o=
 github.com/vultr/govultr/v3 v3.10.0 h1:NjtFMcccmP2+5EXb5dEamwwrdeJjzzc8iAsPWOuAyao=
 github.com/vultr/govultr/v3 v3.10.0/go.mod h1:q34Wd76upKmf+vxFMgaNMH3A8BbsPBmSYZUGC8oZa5w=
 github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
@@ -1672,18 +1711,14 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2
 github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
 github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
-github.com/yandex-cloud/go-genproto v0.0.0-20241004153110-80386e3567fa h1:OEaAUuoBdU7Opsk/JP4KlNe8YCphmMr4ibyYIOAzAKE=
-github.com/yandex-cloud/go-genproto v0.0.0-20241004153110-80386e3567fa/go.mod h1:0LDD/IZLIUIV4iPH+YcF+jysO3jkSvADFGm4dCAuwQo=
-github.com/yandex-cloud/go-genproto v0.0.0-20241014130938-6bcc214f8c09 h1:yPngbVL7P9+BAA/F4ekNHW+Fxw+XhztG809lhlU7Yvk=
-github.com/yandex-cloud/go-genproto v0.0.0-20241014130938-6bcc214f8c09/go.mod h1:0LDD/IZLIUIV4iPH+YcF+jysO3jkSvADFGm4dCAuwQo=
 github.com/yandex-cloud/go-genproto v0.0.0-20241018072940-69706eaae3be h1:jGNL9PedKrHWl1WCRdlBEFo7nDl589LKvkulZRf7ZTA=
 github.com/yandex-cloud/go-genproto v0.0.0-20241018072940-69706eaae3be/go.mod h1:0LDD/IZLIUIV4iPH+YcF+jysO3jkSvADFGm4dCAuwQo=
-github.com/yandex-cloud/go-sdk v0.0.0-20240919120105-e63f9f4339a3 h1:t4T2EYu9LCNGYYjJA8x/ZIn8PHzJIxghjEGa9+Cx4xg=
-github.com/yandex-cloud/go-sdk v0.0.0-20240919120105-e63f9f4339a3/go.mod h1:RI42kDbwc4lOD8MtWmJDji5N/1P4AEToQQAprJby6XU=
-github.com/yandex-cloud/go-sdk v0.0.0-20241007112728-a06ce15e89c7 h1:pnIBO/B6vz9+JnHXGdxdAJ5OJePKEPccYJiFvKbTr1Y=
-github.com/yandex-cloud/go-sdk v0.0.0-20241007112728-a06ce15e89c7/go.mod h1:OISl+xMxmCNom9wbLTwfOWvlS9uu+PpdjKhXKYsXSgE=
+github.com/yandex-cloud/go-genproto v0.0.0-20241021132621-28bb61d00c2f h1:u7ETK40lM4ygnDzYtGFLk36fWARftvU+I0zwTYrOVwE=
+github.com/yandex-cloud/go-genproto v0.0.0-20241021132621-28bb61d00c2f/go.mod h1:0LDD/IZLIUIV4iPH+YcF+jysO3jkSvADFGm4dCAuwQo=
 github.com/yandex-cloud/go-sdk v0.0.0-20241018073342-0142f4806660 h1:/XDcP3XiGxwW6GGYzjHtQ82ZEEdpCuDQlmmsmx6Zyuc=
 github.com/yandex-cloud/go-sdk v0.0.0-20241018073342-0142f4806660/go.mod h1:7Ru6CfLQ1pfa5WcWdzdr8UY7xRsvVTykxBh5dzjx+Ic=
+github.com/yandex-cloud/go-sdk v0.0.0-20241021153520-213d4c625eca h1:m3Hne9w8jnfiPPDw9KqSLtRa7Et+gzCIub2ky5uUGGM=
+github.com/yandex-cloud/go-sdk v0.0.0-20241021153520-213d4c625eca/go.mod h1:id1/mPjMDlqamdsay74AJLVVLGCRTnjMIKuXpNzVN08=
 github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -1696,6 +1731,7 @@ github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo
 github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
 github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
 github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
+github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
 go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
 go.etcd.io/etcd/api/v3 v3.5.7/go.mod h1:9qew1gCdDDLu+VwmeG+iFpL+QlpHTo7iubavdVDgCAA=
 go.etcd.io/etcd/api/v3 v3.5.9/go.mod h1:uyAal843mC8uUVSLWz6eHa/d971iDGnCRpmKd2Z+X8k=
@@ -1715,26 +1751,21 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
 go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
 go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
 go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 h1:ZIg3ZT/aQ7AfKqdwp7ECpOK6vHqquXXuyTjIO8ZdmPs=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0/go.mod h1:DQAwmETtZV00skUwgD6+0U89g80NKsJE3DCKeLLPQMI=
 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s=
 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM=
-go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts=
-go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc=
 go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
 go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
-go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w=
-go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ=
 go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
 go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
-go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc=
-go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o=
 go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
 go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
 go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
 go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
 go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
+go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
@@ -1743,13 +1774,18 @@ go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ
 go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
 go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
+go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
 go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
 go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
 go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
 go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
 go.uber.org/ratelimit v0.3.1 h1:K4qVE+byfv/B3tC+4nYWP7v/6SimcO7HzHekoMNBma0=
 go.uber.org/ratelimit v0.3.1/go.mod h1:6euWsTB6U/Nb3X++xEUXA8ciPJvr19Q/0h1+oDcJhRk=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
+go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
 go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
 go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
 go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
@@ -1759,6 +1795,7 @@ golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -1767,8 +1804,11 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
+golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
@@ -1782,6 +1822,7 @@ golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0
 golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
 golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
 golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
+golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
 golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
 golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
 golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
@@ -1800,8 +1841,6 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
 golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
 golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
-golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6 h1:1wqE9dj9NpSm04INVsJhhEUzhuDVjbcyKH91sVyPATw=
-golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
 golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
 golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
 golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
@@ -1866,6 +1905,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -1983,6 +2023,7 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1991,6 +2032,7 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -2148,16 +2190,20 @@ golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3
 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -2166,6 +2212,7 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
@@ -2208,6 +2255,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
 golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
 golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
+golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -2282,10 +2331,6 @@ google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60c
 google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0=
 google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg=
 google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms=
-google.golang.org/api v0.199.0 h1:aWUXClp+VFJmqE0JPvpZOK3LDQMyFKYIow4etYd9qxs=
-google.golang.org/api v0.199.0/go.mod h1:ohG4qSztDJmZdjK/Ar6MhbAmb/Rpi4JHOqagsh90K28=
-google.golang.org/api v0.200.0 h1:0ytfNWn101is6e9VBoct2wrGDjOi5vn7jw5KtaQgDrU=
-google.golang.org/api v0.200.0/go.mod h1:Tc5u9kcbjO7A8SwGlYj4IiVifJU01UqXtEgDMYmBmV8=
 google.golang.org/api v0.201.0 h1:+7AD9JNM3tREtawRMu8sOjSbb8VYcYXJG/2eEOmfDu0=
 google.golang.org/api v0.201.0/go.mod h1:HVY0FCHVs89xIW9fzf/pBvOEm+OolHa86G/txFezyq4=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
@@ -2427,24 +2472,18 @@ google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOl
 google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=
 google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=
 google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
-google.golang.org/genproto v0.0.0-20240930140551-af27646dc61f h1:mCJ6SGikSxVlt9scCayUl2dMq0msUgmBArqRY6umieI=
-google.golang.org/genproto v0.0.0-20240930140551-af27646dc61f/go.mod h1:xtVODtPkMQRUZ4kqOTgp6JrXQrPevvfCSdk4mJtHUbM=
-google.golang.org/genproto v0.0.0-20241007155032-5fefd90f89a9 h1:nFS3IivktIU5Mk6KQa+v6RKkHUpdQpphqGNLxqNnbEk=
-google.golang.org/genproto v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:tEzYTYZxbmVNOu0OAFH9HzdJtLn6h4Aj89zzlBCdHms=
 google.golang.org/genproto v0.0.0-20241015192408-796eee8c2d53 h1:Df6WuGvthPzc+JiQ/G+m+sNX24kc0aTBqoDN/0yyykE=
 google.golang.org/genproto v0.0.0-20241015192408-796eee8c2d53/go.mod h1:fheguH3Am2dGp1LfXkrvwqC/KlFq8F0nLq3LryOMrrE=
-google.golang.org/genproto/googleapis/api v0.0.0-20240930140551-af27646dc61f h1:jTm13A2itBi3La6yTGqn8bVSrc3ZZ1r8ENHlIXBfnRA=
-google.golang.org/genproto/googleapis/api v0.0.0-20240930140551-af27646dc61f/go.mod h1:CLGoBuH1VHxAUXVPP8FfPwPEVJB6lz3URE5mY2SuayE=
-google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg=
-google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M=
+google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 h1:Q3nlH8iSQSRUwOskjbcSMcF2jiYMNiQYZ0c2KEJLKKU=
+google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38/go.mod h1:xBI+tzfqGGN2JBeSebfKXFSdBpWVQ7sLW40PTupVRm4=
 google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 h1:fVoAXEKA4+yufmbdVYv+SE73+cPZbbbe8paLsHfkK+U=
 google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53/go.mod h1:riSXTwQ4+nqmPGtobMFyW5FqVAmIs0St6VPp4Ug7CE4=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f h1:cUMEy+8oS78BWIH9OWazBkzbr090Od9tWBNtZHkOhf0=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
+google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38 h1:2oV8dfuIkM1Ti7DwXc0BJfnwr9csz4TDXI9EmiI+Rbw=
+google.golang.org/genproto/googleapis/api v0.0.0-20241021214115-324edc3d5d38/go.mod h1:vuAjtvlwkDKF6L1GQ0SokiRLCGFfeBUXWr/aFFkHACc=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 h1:zciRKQ4kBpFgpfC5QQCVtnnNAcLIqweL7plyZRQHVpI=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
 google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@@ -2507,8 +2546,6 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
 google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
-google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
 google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
 google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
@@ -2525,6 +2562,7 @@ gopkg.in/guregu/null.v4 v4.0.0 h1:1Wm3S1WEA2I26Kq+6vcW+w0gcDo44YKYD7YIEJNHDjg=
 gopkg.in/guregu/null.v4 v4.0.0/go.mod h1:YoQhUrADuG3i9WqesrCmpNRwm1ypAgSHYqoOcTu/JrI=
 gopkg.in/h2non/gock.v1 v1.0.15 h1:SzLqcIlb/fDfg7UvukMpNcWsu7sI5tWwL+KCATZqks0=
 gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=
+gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
@@ -2532,8 +2570,6 @@ gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
 gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/ns1/ns1-go.v2 v2.12.1 h1:GiiZPB8JusUF/ruyUDzddd70b3HZGa5A3njtKUe84jA=
-gopkg.in/ns1/ns1-go.v2 v2.12.1/go.mod h1:pfaU0vECVP7DIOr453z03HXS6dFJpXdNRwOyRzwmPSc=
 gopkg.in/ns1/ns1-go.v2 v2.12.2 h1:SPM5BTTMJ1zVBhMMiiPFdF7l6Y3fq5o7bKM7jDqsUfM=
 gopkg.in/ns1/ns1-go.v2 v2.12.2/go.mod h1:pfaU0vECVP7DIOr453z03HXS6dFJpXdNRwOyRzwmPSc=
 gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
@@ -2554,16 +2590,12 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C
 gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gorm.io/datatypes v1.2.2 h1:sdn7ZmG4l7JWtMDUb3L98f2Ym7CO5F8mZLlrQJMfF9g=
-gorm.io/datatypes v1.2.2/go.mod h1:f4BsLcFAX67szSv8svwLRjklArSHAvHLeE3pXAS5DZI=
-gorm.io/datatypes v1.2.3 h1:95ucr9ip9dZMPhB3Tc9zbcoAi62hxYAgHicu7SLjK4g=
-gorm.io/datatypes v1.2.3/go.mod h1:f4BsLcFAX67szSv8svwLRjklArSHAvHLeE3pXAS5DZI=
 gorm.io/datatypes v1.2.4 h1:uZmGAcK/QZ0uyfCuVg0VQY1ZmV9h1fuG0tMwKByO1z4=
 gorm.io/datatypes v1.2.4/go.mod h1:f4BsLcFAX67szSv8svwLRjklArSHAvHLeE3pXAS5DZI=
 gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
 gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
-gorm.io/driver/postgres v1.5.6 h1:ydr9xEd5YAM0vxVDY0X139dyzNz10spDiDlC7+ibLeU=
-gorm.io/driver/postgres v1.5.6/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA=
+gorm.io/driver/postgres v1.5.9 h1:DkegyItji119OlcaLjqN11kHoUgZ/j13E0jkJZgD6A8=
+gorm.io/driver/postgres v1.5.9/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
 gorm.io/driver/sqlite v1.5.0/go.mod h1:kDMDfntV9u/vuMmz8APHtHF0b4nyBB7sfCieC6G8k8I=
 gorm.io/driver/sqlite v1.5.6 h1:fO/X46qn5NUEEOZtnjJRWRzZMe8nqJiQ9E+0hi+hKQE=
 gorm.io/driver/sqlite v1.5.6/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
@@ -2637,8 +2669,6 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8
 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
 rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
-sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
-sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
 sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
 sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
 sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=

BIN
img.png


+ 10 - 1
install.sh

@@ -289,10 +289,19 @@ install_config() {
     mkdir -p "$DataPath"
     if [[ ! -f "$DataPath/app.ini" ]]; then
 cat > "$DataPath/app.ini" << EOF
+[app]
+PageSize = 10
+
 [server]
+HOST = 0.0.0.0
+PORT = 9000
 RunMode = release
-HttpPort = 9000
+
+[cert]
 HTTPChallengePort = 9180
+
+[terminal]
+StartCmd = login
 EOF
         echo "info: The default configuration file was installed to '$DataPath/app.ini' successfully!"
     fi

Some files were not shown because too many files changed in this diff