mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 08:19:15 +08:00
feat: 面板设置增加监听地址 (#2663)
This commit is contained in:
parent
b045261f16
commit
d638796798
@ -150,6 +150,49 @@ func (b *BaseApi) DownloadSSL(c *gin.Context) {
|
|||||||
c.File(pathItem)
|
c.File(pathItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags System Setting
|
||||||
|
// @Summary Load system address
|
||||||
|
// @Description 获取系统地址信息
|
||||||
|
// @Accept json
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /settings/interface [get]
|
||||||
|
func (b *BaseApi) LoadInterfaceAddr(c *gin.Context) {
|
||||||
|
data, err := settingService.LoadInterfaceAddr()
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags System Setting
|
||||||
|
// @Summary Update system bind info
|
||||||
|
// @Description 更新系统监听信息
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.BindInfo true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /settings/bind/update [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["ipv6", "bindAddress"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统监听信息 => ipv6: [ipv6], 监听 IP: [bindAddress]","formatEN":"update system bind info => ipv6: [ipv6], 监听 IP: [bindAddress]"}
|
||||||
|
func (b *BaseApi) UpdateBindInfo(c *gin.Context) {
|
||||||
|
var req dto.BindInfo
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := global.VALID.Struct(req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := settingService.UpdateBindInfo(req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, nil)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags System Setting
|
// @Tags System Setting
|
||||||
// @Summary Update system port
|
// @Summary Update system port
|
||||||
// @Description 更新系统端口
|
// @Description 更新系统端口
|
||||||
|
@ -14,6 +14,8 @@ type SettingInfo struct {
|
|||||||
NtpSite string `json:"ntpSite"`
|
NtpSite string `json:"ntpSite"`
|
||||||
|
|
||||||
Port string `json:"port"`
|
Port string `json:"port"`
|
||||||
|
Ipv6 string `json:"ipv6"`
|
||||||
|
BindAddress string `json:"bindAddress"`
|
||||||
PanelName string `json:"panelName"`
|
PanelName string `json:"panelName"`
|
||||||
Theme string `json:"theme"`
|
Theme string `json:"theme"`
|
||||||
Language string `json:"language"`
|
Language string `json:"language"`
|
||||||
@ -136,6 +138,11 @@ type SyncTime struct {
|
|||||||
NtpSite string `json:"ntpSite"`
|
NtpSite string `json:"ntpSite"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BindInfo struct {
|
||||||
|
Ipv6 string `json:"ipv6" validate:"required,oneof=enable disable"`
|
||||||
|
BindAddress string `json:"bindAddress" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
type Upgrade struct {
|
type Upgrade struct {
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -30,10 +31,12 @@ type SettingService struct{}
|
|||||||
|
|
||||||
type ISettingService interface {
|
type ISettingService interface {
|
||||||
GetSettingInfo() (*dto.SettingInfo, error)
|
GetSettingInfo() (*dto.SettingInfo, error)
|
||||||
|
LoadInterfaceAddr() ([]string, error)
|
||||||
LoadTimeZone() ([]string, error)
|
LoadTimeZone() ([]string, error)
|
||||||
Update(key, value string) error
|
Update(key, value string) error
|
||||||
UpdatePassword(c *gin.Context, old, new string) error
|
UpdatePassword(c *gin.Context, old, new string) error
|
||||||
UpdatePort(port uint) error
|
UpdatePort(port uint) error
|
||||||
|
UpdateBindInfo(req dto.BindInfo) error
|
||||||
UpdateSSL(c *gin.Context, req dto.SSLUpdate) error
|
UpdateSSL(c *gin.Context, req dto.SSLUpdate) error
|
||||||
LoadFromCert() (*dto.SSLInfo, error)
|
LoadFromCert() (*dto.SSLInfo, error)
|
||||||
HandlePasswordExpired(c *gin.Context, old, new string) error
|
HandlePasswordExpired(c *gin.Context, old, new string) error
|
||||||
@ -160,6 +163,41 @@ func (u *SettingService) SyncTime(req dto.SyncTime) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *SettingService) LoadInterfaceAddr() ([]string, error) {
|
||||||
|
addrMap := make(map[string]struct{})
|
||||||
|
addrs, err := net.InterfaceAddrs()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, addr := range addrs {
|
||||||
|
ipNet, ok := addr.(*net.IPNet)
|
||||||
|
if ok && ipNet.IP.To16() != nil {
|
||||||
|
addrMap[ipNet.IP.String()] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var data []string
|
||||||
|
for key := range addrMap {
|
||||||
|
data = append(data, key)
|
||||||
|
}
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *SettingService) UpdateBindInfo(req dto.BindInfo) error {
|
||||||
|
if err := settingRepo.Update("Ipv6", req.Ipv6); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := settingRepo.Update("BindAddress", req.BindAddress); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
_, err := cmd.Exec("systemctl restart 1panel.service")
|
||||||
|
if err != nil {
|
||||||
|
global.LOG.Errorf("restart system with new bind info failed, err: %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (u *SettingService) UpdatePort(port uint) error {
|
func (u *SettingService) UpdatePort(port uint) error {
|
||||||
if common.ScanPort(int(port)) {
|
if common.ScanPort(int(port)) {
|
||||||
return buserr.WithDetail(constant.ErrPortInUsed, port, nil)
|
return buserr.WithDetail(constant.ErrPortInUsed, port, nil)
|
||||||
|
@ -2,6 +2,8 @@ package configs
|
|||||||
|
|
||||||
type System struct {
|
type System struct {
|
||||||
Port string `mapstructure:"port"`
|
Port string `mapstructure:"port"`
|
||||||
|
Ipv6 string `mapstructure:"ipv6"`
|
||||||
|
BindAddress string `mapstructure:"bindAddress"`
|
||||||
SSL string `mapstructure:"ssl"`
|
SSL string `mapstructure:"ssl"`
|
||||||
DbFile string `mapstructure:"db_file"`
|
DbFile string `mapstructure:"db_file"`
|
||||||
DbPath string `mapstructure:"db_path"`
|
DbPath string `mapstructure:"db_path"`
|
||||||
|
@ -18,6 +18,16 @@ func Init() {
|
|||||||
global.LOG.Errorf("load service port from setting failed, err: %v", err)
|
global.LOG.Errorf("load service port from setting failed, err: %v", err)
|
||||||
}
|
}
|
||||||
global.CONF.System.Port = portSetting.Value
|
global.CONF.System.Port = portSetting.Value
|
||||||
|
ipv6Setting, err := settingRepo.Get(settingRepo.WithByKey("Ipv6"))
|
||||||
|
if err != nil {
|
||||||
|
global.LOG.Errorf("load ipv6 status from setting failed, err: %v", err)
|
||||||
|
}
|
||||||
|
global.CONF.System.Ipv6 = ipv6Setting.Value
|
||||||
|
bindAddressSetting, err := settingRepo.Get(settingRepo.WithByKey("BindAddress"))
|
||||||
|
if err != nil {
|
||||||
|
global.LOG.Errorf("load bind address from setting failed, err: %v", err)
|
||||||
|
}
|
||||||
|
global.CONF.System.BindAddress = bindAddressSetting.Value
|
||||||
sslSetting, err := settingRepo.Get(settingRepo.WithByKey("SSL"))
|
sslSetting, err := settingRepo.Get(settingRepo.WithByKey("SSL"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
global.LOG.Errorf("load service ssl from setting failed, err: %v", err)
|
global.LOG.Errorf("load service ssl from setting failed, err: %v", err)
|
||||||
|
@ -47,7 +47,9 @@ func Init() {
|
|||||||
migrations.AddDefaultNetwork,
|
migrations.AddDefaultNetwork,
|
||||||
migrations.UpdateRuntime,
|
migrations.UpdateRuntime,
|
||||||
migrations.UpdateTag,
|
migrations.UpdateTag,
|
||||||
|
|
||||||
migrations.AddFavorite,
|
migrations.AddFavorite,
|
||||||
|
migrations.AddBindAddress,
|
||||||
})
|
})
|
||||||
if err := m.Migrate(); err != nil {
|
if err := m.Migrate(); err != nil {
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
|
@ -15,3 +15,16 @@ var AddFavorite = &gormigrate.Migration{
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var AddBindAddress = &gormigrate.Migration{
|
||||||
|
ID: "20231024-add-bind-address",
|
||||||
|
Migrate: func(tx *gorm.DB) error {
|
||||||
|
if err := tx.Create(&model.Setting{Key: "BindAddress", Value: "0.0.0.0"}).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := tx.Create(&model.Setting{Key: "Ipv6", Value: "disable"}).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -22,6 +22,8 @@ func (s *SettingRouter) InitSettingRouter(Router *gin.RouterGroup) {
|
|||||||
router.POST("/expired/handle", baseApi.HandlePasswordExpired)
|
router.POST("/expired/handle", baseApi.HandlePasswordExpired)
|
||||||
settingRouter.GET("/search/available", baseApi.GetSystemAvailable)
|
settingRouter.GET("/search/available", baseApi.GetSystemAvailable)
|
||||||
settingRouter.POST("/update", baseApi.UpdateSetting)
|
settingRouter.POST("/update", baseApi.UpdateSetting)
|
||||||
|
settingRouter.GET("/interface", baseApi.LoadInterfaceAddr)
|
||||||
|
settingRouter.POST("/bind/update", baseApi.UpdateBindInfo)
|
||||||
settingRouter.POST("/port/update", baseApi.UpdatePort)
|
settingRouter.POST("/port/update", baseApi.UpdatePort)
|
||||||
settingRouter.POST("/ssl/update", baseApi.UpdateSSL)
|
settingRouter.POST("/ssl/update", baseApi.UpdateSSL)
|
||||||
settingRouter.GET("/ssl/info", baseApi.LoadFromCert)
|
settingRouter.GET("/ssl/info", baseApi.LoadFromCert)
|
||||||
|
@ -4,10 +4,10 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/init/app"
|
"github.com/1Panel-dev/1Panel/backend/init/app"
|
||||||
"github.com/1Panel-dev/1Panel/backend/init/business"
|
"github.com/1Panel-dev/1Panel/backend/init/business"
|
||||||
@ -26,7 +26,6 @@ import (
|
|||||||
"github.com/1Panel-dev/1Panel/backend/init/validator"
|
"github.com/1Panel-dev/1Panel/backend/init/validator"
|
||||||
"github.com/1Panel-dev/1Panel/backend/init/viper"
|
"github.com/1Panel-dev/1Panel/backend/init/viper"
|
||||||
|
|
||||||
"github.com/fvbock/endless"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -46,19 +45,17 @@ func Start() {
|
|||||||
hook.Init()
|
hook.Init()
|
||||||
|
|
||||||
rootRouter := router.Routers()
|
rootRouter := router.Routers()
|
||||||
address := fmt.Sprintf(":%s", global.CONF.System.Port)
|
|
||||||
s := endless.NewServer(address, rootRouter)
|
|
||||||
s.ReadHeaderTimeout = 20 * time.Second
|
|
||||||
s.WriteTimeout = 60 * time.Second
|
|
||||||
s.MaxHeaderBytes = 1 << 20
|
|
||||||
|
|
||||||
if global.CONF.System.SSL == "disable" {
|
tcpItem := "tcp4"
|
||||||
global.LOG.Infof("server run success on %s with http", global.CONF.System.Port)
|
if global.CONF.System.Ipv6 == "enable" {
|
||||||
if err := s.ListenAndServe(); err != nil {
|
tcpItem = "tcp"
|
||||||
global.LOG.Error(err)
|
global.CONF.System.BindAddress = fmt.Sprintf("[%s]", global.CONF.System.BindAddress)
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
} else {
|
server := &http.Server{
|
||||||
|
Addr: global.CONF.System.BindAddress + ":" + global.CONF.System.Port,
|
||||||
|
Handler: rootRouter,
|
||||||
|
}
|
||||||
|
if global.CONF.System.SSL == "enable" {
|
||||||
certificate, err := os.ReadFile(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt"))
|
certificate, err := os.ReadFile(path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -71,18 +68,19 @@ func Start() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
s := &http.Server{
|
server.TLSConfig = &tls.Config{
|
||||||
Addr: address,
|
|
||||||
Handler: rootRouter,
|
|
||||||
TLSConfig: &tls.Config{
|
|
||||||
Certificates: []tls.Certificate{cert},
|
Certificates: []tls.Certificate{cert},
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
global.LOG.Infof("server run success on %s with https", global.CONF.System.Port)
|
global.LOG.Infof("listen at %s:%s [%s]", global.CONF.System.BindAddress, global.CONF.System.Port, tcpItem)
|
||||||
if err := s.ListenAndServeTLS("", ""); err != nil {
|
ln, err := net.Listen(tcpItem, global.CONF.System.BindAddress+":"+global.CONF.System.Port)
|
||||||
global.LOG.Error(err)
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
type tcpKeepAliveListener struct {
|
||||||
|
*net.TCPListener
|
||||||
|
}
|
||||||
|
if err := server.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)}); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Package docs GENERATED BY SWAG; DO NOT EDIT
|
// Code generated by swaggo/swag. DO NOT EDIT.
|
||||||
// This file was generated by swaggo/swag
|
|
||||||
package docs
|
package docs
|
||||||
|
|
||||||
import "github.com/swaggo/swag"
|
import "github.com/swaggo/swag"
|
||||||
@ -8931,6 +8931,49 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/settings/bind/update": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "更新系统监听信息",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"System Setting"
|
||||||
|
],
|
||||||
|
"summary": "Update system bind info",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.BindInfo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFunctions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"ipv6",
|
||||||
|
"bindAddress"
|
||||||
|
],
|
||||||
|
"formatEN": "update system bind info =\u003e ipv6: [ipv6], 监听 IP: [bindAddress]",
|
||||||
|
"formatZH": "修改系统监听信息 =\u003e ipv6: [ipv6], 监听 IP: [bindAddress]",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/settings/clean": {
|
"/settings/clean": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@ -9014,6 +9057,28 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/settings/interface": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "获取系统地址信息",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"System Setting"
|
||||||
|
],
|
||||||
|
"summary": "Load system address",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/settings/mfa": {
|
"/settings/mfa": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@ -12501,6 +12566,25 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.BindInfo": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"bindAddress",
|
||||||
|
"ipv6"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"bindAddress": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"enable",
|
||||||
|
"disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.CaptchaResponse": {
|
"dto.CaptchaResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -15379,6 +15463,9 @@ const docTemplate = `{
|
|||||||
"appStoreVersion": {
|
"appStoreVersion": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"bindAddress": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"bindDomain": {
|
"bindDomain": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -15403,6 +15490,9 @@ const docTemplate = `{
|
|||||||
"expirationTime": {
|
"expirationTime": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"language": {
|
"language": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
@ -8924,6 +8924,49 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/settings/bind/update": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "更新系统监听信息",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"System Setting"
|
||||||
|
],
|
||||||
|
"summary": "Update system bind info",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.BindInfo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFunctions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"ipv6",
|
||||||
|
"bindAddress"
|
||||||
|
],
|
||||||
|
"formatEN": "update system bind info =\u003e ipv6: [ipv6], 监听 IP: [bindAddress]",
|
||||||
|
"formatZH": "修改系统监听信息 =\u003e ipv6: [ipv6], 监听 IP: [bindAddress]",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/settings/clean": {
|
"/settings/clean": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@ -9007,6 +9050,28 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/settings/interface": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "获取系统地址信息",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"System Setting"
|
||||||
|
],
|
||||||
|
"summary": "Load system address",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/settings/mfa": {
|
"/settings/mfa": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@ -12494,6 +12559,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dto.BindInfo": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"bindAddress",
|
||||||
|
"ipv6"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"bindAddress": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"enable",
|
||||||
|
"disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"dto.CaptchaResponse": {
|
"dto.CaptchaResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -15372,6 +15456,9 @@
|
|||||||
"appStoreVersion": {
|
"appStoreVersion": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"bindAddress": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"bindDomain": {
|
"bindDomain": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -15396,6 +15483,9 @@
|
|||||||
"expirationTime": {
|
"expirationTime": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"ipv6": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"language": {
|
"language": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
@ -122,6 +122,19 @@ definitions:
|
|||||||
required:
|
required:
|
||||||
- type
|
- type
|
||||||
type: object
|
type: object
|
||||||
|
dto.BindInfo:
|
||||||
|
properties:
|
||||||
|
bindAddress:
|
||||||
|
type: string
|
||||||
|
ipv6:
|
||||||
|
enum:
|
||||||
|
- enable
|
||||||
|
- disable
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- bindAddress
|
||||||
|
- ipv6
|
||||||
|
type: object
|
||||||
dto.CaptchaResponse:
|
dto.CaptchaResponse:
|
||||||
properties:
|
properties:
|
||||||
captchaID:
|
captchaID:
|
||||||
@ -2064,6 +2077,8 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
appStoreVersion:
|
appStoreVersion:
|
||||||
type: string
|
type: string
|
||||||
|
bindAddress:
|
||||||
|
type: string
|
||||||
bindDomain:
|
bindDomain:
|
||||||
type: string
|
type: string
|
||||||
complexityVerification:
|
complexityVerification:
|
||||||
@ -2080,6 +2095,8 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
expirationTime:
|
expirationTime:
|
||||||
type: string
|
type: string
|
||||||
|
ipv6:
|
||||||
|
type: string
|
||||||
language:
|
language:
|
||||||
type: string
|
type: string
|
||||||
lastCleanData:
|
lastCleanData:
|
||||||
@ -9879,6 +9896,34 @@ paths:
|
|||||||
summary: Load local backup dir
|
summary: Load local backup dir
|
||||||
tags:
|
tags:
|
||||||
- System Setting
|
- System Setting
|
||||||
|
/settings/bind/update:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 更新系统监听信息
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/dto.BindInfo'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Update system bind info
|
||||||
|
tags:
|
||||||
|
- System Setting
|
||||||
|
x-panel-log:
|
||||||
|
BeforeFunctions: []
|
||||||
|
bodyKeys:
|
||||||
|
- ipv6
|
||||||
|
- bindAddress
|
||||||
|
formatEN: 'update system bind info => ipv6: [ipv6], 监听 IP: [bindAddress]'
|
||||||
|
formatZH: '修改系统监听信息 => ipv6: [ipv6], 监听 IP: [bindAddress]'
|
||||||
|
paramKeys: []
|
||||||
/settings/clean:
|
/settings/clean:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
@ -9933,6 +9978,19 @@ paths:
|
|||||||
formatEN: reset an expired Password
|
formatEN: reset an expired Password
|
||||||
formatZH: 重置过期密码
|
formatZH: 重置过期密码
|
||||||
paramKeys: []
|
paramKeys: []
|
||||||
|
/settings/interface:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 获取系统地址信息
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Load system address
|
||||||
|
tags:
|
||||||
|
- System Setting
|
||||||
/settings/mfa:
|
/settings/mfa:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
|
@ -22,6 +22,8 @@ export namespace Setting {
|
|||||||
lastCleanData: string;
|
lastCleanData: string;
|
||||||
|
|
||||||
serverPort: number;
|
serverPort: number;
|
||||||
|
ipv6: string;
|
||||||
|
bindAddress: string;
|
||||||
ssl: string;
|
ssl: string;
|
||||||
sslType: string;
|
sslType: string;
|
||||||
allowIPs: string;
|
allowIPs: string;
|
||||||
|
@ -21,6 +21,14 @@ export const updatePassword = (param: Setting.PasswordUpdate) => {
|
|||||||
return http.post(`/settings/password/update`, param);
|
return http.post(`/settings/password/update`, param);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const loadInterfaceAddr = () => {
|
||||||
|
return http.get(`/settings/interface`);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateBindInfo = (ipv6: string, bindAddress: string) => {
|
||||||
|
return http.post(`/settings/bind/update`, { ipv6: ipv6, bindAddress: bindAddress });
|
||||||
|
};
|
||||||
|
|
||||||
export const updatePort = (param: Setting.PortUpdate) => {
|
export const updatePort = (param: Setting.PortUpdate) => {
|
||||||
return http.post(`/settings/port/update`, param);
|
return http.post(`/settings/port/update`, param);
|
||||||
};
|
};
|
||||||
|
@ -22,6 +22,33 @@ const checkIp = (rule: any, value: any, callback: any) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const checkIpV6 = (rule: any, value: any, callback: any) => {
|
||||||
|
if (value === '' || typeof value === 'undefined' || value == null) {
|
||||||
|
callback(new Error(i18n.global.t('commons.rule.requiredInput')));
|
||||||
|
} else {
|
||||||
|
const IPv4SegmentFormat = '(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
|
||||||
|
const IPv4AddressFormat = `(${IPv4SegmentFormat}[.]){3}${IPv4SegmentFormat}`;
|
||||||
|
const IPv6SegmentFormat = '(?:[0-9a-fA-F]{1,4})';
|
||||||
|
const IPv6AddressRegExp = new RegExp(
|
||||||
|
'^(' +
|
||||||
|
`(?:${IPv6SegmentFormat}:){7}(?:${IPv6SegmentFormat}|:)|` +
|
||||||
|
`(?:${IPv6SegmentFormat}:){6}(?:${IPv4AddressFormat}|:${IPv6SegmentFormat}|:)|` +
|
||||||
|
`(?:${IPv6SegmentFormat}:){5}(?::${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,2}|:)|` +
|
||||||
|
`(?:${IPv6SegmentFormat}:){4}(?:(:${IPv6SegmentFormat}){0,1}:${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,3}|:)|` +
|
||||||
|
`(?:${IPv6SegmentFormat}:){3}(?:(:${IPv6SegmentFormat}){0,2}:${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,4}|:)|` +
|
||||||
|
`(?:${IPv6SegmentFormat}:){2}(?:(:${IPv6SegmentFormat}){0,3}:${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,5}|:)|` +
|
||||||
|
`(?:${IPv6SegmentFormat}:){1}(?:(:${IPv6SegmentFormat}){0,4}:${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,6}|:)|` +
|
||||||
|
`(?::((?::${IPv6SegmentFormat}){0,5}:${IPv4AddressFormat}|(?::${IPv6SegmentFormat}){1,7}|:))` +
|
||||||
|
')(%[0-9a-zA-Z-.:]{1,})?$',
|
||||||
|
);
|
||||||
|
if (!IPv6AddressRegExp.test(value) && value !== '') {
|
||||||
|
callback(new Error(i18n.global.t('commons.rule.ip')));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const checkIpV4V6OrDomain = (rule: any, value: any, callback: any) => {
|
const checkIpV4V6OrDomain = (rule: any, value: any, callback: any) => {
|
||||||
if (value === '' || typeof value === 'undefined' || value == null) {
|
if (value === '' || typeof value === 'undefined' || value == null) {
|
||||||
callback(new Error(i18n.global.t('commons.rule.requiredInput')));
|
callback(new Error(i18n.global.t('commons.rule.requiredInput')));
|
||||||
@ -453,6 +480,7 @@ interface CommonRule {
|
|||||||
integerNumberWith0: FormItemRule;
|
integerNumberWith0: FormItemRule;
|
||||||
floatNumber: FormItemRule;
|
floatNumber: FormItemRule;
|
||||||
ip: FormItemRule;
|
ip: FormItemRule;
|
||||||
|
ipV6: FormItemRule;
|
||||||
ipV4V6OrDomain: FormItemRule;
|
ipV4V6OrDomain: FormItemRule;
|
||||||
host: FormItemRule;
|
host: FormItemRule;
|
||||||
illegal: FormItemRule;
|
illegal: FormItemRule;
|
||||||
@ -576,6 +604,11 @@ export const Rules: CommonRule = {
|
|||||||
required: true,
|
required: true,
|
||||||
trigger: 'blur',
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
|
ipV6: {
|
||||||
|
validator: checkIpV6,
|
||||||
|
required: true,
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
ipV4V6OrDomain: {
|
ipV4V6OrDomain: {
|
||||||
validator: checkIpV4V6OrDomain,
|
validator: checkIpV4V6OrDomain,
|
||||||
required: true,
|
required: true,
|
||||||
|
@ -1125,6 +1125,12 @@ const message = {
|
|||||||
path: 'Path',
|
path: 'Path',
|
||||||
|
|
||||||
safe: 'Security',
|
safe: 'Security',
|
||||||
|
bindInfo: 'BindInfo',
|
||||||
|
bindAll: 'Listen All',
|
||||||
|
bindInfoHelper:
|
||||||
|
'Changing the service listening address or protocol may result in service unavailability. Do you want to continue?',
|
||||||
|
ipv6: 'Listen IPv6',
|
||||||
|
bindAddress: 'Listen Address',
|
||||||
entrance: 'Entrance',
|
entrance: 'Entrance',
|
||||||
showEntrance: 'Enable Home Page Notification Not Enabled',
|
showEntrance: 'Enable Home Page Notification Not Enabled',
|
||||||
entranceHelper: 'Enabling secure entry will only allow logging in to the panel through specified secure entry.',
|
entranceHelper: 'Enabling secure entry will only allow logging in to the panel through specified secure entry.',
|
||||||
|
@ -1119,6 +1119,11 @@ const message = {
|
|||||||
hasNewVersion: '有新版本',
|
hasNewVersion: '有新版本',
|
||||||
|
|
||||||
safe: '安全',
|
safe: '安全',
|
||||||
|
bindInfo: '監聽地址',
|
||||||
|
bindAll: '監聽所有',
|
||||||
|
bindInfoHelper: '修改服務監聽地址或協議可能導致服務不可用,是否繼續?',
|
||||||
|
ipv6: '監聽 IPv6',
|
||||||
|
bindAddress: '監聽地址',
|
||||||
entrance: '安全入口',
|
entrance: '安全入口',
|
||||||
showEntrance: '啟用概覽頁未開啟提醒',
|
showEntrance: '啟用概覽頁未開啟提醒',
|
||||||
entranceHelper: '開啟安全入口後只能通過指定安全入口登錄面板',
|
entranceHelper: '開啟安全入口後只能通過指定安全入口登錄面板',
|
||||||
|
@ -1120,6 +1120,11 @@ const message = {
|
|||||||
hasNewVersion: '有新版本',
|
hasNewVersion: '有新版本',
|
||||||
|
|
||||||
safe: '安全',
|
safe: '安全',
|
||||||
|
bindInfo: '监听地址',
|
||||||
|
bindAll: '监听所有',
|
||||||
|
bindInfoHelper: '修改服务监听地址或协议可能导致服务不可用,是否继续?',
|
||||||
|
ipv6: '监听 IPv6',
|
||||||
|
bindAddress: '监听地址',
|
||||||
entrance: '安全入口',
|
entrance: '安全入口',
|
||||||
showEntrance: '启用概览页未开启提醒',
|
showEntrance: '启用概览页未开启提醒',
|
||||||
entranceHelper: '开启安全入口后只能通过指定安全入口登录面板',
|
entranceHelper: '开启安全入口后只能通过指定安全入口登录面板',
|
||||||
|
136
frontend/src/views/setting/safe/bind/index.vue
Normal file
136
frontend/src/views/setting/safe/bind/index.vue
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-drawer v-model="drawerVisible" :destroy-on-close="true" :close-on-click-modal="false" size="30%">
|
||||||
|
<template #header>
|
||||||
|
<DrawerHeader :header="$t('setting.bindInfo')" :back="handleClose" />
|
||||||
|
</template>
|
||||||
|
<el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading">
|
||||||
|
<el-row type="flex" justify="center">
|
||||||
|
<el-col :span="22">
|
||||||
|
<el-form-item :label="$t('setting.ipv6')" prop="ipv6" :rules="Rules.requiredSelect">
|
||||||
|
<el-radio-group style="width: 100%" v-model="form.ipv6" @change="onChangeMode()">
|
||||||
|
<el-radio label="enable">{{ $t('commons.button.enable') }}</el-radio>
|
||||||
|
<el-radio label="disable">{{ $t('commons.button.disable') }}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
v-if="form.ipv6 === 'disable'"
|
||||||
|
:label="$t('setting.bindAddress')"
|
||||||
|
prop="bindAddress"
|
||||||
|
:rules="Rules.ip"
|
||||||
|
>
|
||||||
|
<el-checkbox v-model="form.input" :label="$t('container.input')" />
|
||||||
|
<el-select v-if="!form.input" clearable v-model="form.bindAddress">
|
||||||
|
<el-option value="0.0.0.0" :label="$t('setting.bindAll') + ' (0.0.0.0)'"></el-option>
|
||||||
|
<div v-for="item in interfaceOptions" :key="item">
|
||||||
|
<el-option v-if="item.indexOf(':') === -1" :value="item" :label="item" />
|
||||||
|
</div>
|
||||||
|
</el-select>
|
||||||
|
<el-input v-else clearable v-model="form.bindAddress"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-else :label="$t('setting.bindAddress')" prop="bindAddress" :rules="Rules.ipV6">
|
||||||
|
<el-checkbox v-model="form.input" :label="$t('container.input')" />
|
||||||
|
<el-select v-if="!form.input" clearable v-model="form.bindAddress">
|
||||||
|
<el-option value="::" :label="$t('setting.bindAll') + ' (::)'"></el-option>
|
||||||
|
<div v-for="item in interfaceOptions" :key="item">
|
||||||
|
<el-option v-if="item.indexOf(':') !== -1" :value="item" :label="item" />
|
||||||
|
</div>
|
||||||
|
</el-select>
|
||||||
|
<el-input v-else clearable v-model="form.bindAddress"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="drawerVisible = false">{{ $t('commons.button.cancel') }}</el-button>
|
||||||
|
<el-button :disabled="loading" type="primary" @click="onSavePort(formRef)">
|
||||||
|
{{ $t('commons.button.confirm') }}
|
||||||
|
</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-drawer>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { reactive, ref } from 'vue';
|
||||||
|
import i18n from '@/lang';
|
||||||
|
import { MsgSuccess } from '@/utils/message';
|
||||||
|
import { updateBindInfo, loadInterfaceAddr } from '@/api/modules/setting';
|
||||||
|
import { ElMessageBox, FormInstance } from 'element-plus';
|
||||||
|
import { Rules } from '@/global/form-rules';
|
||||||
|
import { GlobalStore } from '@/store';
|
||||||
|
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||||
|
const globalStore = GlobalStore();
|
||||||
|
|
||||||
|
interface DialogProps {
|
||||||
|
ipv6: string;
|
||||||
|
bindAddress: string;
|
||||||
|
}
|
||||||
|
const drawerVisible = ref();
|
||||||
|
const loading = ref();
|
||||||
|
const interfaceOptions = ref();
|
||||||
|
|
||||||
|
const form = reactive({
|
||||||
|
ipv6: '',
|
||||||
|
bindAddress: '',
|
||||||
|
input: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const formRef = ref<FormInstance>();
|
||||||
|
|
||||||
|
const acceptParams = (params: DialogProps): void => {
|
||||||
|
form.ipv6 = params.ipv6;
|
||||||
|
form.bindAddress = params.bindAddress;
|
||||||
|
loadInterface();
|
||||||
|
drawerVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadInterface = async () => {
|
||||||
|
const res = await loadInterfaceAddr();
|
||||||
|
interfaceOptions.value = res.data || [];
|
||||||
|
};
|
||||||
|
|
||||||
|
const onChangeMode = () => {
|
||||||
|
form.bindAddress = form.ipv6 === 'enable' ? '::' : '0.0.0.0';
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSavePort = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.validate(async (valid) => {
|
||||||
|
if (!valid) return;
|
||||||
|
ElMessageBox.confirm(i18n.global.t('setting.bindInfoHelper'), i18n.global.t('setting.bindInfo'), {
|
||||||
|
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||||
|
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||||
|
type: 'info',
|
||||||
|
}).then(async () => {
|
||||||
|
loading.value = true;
|
||||||
|
await updateBindInfo(form.ipv6, form.bindAddress)
|
||||||
|
.then(() => {
|
||||||
|
loading.value = false;
|
||||||
|
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||||
|
globalStore.isLogin = false;
|
||||||
|
let href = window.location.href;
|
||||||
|
let address = '';
|
||||||
|
if (globalStore.entrance) {
|
||||||
|
address = href.replaceAll('settings/safe', globalStore.entrance);
|
||||||
|
} else {
|
||||||
|
address = href.replaceAll('settings/safe', 'login');
|
||||||
|
}
|
||||||
|
window.open(address, '_self');
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
drawerVisible.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
acceptParams,
|
||||||
|
});
|
||||||
|
</script>
|
@ -15,7 +15,15 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t('setting.bindInfo')" prop="bindAddress">
|
||||||
|
<el-input disabled v-model="form.bindAddressItem">
|
||||||
|
<template #append>
|
||||||
|
<el-button @click="onChangeBind" icon="Setting">
|
||||||
|
{{ $t('commons.button.set') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item :label="$t('setting.entrance')">
|
<el-form-item :label="$t('setting.entrance')">
|
||||||
<el-input
|
<el-input
|
||||||
type="password"
|
type="password"
|
||||||
@ -148,10 +156,11 @@
|
|||||||
</LayoutContent>
|
</LayoutContent>
|
||||||
|
|
||||||
<PortSetting ref="portRef" />
|
<PortSetting ref="portRef" />
|
||||||
|
<BindSetting ref="bindRef" />
|
||||||
<MfaSetting ref="mfaRef" @search="search" />
|
<MfaSetting ref="mfaRef" @search="search" />
|
||||||
<SSLSetting ref="sslRef" @search="search" />
|
<SSLSetting ref="sslRef" @search="search" />
|
||||||
<EntranceSetting ref="entranceRef" @search="search" />
|
<EntranceSetting ref="entranceRef" @search="search" />
|
||||||
<TimeoutSetting ref="timeoutref" @search="search" />
|
<TimeoutSetting ref="timeoutRef" @search="search" />
|
||||||
<DomainSetting ref="domainRef" @search="search" />
|
<DomainSetting ref="domainRef" @search="search" />
|
||||||
<AllowIPsSetting ref="allowIPsRef" @search="search" />
|
<AllowIPsSetting ref="allowIPsRef" @search="search" />
|
||||||
</div>
|
</div>
|
||||||
@ -161,6 +170,7 @@
|
|||||||
import { ref, reactive, onMounted } from 'vue';
|
import { ref, reactive, onMounted } from 'vue';
|
||||||
import { ElForm, ElMessageBox } from 'element-plus';
|
import { ElForm, ElMessageBox } from 'element-plus';
|
||||||
import PortSetting from '@/views/setting/safe/port/index.vue';
|
import PortSetting from '@/views/setting/safe/port/index.vue';
|
||||||
|
import BindSetting from '@/views/setting/safe/bind/index.vue';
|
||||||
import SSLSetting from '@/views/setting/safe/ssl/index.vue';
|
import SSLSetting from '@/views/setting/safe/ssl/index.vue';
|
||||||
import MfaSetting from '@/views/setting/safe/mfa/index.vue';
|
import MfaSetting from '@/views/setting/safe/mfa/index.vue';
|
||||||
import TimeoutSetting from '@/views/setting/safe/timeout/index.vue';
|
import TimeoutSetting from '@/views/setting/safe/timeout/index.vue';
|
||||||
@ -177,7 +187,8 @@ const globalStore = GlobalStore();
|
|||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const entranceRef = ref();
|
const entranceRef = ref();
|
||||||
const portRef = ref();
|
const portRef = ref();
|
||||||
const timeoutref = ref();
|
const bindRef = ref();
|
||||||
|
const timeoutRef = ref();
|
||||||
const mfaRef = ref();
|
const mfaRef = ref();
|
||||||
|
|
||||||
const sslRef = ref();
|
const sslRef = ref();
|
||||||
@ -187,6 +198,9 @@ const allowIPsRef = ref();
|
|||||||
|
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
serverPort: 9999,
|
serverPort: 9999,
|
||||||
|
ipv6: 'disable',
|
||||||
|
bindAddress: '',
|
||||||
|
bindAddressItem: '',
|
||||||
ssl: 'disable',
|
ssl: 'disable',
|
||||||
sslType: 'self',
|
sslType: 'self',
|
||||||
securityEntrance: '',
|
securityEntrance: '',
|
||||||
@ -204,6 +218,10 @@ const unset = ref(i18n.global.t('setting.unSetting'));
|
|||||||
const search = async () => {
|
const search = async () => {
|
||||||
const res = await getSettingInfo();
|
const res = await getSettingInfo();
|
||||||
form.serverPort = Number(res.data.serverPort);
|
form.serverPort = Number(res.data.serverPort);
|
||||||
|
form.ipv6 = res.data.ipv6;
|
||||||
|
form.bindAddress = res.data.bindAddress;
|
||||||
|
let proto = form.ipv6 === 'enable' ? 'ipv6' : 'ipv4';
|
||||||
|
form.bindAddressItem = ' [' + proto + '] ' + res.data.bindAddress;
|
||||||
form.ssl = res.data.ssl;
|
form.ssl = res.data.ssl;
|
||||||
form.sslType = res.data.sslType;
|
form.sslType = res.data.sslType;
|
||||||
if (form.ssl === 'enable') {
|
if (form.ssl === 'enable') {
|
||||||
@ -259,6 +277,9 @@ const onChangeEntrance = () => {
|
|||||||
const onChangePort = () => {
|
const onChangePort = () => {
|
||||||
portRef.value.acceptParams({ serverPort: form.serverPort });
|
portRef.value.acceptParams({ serverPort: form.serverPort });
|
||||||
};
|
};
|
||||||
|
const onChangeBind = () => {
|
||||||
|
bindRef.value.acceptParams({ ipv6: form.ipv6, bindAddress: form.bindAddress });
|
||||||
|
};
|
||||||
const onChangeBindDomain = () => {
|
const onChangeBindDomain = () => {
|
||||||
domainRef.value.acceptParams({ bindDomain: form.bindDomain });
|
domainRef.value.acceptParams({ bindDomain: form.bindDomain });
|
||||||
};
|
};
|
||||||
@ -305,7 +326,7 @@ const loadInfo = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onChangeExpirationTime = async () => {
|
const onChangeExpirationTime = async () => {
|
||||||
timeoutref.value.acceptParams({ expirationDays: form.expirationDays });
|
timeoutRef.value.acceptParams({ expirationDays: form.expirationDays });
|
||||||
};
|
};
|
||||||
|
|
||||||
function loadTimeOut() {
|
function loadTimeOut() {
|
||||||
|
1
go.mod
1
go.mod
@ -12,7 +12,6 @@ require (
|
|||||||
github.com/docker/docker v23.0.3+incompatible
|
github.com/docker/docker v23.0.3+incompatible
|
||||||
github.com/docker/go-connections v0.4.0
|
github.com/docker/go-connections v0.4.0
|
||||||
github.com/fsnotify/fsnotify v1.6.0
|
github.com/fsnotify/fsnotify v1.6.0
|
||||||
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6
|
|
||||||
github.com/gin-contrib/gzip v0.0.6
|
github.com/gin-contrib/gzip v0.0.6
|
||||||
github.com/gin-contrib/i18n v0.0.1
|
github.com/gin-contrib/i18n v0.0.1
|
||||||
github.com/gin-gonic/gin v1.9.1
|
github.com/gin-gonic/gin v1.9.1
|
||||||
|
2
go.sum
2
go.sum
@ -228,8 +228,6 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
|
|||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||||
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 h1:6VSn3hB5U5GeA6kQw4TwWIWbOhtvR2hmbBJnTOtqTWc=
|
|
||||||
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6/go.mod h1:YxOVT5+yHzKvwhsiSIWmbAYM3Dr9AEEbER2dVayfBkg=
|
|
||||||
github.com/fvbommel/sortorder v1.0.2 h1:mV4o8B2hKboCdkJm+a7uX/SIpZob4JzUpc5GGnM45eo=
|
github.com/fvbommel/sortorder v1.0.2 h1:mV4o8B2hKboCdkJm+a7uX/SIpZob4JzUpc5GGnM45eo=
|
||||||
github.com/fvbommel/sortorder v1.0.2/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
github.com/fvbommel/sortorder v1.0.2/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||||
|
Loading…
x
Reference in New Issue
Block a user