2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 04:22:33 +08:00

feat: 支持自定义IP头,close #901

This commit is contained in:
2025-10-11 00:42:42 +08:00
parent 8d50b7c082
commit 2fefba51e1
18 changed files with 143 additions and 188 deletions

View File

@@ -68,7 +68,7 @@ func initWeb() (*app.Web, error) {
queue := bootstrap.NewQueue()
taskRepo := data.NewTaskRepo(locale, db, logger, queue)
appRepo := data.NewAppRepo(locale, koanf, db, logger, cacheRepo, taskRepo)
userTokenRepo := data.NewUserTokenRepo(locale, db)
userTokenRepo := data.NewUserTokenRepo(locale, koanf, db)
middlewares := middleware.NewMiddlewares(koanf, manager, appRepo, userTokenRepo)
userRepo := data.NewUserRepo(locale, db)
userService := service.NewUserService(locale, koanf, manager, userRepo)
@@ -142,7 +142,7 @@ func initWeb() (*app.Web, error) {
s3fsApp := s3fs.NewApp(locale)
supervisorApp := supervisor.NewApp(locale)
loader := bootstrap.NewLoader(codeserverApp, dockerApp, fail2banApp, frpApp, giteaApp, memcachedApp, minioApp, mysqlApp, nginxApp, php74App, php80App, php81App, php82App, php83App, php84App, phpmyadminApp, podmanApp, postgresqlApp, pureftpdApp, redisApp, rsyncApp, s3fsApp, supervisorApp)
http := route.NewHttp(userService, userTokenService, dashboardService, taskService, websiteService, databaseService, databaseServerService, databaseUserService, backupService, certService, certDNSService, certAccountService, appService, cronService, processService, safeService, firewallService, sshService, containerService, containerComposeService, containerNetworkService, containerImageService, containerVolumeService, fileService, monitorService, settingService, systemctlService, toolboxSystemService, toolboxBenchmarkService, loader)
http := route.NewHttp(koanf, userService, userTokenService, dashboardService, taskService, websiteService, databaseService, databaseServerService, databaseUserService, backupService, certService, certDNSService, certAccountService, appService, cronService, processService, safeService, firewallService, sshService, containerService, containerComposeService, containerNetworkService, containerImageService, containerVolumeService, fileService, monitorService, settingService, systemctlService, toolboxSystemService, toolboxBenchmarkService, loader)
wsService := service.NewWsService(locale, koanf, sshRepo)
ws := route.NewWs(wsService)
mux, err := bootstrap.NewRouter(locale, middlewares, http, ws)

View File

@@ -9,6 +9,10 @@ http:
port: 8888
entrance: /
tls: true
ip_header: ''
bind_domain: []
bind_ip: []
bind_ua: []
database:
debug: false
session:

2
go.mod
View File

@@ -12,10 +12,10 @@ require (
github.com/creack/pty v1.1.24
github.com/expr-lang/expr v1.17.6
github.com/go-chi/chi/v5 v5.2.3
github.com/go-chi/httplog/v3 v3.3.0
github.com/go-gormigrate/gormigrate/v2 v2.1.5
github.com/go-resty/resty/v2 v2.16.5
github.com/go-sql-driver/mysql v1.9.3
github.com/golang-cz/httplog v0.0.2
github.com/gomodule/redigo v1.9.3
github.com/google/wire v0.7.0
github.com/gookit/color v1.6.0

4
go.sum
View File

@@ -100,6 +100,8 @@ github.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9t
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE=
github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
github.com/go-chi/httplog/v3 v3.3.0 h1:Gr6Y7nSzbpyCyRwKPOVKjDH3BH6TH5uvRNDsTZWDpvU=
github.com/go-chi/httplog/v3 v3.3.0/go.mod h1:N/J1l5l1fozUrqIVuT8Z/HzNeSy8TF2EFyokPLe6y2w=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gormigrate/gormigrate/v2 v2.1.5 h1:1OyorA5LtdQw12cyJDEHuTrEV3GiXiIhS4/QTTa/SM8=
github.com/go-gormigrate/gormigrate/v2 v2.1.5/go.mod h1:mj9ekk/7CPF3VjopaFvWKN2v7fN3D9d3eEOAXRhi/+M=
@@ -120,8 +122,6 @@ github.com/gofiber/schema v1.6.0 h1:rAgVDFwhndtC+hgV7Vu5ItQCn7eC2mBA4Eu1/ZTiEYY=
github.com/gofiber/schema v1.6.0/go.mod h1:WNZWpQx8LlPSK7ZaX0OqOh+nQo/eW2OevsXs1VZfs/s=
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/golang-cz/httplog v0.0.2 h1:3d8iScWLeMWQG5/bfMZ5Dizh+zvRfNmLBZMe5N2HrGU=
github.com/golang-cz/httplog v0.0.2/go.mod h1:bgk4Ij/0OQ89UeoFFAQrSNhbbr4rKJ0fwWfo7wc+TCc=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=

View File

@@ -241,6 +241,7 @@ func (r *settingRepo) GetPanel() (*request.SettingPanel, error) {
OfflineMode: offlineMode,
AutoUpdate: autoUpdate,
Lifetime: uint(r.conf.Int("session.lifetime")),
IPHeader: r.conf.String("http.ip_header"),
BindDomain: r.conf.Strings("http.bind_domain"),
BindIP: r.conf.Strings("http.bind_ip"),
BindUA: r.conf.Strings("http.bind_ua"),
@@ -331,6 +332,7 @@ func (r *settingRepo) UpdatePanel(req *request.SettingPanel) (bool, error) {
config.HTTP.Port = req.Port
config.HTTP.Entrance = req.Entrance
config.HTTP.TLS = req.HTTPS
config.HTTP.IPHeader = req.IPHeader
config.HTTP.BindDomain = req.BindDomain
config.HTTP.BindIP = req.BindIP
config.HTTP.BindUA = req.BindUA

View File

@@ -14,6 +14,7 @@ import (
"strings"
"time"
"github.com/knadh/koanf/v2"
"github.com/leonelquinteros/gotext"
"github.com/libtnb/utils/str"
"github.com/spf13/cast"
@@ -23,14 +24,16 @@ import (
)
type userTokenRepo struct {
t *gotext.Locale
db *gorm.DB
t *gotext.Locale
conf *koanf.Koanf
db *gorm.DB
}
func NewUserTokenRepo(t *gotext.Locale, db *gorm.DB) biz.UserTokenRepo {
func NewUserTokenRepo(t *gotext.Locale, conf *koanf.Koanf, db *gorm.DB) biz.UserTokenRepo {
return &userTokenRepo{
t: t,
db: db,
t: t,
conf: conf,
db: db,
}
}
@@ -140,10 +143,16 @@ func (r userTokenRepo) ValidateReq(req *http.Request) (uint, error) {
// 步骤六验证IP
if len(userToken.IPs) > 0 {
ip, _, err := net.SplitHostPort(req.RemoteAddr)
ip := req.RemoteAddr
ipHeader := r.conf.String("http.ip_header")
if ipHeader != "" && req.Header.Get(ipHeader) != "" {
ip = strings.Split(req.Header.Get(ipHeader), ",")[0]
}
ip, _, err = net.SplitHostPort(strings.TrimSpace(ip))
if err != nil {
ip = req.RemoteAddr
}
allowed := false
requestIP := net.ParseIP(ip)
if requestIP != nil {

View File

@@ -43,10 +43,18 @@ func Entrance(t *gotext.Locale, conf *koanf.Koanf, session *sessions.Manager) fu
Abort(w, http.StatusTeapot, t.Get("invalid request domain: %s", r.Host))
return
}
ip, _, err := net.SplitHostPort(r.RemoteAddr)
// 取请求 IP
ip := r.RemoteAddr
ipHeader := conf.String("http.ip_header")
if ipHeader != "" && r.Header.Get(ipHeader) != "" {
ip = strings.Split(r.Header.Get(ipHeader), ",")[0]
}
ip, _, err = net.SplitHostPort(strings.TrimSpace(ip))
if err != nil {
ip = r.RemoteAddr
}
if len(conf.Strings("http.bind_ip")) > 0 {
allowed := false
requestIP := net.ParseIP(ip)

View File

@@ -8,7 +8,7 @@ import (
"github.com/acepanel/panel/internal/app"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/golang-cz/httplog"
"github.com/go-chi/httplog/v3"
"github.com/google/wire"
"github.com/knadh/koanf/v2"
"github.com/leonelquinteros/gotext"
@@ -52,14 +52,22 @@ func (r *Middlewares) Globals(t *gotext.Locale, mux *chi.Mux) []func(http.Handle
middleware.Recoverer,
//middleware.SupressNotFound(mux),// bug https://github.com/go-chi/chi/pull/940
httplog.RequestLogger(r.log, &httplog.Options{
Level: slog.LevelInfo,
LogRequestHeaders: []string{"User-Agent"},
Skip: func(req *http.Request, respStatus int) bool {
return respStatus == 404 || respStatus == 405
},
LogRequestBody: func(req *http.Request) bool {
return req.Header.Get("X-Debug-Request") == "1"
},
LogResponseBody: func(req *http.Request) bool {
return req.Header.Get("X-Debug-Response") == "1"
},
}),
middleware.Compress(5),
sessionmiddleware.StartSession(r.session),
Status(t),
Entrance(t, r.conf, r.session),
MustLogin(t, r.session, r.userToken),
MustLogin(t, r.conf, r.session, r.userToken),
MustInstall(t, r.appRepo),
}
}

View File

@@ -10,6 +10,7 @@ import (
"strings"
"time"
"github.com/knadh/koanf/v2"
"github.com/leonelquinteros/gotext"
"github.com/libtnb/sessions"
"github.com/spf13/cast"
@@ -18,7 +19,7 @@ import (
)
// MustLogin 确保已登录
func MustLogin(t *gotext.Locale, session *sessions.Manager, userToken biz.UserTokenRepo) func(next http.Handler) http.Handler {
func MustLogin(t *gotext.Locale, conf *koanf.Koanf, session *sessions.Manager, userToken biz.UserTokenRepo) func(next http.Handler) http.Handler {
// 白名单
whiteList := []string{
"/api/user/key",
@@ -62,9 +63,18 @@ func MustLogin(t *gotext.Locale, session *sessions.Manager, userToken biz.UserTo
safeLogin := cast.ToBool(sess.Get("safe_login"))
if safeLogin {
safeClientHash := cast.ToString(sess.Get("safe_client"))
ip, _, _ := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr))
// 取请求 IP
ip := r.RemoteAddr
ipHeader := conf.String("http.ip_header")
if ipHeader != "" && r.Header.Get(ipHeader) != "" {
ip = strings.Split(r.Header.Get(ipHeader), ",")[0]
}
ip, _, err = net.SplitHostPort(strings.TrimSpace(ip))
if err != nil {
ip = r.RemoteAddr
}
clientHash := fmt.Sprintf("%x", sha256.Sum256([]byte(ip)))
safeClientHash := cast.ToString(sess.Get("safe_client"))
if safeClientHash != clientHash || safeClientHash == "" {
sess.Forget("user_id") // 清除 user_id否则会来回跳转
Abort(w, http.StatusUnauthorized, t.Get("client ip/ua changed, please login again"))

View File

@@ -10,7 +10,7 @@ import (
)
// Throttle 限流器
func Throttle(tokens uint64, interval time.Duration) func(next http.Handler) http.Handler {
func Throttle(ipHeader string, tokens uint64, interval time.Duration) func(next http.Handler) http.Handler {
store, err := memorystore.New(&memorystore.Config{
Tokens: tokens,
Interval: interval,
@@ -19,7 +19,7 @@ func Throttle(tokens uint64, interval time.Duration) func(next http.Handler) htt
log.Fatalf("failed to create throttle memorystore: %v", err)
}
limiter, err := httplimit.NewMiddleware(store, httplimit.IPKeyFunc())
limiter, err := httplimit.NewMiddleware(store, httplimit.IPKeyFunc(ipHeader))
if err != nil {
log.Fatalf("failed to initialize throttle middleware: %v", err)
}

View File

@@ -11,6 +11,7 @@ type SettingPanel struct {
AutoUpdate bool `json:"auto_update"`
TwoFA bool `json:"two_fa"`
Lifetime uint `json:"lifetime" validate:"required|min:10|max:43200"` // 登录超时,单位:分
IPHeader string `json:"ip_header"`
BindDomain []string `json:"bind_domain"`
BindIP []string `json:"bind_ip"`
BindUA []string `json:"bind_ua"`

View File

@@ -7,6 +7,7 @@ import (
"time"
"github.com/go-chi/chi/v5"
"github.com/knadh/koanf/v2"
"github.com/acepanel/panel/internal/http/middleware"
"github.com/acepanel/panel/internal/service"
@@ -15,6 +16,7 @@ import (
)
type Http struct {
conf *koanf.Koanf
user *service.UserService
userToken *service.UserTokenService
dashboard *service.DashboardService
@@ -48,6 +50,7 @@ type Http struct {
}
func NewHttp(
conf *koanf.Koanf,
user *service.UserService,
userToken *service.UserTokenService,
dashboard *service.DashboardService,
@@ -80,6 +83,7 @@ func NewHttp(
apps *apploader.Loader,
) *Http {
return &Http{
conf: conf,
user: user,
userToken: userToken,
dashboard: dashboard,
@@ -117,7 +121,7 @@ func (route *Http) Register(r *chi.Mux) {
r.Route("/api", func(r chi.Router) {
r.Route("/user", func(r chi.Router) {
r.Get("/key", route.user.GetKey)
r.With(middleware.Throttle(5, time.Minute)).Post("/login", route.user.Login)
r.With(middleware.Throttle(route.conf.String("http.ip_header"), 5, time.Minute)).Post("/login", route.user.Login)
r.Post("/logout", route.user.Logout)
r.Get("/is_login", route.user.IsLogin)
r.Get("/is_2fa", route.user.IsTwoFA)

View File

@@ -107,11 +107,16 @@ func (s *UserService) Login(w http.ResponseWriter, r *http.Request) {
// 安全登录下,将当前客户端与会话绑定
// 安全登录只在未启用面板 HTTPS 时生效
ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr))
if err != nil {
Error(w, http.StatusInternalServerError, "%v", err)
return
ip := r.RemoteAddr
ipHeader := s.conf.String("http.ip_header")
if ipHeader != "" && r.Header.Get(ipHeader) != "" {
ip = strings.Split(r.Header.Get(ipHeader), ",")[0]
}
ip, _, err = net.SplitHostPort(strings.TrimSpace(ip))
if err != nil {
ip = r.RemoteAddr
}
if req.SafeLogin && !s.conf.Bool("http.tls") {
sess.Put("safe_login", true)
sess.Put("safe_client", fmt.Sprintf("%x", sha256.Sum256([]byte(ip))))

View File

@@ -21,6 +21,7 @@ type PanelHTTPConfig struct {
Port uint `yaml:"port"`
Entrance string `yaml:"entrance"`
TLS bool `yaml:"tls"`
IPHeader string `yaml:"ip_header"`
BindDomain []string `yaml:"bind_domain"`
BindIP []string `yaml:"bind_ip"`
BindUA []string `yaml:"bind_ua"`

205
web/pnpm-lock.yaml generated
View File

@@ -134,7 +134,7 @@ importers:
version: 10.2.0(eslint@9.37.0(jiti@2.6.1))(prettier@3.6.2)
'@vue/eslint-config-typescript':
specifier: ^14.5.0
version: 14.6.0(eslint-plugin-vue@10.5.0(@typescript-eslint/parser@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.37.0(jiti@2.6.1))))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
version: 14.6.0(eslint-plugin-vue@10.5.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.37.0(jiti@2.6.1))))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
'@vue/tsconfig':
specifier: ^0.8.0
version: 0.8.1(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3))
@@ -149,7 +149,7 @@ importers:
version: 9.37.0(jiti@2.6.1)
eslint-plugin-vue:
specifier: ^10.1.0
version: 10.5.0(@typescript-eslint/parser@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.37.0(jiti@2.6.1)))
version: 10.5.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.37.0(jiti@2.6.1)))
md-editor-v3:
specifier: ^6.0.0
version: 6.1.0(vue@3.5.22(typescript@5.9.3))
@@ -1071,87 +1071,54 @@ packages:
'@types/web-bluetooth@0.0.21':
resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==}
'@typescript-eslint/eslint-plugin@8.45.0':
resolution: {integrity: sha512-HC3y9CVuevvWCl/oyZuI47dOeDF9ztdMEfMH8/DW/Mhwa9cCLnK1oD7JoTVGW/u7kFzNZUKUoyJEqkaJh5y3Wg==}
'@typescript-eslint/eslint-plugin@8.46.0':
resolution: {integrity: sha512-hA8gxBq4ukonVXPy0OKhiaUh/68D0E88GSmtC1iAEnGaieuDi38LhS7jdCHRLi6ErJBNDGCzvh5EnzdPwUc0DA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
'@typescript-eslint/parser': ^8.45.0
'@typescript-eslint/parser': ^8.46.0
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/parser@8.45.0':
resolution: {integrity: sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ==}
'@typescript-eslint/parser@8.46.0':
resolution: {integrity: sha512-n1H6IcDhmmUEG7TNVSspGmiHHutt7iVKtZwRppD7e04wha5MrkV1h3pti9xQLcCMt6YWsncpoT0HMjkH1FNwWQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/project-service@8.45.0':
resolution: {integrity: sha512-3pcVHwMG/iA8afdGLMuTibGR7pDsn9RjDev6CCB+naRsSYs2pns5QbinF4Xqw6YC/Sj3lMrm/Im0eMfaa61WUg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/project-service@8.46.0':
resolution: {integrity: sha512-OEhec0mH+U5Je2NZOeK1AbVCdm0ChyapAyTeXVIYTPXDJ3F07+cu87PPXcGoYqZ7M9YJVvFnfpGg1UmCIqM+QQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/scope-manager@8.45.0':
resolution: {integrity: sha512-clmm8XSNj/1dGvJeO6VGH7EUSeA0FMs+5au/u3lrA3KfG8iJ4u8ym9/j2tTEoacAffdW1TVUzXO30W1JTJS7dA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/scope-manager@8.46.0':
resolution: {integrity: sha512-lWETPa9XGcBes4jqAMYD9fW0j4n6hrPtTJwWDmtqgFO/4HF4jmdH/Q6wggTw5qIT5TXjKzbt7GsZUBnWoO3dqw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/tsconfig-utils@8.45.0':
resolution: {integrity: sha512-aFdr+c37sc+jqNMGhH+ajxPXwjv9UtFZk79k8pLoJ6p4y0snmYpPA52GuWHgt2ZF4gRRW6odsEj41uZLojDt5w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/tsconfig-utils@8.46.0':
resolution: {integrity: sha512-WrYXKGAHY836/N7zoK/kzi6p8tXFhasHh8ocFL9VZSAkvH956gfeRfcnhs3xzRy8qQ/dq3q44v1jvQieMFg2cw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/type-utils@8.45.0':
resolution: {integrity: sha512-bpjepLlHceKgyMEPglAeULX1vixJDgaKocp0RVJ5u4wLJIMNuKtUXIczpJCPcn2waII0yuvks/5m5/h3ZQKs0A==}
'@typescript-eslint/type-utils@8.46.0':
resolution: {integrity: sha512-hy+lvYV1lZpVs2jRaEYvgCblZxUoJiPyCemwbQZ+NGulWkQRy0HRPYAoef/CNSzaLt+MLvMptZsHXHlkEilaeg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/types@8.45.0':
resolution: {integrity: sha512-WugXLuOIq67BMgQInIxxnsSyRLFxdkJEJu8r4ngLR56q/4Q5LrbfkFRH27vMTjxEK8Pyz7QfzuZe/G15qQnVRA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/types@8.46.0':
resolution: {integrity: sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/typescript-estree@8.45.0':
resolution: {integrity: sha512-GfE1NfVbLam6XQ0LcERKwdTTPlLvHvXXhOeUGC1OXi4eQBoyy1iVsW+uzJ/J9jtCz6/7GCQ9MtrQ0fml/jWCnA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/typescript-estree@8.46.0':
resolution: {integrity: sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/utils@8.45.0':
resolution: {integrity: sha512-bxi1ht+tLYg4+XV2knz/F7RVhU0k6VrSMc9sb8DQ6fyCTrGQLHfo7lDtN0QJjZjKkLA2ThrKuCdHEvLReqtIGg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/utils@8.46.0':
resolution: {integrity: sha512-nD6yGWPj1xiOm4Gk0k6hLSZz2XkNXhuYmyIrOWcHoPuAhjT9i5bAG+xbWPgFeNR8HPHHtpNKdYUXJl/D3x7f5g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -1159,10 +1126,6 @@ packages:
eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/visitor-keys@8.45.0':
resolution: {integrity: sha512-qsaFBA3e09MIDAGFUrTk+dzqtfv1XPVz8t8d1f0ybTzrCY7BKiMC5cjrl1O/P7UmHsNyW90EYSkU/ZWpmXelag==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/visitor-keys@8.46.0':
resolution: {integrity: sha512-FrvMpAK+hTbFy7vH5j1+tMYHMSKLE6RzluFJlkFNKD0p9YsUT75JlBSmr5so3QRzvMwU5/bIEdeNrxm8du8l3Q==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -1515,8 +1478,8 @@ packages:
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
baseline-browser-mapping@2.8.12:
resolution: {integrity: sha512-vAPMQdnyKCBtkmQA6FMCBvU9qFIppS3nzyXnEM+Lo2IAhG4Mpjv9cCxMudhgV3YdNNJv6TNqXy97dfRVL2LmaQ==}
baseline-browser-mapping@2.8.16:
resolution: {integrity: sha512-OMu3BGQ4E7P1ErFsIPpbJh0qvDudM/UuJeHgkAvfWe+0HFJCXh+t/l8L6fVLR55RI/UbKrVLnAXZSVwd9ysWYw==}
hasBin: true
binary-extensions@2.3.0:
@@ -1580,8 +1543,8 @@ packages:
camel-case@4.1.2:
resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==}
caniuse-lite@1.0.30001748:
resolution: {integrity: sha512-5P5UgAr0+aBmNiplks08JLw+AW/XG/SurlgZLgB1dDLfAw7EfRGxIwzPHxdSCGY/BTKDqIVyJL87cCN6s0ZR0w==}
caniuse-lite@1.0.30001749:
resolution: {integrity: sha512-0rw2fJOmLfnzCRbkm8EyHL8SvI2Apu5UbnQuTsJ0ClgrH8hcwFooJ1s5R0EP8o8aVrFu8++ae29Kt9/gZAZp/Q==}
chainsaw@0.0.9:
resolution: {integrity: sha512-nG8PYH+/4xB+8zkV4G844EtfvZ5tTiLFoX3dZ4nhF4t3OCKIb9UvaFyNmeZO2zOSmRWzBoTD+napN6hiL+EgcA==}
@@ -1840,8 +1803,8 @@ packages:
engines: {node: '>=0.10.0'}
hasBin: true
electron-to-chromium@1.5.230:
resolution: {integrity: sha512-A6A6Fd3+gMdaed9wX83CvHYJb4UuapPD5X5SLq72VZJzxHSY0/LUweGXRWmQlh2ln7KV7iw7jnwXK7dlPoOnHQ==}
electron-to-chromium@1.5.234:
resolution: {integrity: sha512-RXfEp2x+VRYn8jbKfQlRImzoJU01kyDvVPBmG39eU2iuRVhuS6vQNocB8J0/8GrIMLnPzgz4eW6WiRnJkTuNWg==}
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@@ -2124,8 +2087,8 @@ packages:
resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
engines: {node: '>= 0.4'}
get-tsconfig@4.10.1:
resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==}
get-tsconfig@4.12.0:
resolution: {integrity: sha512-LScr2aNr2FbjAjZh2C6X6BxRx1/x+aTDExct/xyq2XKbYOiG5c0aK7pMsSuyc0brz3ibr/lbQiHD9jzt4lccJw==}
glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
@@ -2727,8 +2690,8 @@ packages:
package-json-from-dist@1.0.1:
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
package-manager-detector@1.3.0:
resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==}
package-manager-detector@1.4.0:
resolution: {integrity: sha512-rRZ+pR1Usc+ND9M2NkmCvE/LYJS+8ORVV9X0KuNSY/gFsp7RBHJM/ADh9LYq4Vvfq6QkKrW6/weuh8SMEtN5gw==}
param-case@3.0.4:
resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==}
@@ -3191,8 +3154,8 @@ packages:
resolution: {integrity: sha512-q7QNVDGTdl702bVFiI5eY4l/HkgCM6at9KhcFbgUAzezHFbOVy4+0O/lCjsABEQwbZPravVfBIiBVGo89yzHFg==}
engines: {node: '>= 0.4'}
typescript-eslint@8.45.0:
resolution: {integrity: sha512-qzDmZw/Z5beNLUrXfd0HIW6MzIaAV5WNDxmMs9/3ojGOpYavofgNAAD/nC6tGV2PczIi0iw8vot2eAe/sBn7zg==}
typescript-eslint@8.46.0:
resolution: {integrity: sha512-6+ZrB6y2bT2DX3K+Qd9vn7OFOJR+xSLDj+Aw/N3zBwUt27uTw2sw2TE2+UcY1RiyBZkaGbTkVg9SSdPNUG6aUw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
@@ -3566,7 +3529,7 @@ snapshots:
'@antfu/install-pkg@1.1.0':
dependencies:
package-manager-detector: 1.3.0
package-manager-detector: 1.4.0
tinyexec: 1.0.1
'@antfu/utils@9.3.0': {}
@@ -3746,14 +3709,14 @@ snapshots:
'@babel/template@7.27.2':
dependencies:
'@babel/code-frame': 7.27.1
'@babel/parser': 7.28.4
'@babel/parser': 7.27.7
'@babel/types': 7.28.4
'@babel/traverse@7.27.7':
dependencies:
'@babel/code-frame': 7.27.1
'@babel/generator': 7.28.3
'@babel/parser': 7.28.4
'@babel/parser': 7.27.7
'@babel/template': 7.27.2
'@babel/types': 7.28.4
debug: 4.4.3
@@ -4531,14 +4494,14 @@ snapshots:
'@types/web-bluetooth@0.0.21': {}
'@typescript-eslint/eslint-plugin@8.45.0(@typescript-eslint/parser@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
'@typescript-eslint/eslint-plugin@8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
dependencies:
'@eslint-community/regexpp': 4.12.1
'@typescript-eslint/parser': 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.45.0
'@typescript-eslint/type-utils': 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/utils': 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.45.0
'@typescript-eslint/parser': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.46.0
'@typescript-eslint/type-utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.46.0
eslint: 9.37.0(jiti@2.6.1)
graphemer: 1.4.0
ignore: 7.0.5
@@ -4548,27 +4511,18 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/parser@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
'@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
dependencies:
'@typescript-eslint/scope-manager': 8.45.0
'@typescript-eslint/types': 8.45.0
'@typescript-eslint/typescript-estree': 8.45.0(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.45.0
'@typescript-eslint/scope-manager': 8.46.0
'@typescript-eslint/types': 8.46.0
'@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.46.0
debug: 4.4.3
eslint: 9.37.0(jiti@2.6.1)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/project-service@8.45.0(typescript@5.9.3)':
dependencies:
'@typescript-eslint/tsconfig-utils': 8.46.0(typescript@5.9.3)
'@typescript-eslint/types': 8.46.0
debug: 4.4.3
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/project-service@8.46.0(typescript@5.9.3)':
dependencies:
'@typescript-eslint/tsconfig-utils': 8.46.0(typescript@5.9.3)
@@ -4578,29 +4532,20 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/scope-manager@8.45.0':
dependencies:
'@typescript-eslint/types': 8.45.0
'@typescript-eslint/visitor-keys': 8.45.0
'@typescript-eslint/scope-manager@8.46.0':
dependencies:
'@typescript-eslint/types': 8.46.0
'@typescript-eslint/visitor-keys': 8.46.0
'@typescript-eslint/tsconfig-utils@8.45.0(typescript@5.9.3)':
dependencies:
typescript: 5.9.3
'@typescript-eslint/tsconfig-utils@8.46.0(typescript@5.9.3)':
dependencies:
typescript: 5.9.3
'@typescript-eslint/type-utils@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
'@typescript-eslint/type-utils@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
dependencies:
'@typescript-eslint/types': 8.45.0
'@typescript-eslint/typescript-estree': 8.45.0(typescript@5.9.3)
'@typescript-eslint/utils': 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/types': 8.46.0
'@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3)
'@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
debug: 4.4.3
eslint: 9.37.0(jiti@2.6.1)
ts-api-utils: 2.1.0(typescript@5.9.3)
@@ -4608,26 +4553,8 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/types@8.45.0': {}
'@typescript-eslint/types@8.46.0': {}
'@typescript-eslint/typescript-estree@8.45.0(typescript@5.9.3)':
dependencies:
'@typescript-eslint/project-service': 8.45.0(typescript@5.9.3)
'@typescript-eslint/tsconfig-utils': 8.45.0(typescript@5.9.3)
'@typescript-eslint/types': 8.45.0
'@typescript-eslint/visitor-keys': 8.45.0
debug: 4.4.3
fast-glob: 3.3.3
is-glob: 4.0.3
minimatch: 9.0.5
semver: 7.7.3
ts-api-utils: 2.1.0(typescript@5.9.3)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/typescript-estree@8.46.0(typescript@5.9.3)':
dependencies:
'@typescript-eslint/project-service': 8.46.0(typescript@5.9.3)
@@ -4644,17 +4571,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/utils@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
dependencies:
'@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@2.6.1))
'@typescript-eslint/scope-manager': 8.45.0
'@typescript-eslint/types': 8.45.0
'@typescript-eslint/typescript-estree': 8.45.0(typescript@5.9.3)
eslint: 9.37.0(jiti@2.6.1)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/utils@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
dependencies:
'@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@2.6.1))
@@ -4666,11 +4582,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/visitor-keys@8.45.0':
dependencies:
'@typescript-eslint/types': 8.45.0
eslint-visitor-keys: 4.2.1
'@typescript-eslint/visitor-keys@8.46.0':
dependencies:
'@typescript-eslint/types': 8.46.0
@@ -4990,13 +4901,13 @@ snapshots:
transitivePeerDependencies:
- '@types/eslint'
'@vue/eslint-config-typescript@14.6.0(eslint-plugin-vue@10.5.0(@typescript-eslint/parser@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.37.0(jiti@2.6.1))))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
'@vue/eslint-config-typescript@14.6.0(eslint-plugin-vue@10.5.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.37.0(jiti@2.6.1))))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
dependencies:
'@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
eslint: 9.37.0(jiti@2.6.1)
eslint-plugin-vue: 10.5.0(@typescript-eslint/parser@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.37.0(jiti@2.6.1)))
eslint-plugin-vue: 10.5.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.37.0(jiti@2.6.1)))
fast-glob: 3.3.3
typescript-eslint: 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
typescript-eslint: 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
vue-eslint-parser: 10.2.0(eslint@9.37.0(jiti@2.6.1))
optionalDependencies:
typescript: 5.9.3
@@ -5152,7 +5063,7 @@ snapshots:
balanced-match@1.0.2: {}
baseline-browser-mapping@2.8.12: {}
baseline-browser-mapping@2.8.16: {}
binary-extensions@2.3.0: {}
@@ -5175,9 +5086,9 @@ snapshots:
browserslist@4.26.3:
dependencies:
baseline-browser-mapping: 2.8.12
caniuse-lite: 1.0.30001748
electron-to-chromium: 1.5.230
baseline-browser-mapping: 2.8.16
caniuse-lite: 1.0.30001749
electron-to-chromium: 1.5.234
node-releases: 2.0.23
update-browserslist-db: 1.1.3(browserslist@4.26.3)
@@ -5218,7 +5129,7 @@ snapshots:
pascal-case: 3.1.2
tslib: 2.8.1
caniuse-lite@1.0.30001748: {}
caniuse-lite@1.0.30001749: {}
chainsaw@0.0.9:
dependencies:
@@ -5481,7 +5392,7 @@ snapshots:
dependencies:
jake: 10.9.4
electron-to-chromium@1.5.230: {}
electron-to-chromium@1.5.234: {}
emoji-regex@8.0.0: {}
@@ -5623,7 +5534,7 @@ snapshots:
optionalDependencies:
eslint-config-prettier: 10.1.8(eslint@9.37.0(jiti@2.6.1))
eslint-plugin-vue@10.5.0(@typescript-eslint/parser@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.37.0(jiti@2.6.1))):
eslint-plugin-vue@10.5.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.37.0(jiti@2.6.1))):
dependencies:
'@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0(jiti@2.6.1))
eslint: 9.37.0(jiti@2.6.1)
@@ -5634,7 +5545,7 @@ snapshots:
vue-eslint-parser: 10.2.0(eslint@9.37.0(jiti@2.6.1))
xml-name-validator: 4.0.0
optionalDependencies:
'@typescript-eslint/parser': 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/parser': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
eslint-scope@8.4.0:
dependencies:
@@ -5868,7 +5779,7 @@ snapshots:
es-errors: 1.3.0
get-intrinsic: 1.3.0
get-tsconfig@4.10.1:
get-tsconfig@4.12.0:
dependencies:
resolve-pkg-maps: 1.0.0
@@ -6453,7 +6364,7 @@ snapshots:
package-json-from-dist@1.0.1: {}
package-manager-detector@1.3.0: {}
package-manager-detector@1.4.0: {}
param-case@3.0.4:
dependencies:
@@ -6902,7 +6813,7 @@ snapshots:
tsx@4.20.6:
dependencies:
esbuild: 0.25.10
get-tsconfig: 4.10.1
get-tsconfig: 4.12.0
optionalDependencies:
fsevents: 2.3.3
@@ -6954,12 +6865,12 @@ snapshots:
typed-array-buffer: 1.0.3
typed-array-byte-offset: 1.0.4
typescript-eslint@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3):
typescript-eslint@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3):
dependencies:
'@typescript-eslint/eslint-plugin': 8.45.0(@typescript-eslint/parser@8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/parser': 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/typescript-estree': 8.45.0(typescript@5.9.3)
'@typescript-eslint/utils': 8.45.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/eslint-plugin': 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/parser': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/typescript-estree': 8.46.0(typescript@5.9.3)
'@typescript-eslint/utils': 8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
eslint: 9.37.0(jiti@2.6.1)
typescript: 5.9.3
transitivePeerDependencies:

View File

@@ -2,6 +2,7 @@
defineOptions({
name: 'setting-index'
})
import { NButton } from 'naive-ui'
import { useGettext } from 'vue3-gettext'
@@ -27,6 +28,7 @@ const { data: model } = useRequest(setting.list, {
offline_mode: false,
two_fa: false,
lifetime: 0,
ip_header: '',
bind_domain: [],
bind_ip: [],
bind_ua: [],

View File

@@ -25,6 +25,12 @@ const model = defineModel<any>('model', { type: Object, required: true })
<n-form-item :label="$gettext('Access Entrance')">
<n-input v-model:value="model.entrance" :placeholder="$gettext('/admin')" />
</n-form-item>
<n-form-item :label="$gettext('Request IP Header')">
<n-input
v-model:value="model.ip_header"
:placeholder="$gettext('Customize the IP used by panel (useful when using CDN)')"
/>
</n-form-item>
<n-form-item :label="$gettext('Bind Domain')">
<n-dynamic-input
v-model:value="model.bind_domain"

View File

@@ -1,16 +0,0 @@
export interface Setting {
name: string
locale: string
username: string
password: string
email: string
port: number
entrance: string
offline_mode: boolean
auto_update: boolean
website_path: string
backup_path: string
https: boolean
cert: string
key: string
}