mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-09-19 09:40:12 +00:00
feat: custom domain management, config and notification fixes, and VPS auto-renewal rollover
This commit is contained in:
+19
-18
@@ -35,14 +35,14 @@ const (
|
||||
)
|
||||
|
||||
type ConfigForGuests struct {
|
||||
Language string `koanf:"language" json:"language"` // 系统语言,默认 zh_CN
|
||||
SiteName string `koanf:"site_name" json:"site_name"`
|
||||
CustomCode string `koanf:"custom_code" json:"custom_code,omitempty"`
|
||||
CustomCodeDashboard string `koanf:"custom_code_dashboard" json:"custom_code_dashboard,omitempty"`
|
||||
CustomLogo string `koanf:"custom_logo" json:"custom_logo,omitempty"`
|
||||
CustomDescription string `koanf:"custom_description" json:"custom_description,omitempty"`
|
||||
CustomLinks string `koanf:"custom_links" json:"custom_links,omitempty"`
|
||||
BackgroundImageDay string `koanf:"background_image_day" json:"background_image_day,omitempty"`
|
||||
Language string `koanf:"language" json:"language"` // 系统语言,默认 zh_CN
|
||||
SiteName string `koanf:"site_name" json:"site_name"`
|
||||
CustomCode string `koanf:"custom_code" json:"custom_code,omitempty"`
|
||||
CustomCodeDashboard string `koanf:"custom_code_dashboard" json:"custom_code_dashboard,omitempty"`
|
||||
CustomLogo string `koanf:"custom_logo" json:"custom_logo,omitempty"`
|
||||
CustomDescription string `koanf:"custom_description" json:"custom_description,omitempty"`
|
||||
CustomLinks string `koanf:"custom_links" json:"custom_links,omitempty"`
|
||||
BackgroundImageDay string `koanf:"background_image_day" json:"background_image_day,omitempty"`
|
||||
BackgroundImageNight string `koanf:"background_image_night" json:"background_image_night,omitempty"`
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ type ConfigDashboard struct {
|
||||
UserTemplate string `koanf:"user_template" json:"user_template,omitempty"`
|
||||
AdminTemplate string `koanf:"admin_template" json:"admin_template,omitempty"`
|
||||
|
||||
EnablePlainIPInNotification bool `koanf:"enable_plain_ip_in_notification" json:"enable_plain_ip_in_notification,omitempty"` // 通知信息IP不打码
|
||||
EnablePlainIPInNotification bool `koanf:"enable_plain_ip_in_notification" json:"enable_plain_ip_in_notification,omitempty"` // 通知信息IP不打码
|
||||
|
||||
EnableMCP bool `koanf:"enable_mcp" json:"enable_mcp,omitempty"` // 是否启用 MCP 入口(默认关闭;启用前请审视 PAT scope/whitelist)
|
||||
|
||||
@@ -80,15 +80,15 @@ type ConfigDashboard struct {
|
||||
Cover uint8 `koanf:"cover" json:"cover"` // 覆盖范围(0:提醒未被 IgnoredIPNotification 包含的所有服务器; 1:仅提醒被 IgnoredIPNotification 包含的服务器;)
|
||||
IgnoredIPNotification string `koanf:"ignored_ip_notification" json:"ignored_ip_notification,omitempty"` // 特定服务器IP(多个服务器用逗号分隔)
|
||||
|
||||
DNSServers string `koanf:"dns_servers" json:"dns_servers,omitempty"`
|
||||
ExpiryNotificationGroupID uint64 `koanf:"expiry_notification_group_id" json:"expiry_notification_group_id,omitempty"`
|
||||
TelegramBotToken string `koanf:"telegram_bot_token" json:"telegram_bot_token,omitempty"`
|
||||
TelegramAdminChatID string `koanf:"telegram_admin_chat_id" json:"telegram_admin_chat_id,omitempty"`
|
||||
DNSServers string `koanf:"dns_servers" json:"dns_servers,omitempty"`
|
||||
ExpiryNotificationGroupID uint64 `koanf:"expiry_notification_group_id" json:"expiry_notification_group_id,omitempty"`
|
||||
TelegramBotToken string `koanf:"telegram_bot_token" json:"telegram_bot_token,omitempty"`
|
||||
TelegramAdminChatID string `koanf:"telegram_admin_chat_id" json:"telegram_admin_chat_id,omitempty"`
|
||||
|
||||
SMTPServer string `koanf:"smtp_server" json:"smtp_server,omitempty"`
|
||||
SMTPUser string `koanf:"smtp_user" json:"smtp_user,omitempty"`
|
||||
SMTPPassword string `koanf:"smtp_password" json:"smtp_password,omitempty"`
|
||||
AdminEmail string `koanf:"admin_email" json:"admin_email,omitempty"`
|
||||
SMTPServer string `koanf:"smtp_server" json:"smtp_server,omitempty"`
|
||||
SMTPUser string `koanf:"smtp_user" json:"smtp_user,omitempty"`
|
||||
SMTPPassword string `koanf:"smtp_password" json:"smtp_password,omitempty"`
|
||||
AdminEmail string `koanf:"admin_email" json:"admin_email,omitempty"`
|
||||
DomainExpiryNotificationDays string `koanf:"domain_expiry_notification_days" json:"domain_expiry_notification_days,omitempty"`
|
||||
ServerExpiryNotificationDays string `koanf:"server_expiry_notification_days" json:"server_expiry_notification_days,omitempty"`
|
||||
}
|
||||
@@ -397,8 +397,9 @@ func koanfConf(c any) koanf.UnmarshalConf {
|
||||
WeaklyTypedInput: true,
|
||||
MatchName: func(mapKey, fieldName string) bool {
|
||||
return strings.EqualFold(mapKey, fieldName) ||
|
||||
strings.EqualFold(mapKey, strings.ReplaceAll(fieldName, "_", ""))
|
||||
strings.EqualFold(strings.ReplaceAll(mapKey, "_", ""), strings.ReplaceAll(fieldName, "_", ""))
|
||||
},
|
||||
|
||||
Squash: true,
|
||||
},
|
||||
}
|
||||
|
||||
+27
-1
@@ -36,7 +36,23 @@ func TestReadConfig(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("ReadFile", func(t *testing.T) {
|
||||
const testCfg = "jwt_secret_key: test\nuser_template: um\nadmin_template: am\nagent_secret_key: none\nsite_name: lowkick"
|
||||
const testCfg = `
|
||||
jwt_secret_key: test
|
||||
user_template: um
|
||||
admin_template: am
|
||||
agent_secret_key: none
|
||||
site_name: lowkick
|
||||
telegram_bot_token: 8155880635:AAH_test
|
||||
telegram_admin_chat_id: "12345678"
|
||||
web_real_ip_header: nz-realip
|
||||
agent_real_ip_header: nz-realip
|
||||
domain_expiry_notification_days: 100, 30, 7, 1, 0
|
||||
server_expiry_notification_days: 30, 7, 3, 1, 0
|
||||
smtp_server: us1.workspace.org:465
|
||||
smtp_user: test@loohui.com
|
||||
smtp_password: password123
|
||||
admin_email: admin@loohui.com
|
||||
`
|
||||
|
||||
var testFrontendTemplates = []FrontendTemplate{
|
||||
{Path: "um"},
|
||||
@@ -59,6 +75,16 @@ func TestReadConfig(t *testing.T) {
|
||||
{"admin_template", c.AdminTemplate, c.AdminTemplate == "am"},
|
||||
{"agent_secret_key", c.AgentSecretKey, c.AgentSecretKey == "none"},
|
||||
{"site_name", c.SiteName, c.SiteName == "lowkick"},
|
||||
{"telegram_bot_token", c.TelegramBotToken, c.TelegramBotToken == "8155880635:AAH_test"},
|
||||
{"telegram_admin_chat_id", c.TelegramAdminChatID, c.TelegramAdminChatID == "12345678"},
|
||||
{"web_real_ip_header", c.WebRealIPHeader, c.WebRealIPHeader == "nz-realip"},
|
||||
{"agent_real_ip_header", c.AgentRealIPHeader, c.AgentRealIPHeader == "nz-realip"},
|
||||
{"domain_expiry_notification_days", c.DomainExpiryNotificationDays, c.DomainExpiryNotificationDays == "100, 30, 7, 1, 0"},
|
||||
{"server_expiry_notification_days", c.ServerExpiryNotificationDays, c.ServerExpiryNotificationDays == "30, 7, 3, 1, 0"},
|
||||
{"smtp_server", c.SMTPServer, c.SMTPServer == "us1.workspace.org:465"},
|
||||
{"smtp_user", c.SMTPUser, c.SMTPUser == "test@loohui.com"},
|
||||
{"smtp_password", c.SMTPPassword, c.SMTPPassword == "password123"},
|
||||
{"admin_email", c.AdminEmail, c.AdminEmail == "admin@loohui.com"},
|
||||
}
|
||||
|
||||
for _, field := range testFields {
|
||||
|
||||
@@ -143,7 +143,6 @@ func (ns *NotificationServerBundle) Send(message string) error {
|
||||
|
||||
verifyTLS := n.VerifyTLS != nil && *n.VerifyTLS
|
||||
|
||||
|
||||
reqBody, err := ns.reqBody(message)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -331,33 +330,6 @@ func (ns *NotificationServerBundle) replaceParamsInString(str string, message st
|
||||
)
|
||||
}
|
||||
|
||||
replacer := strings.NewReplacer(replacements...)
|
||||
return replacer.Replace(str)
|
||||
}
|
||||
|
||||
var ipv4, ipv6, validIP string
|
||||
if ns.Server.GeoIP != nil {
|
||||
ip := ns.Server.GeoIP.IP
|
||||
if ip.IPv4Addr != "" && ip.IPv6Addr != "" {
|
||||
ipv4 = ip.IPv4Addr
|
||||
ipv6 = ip.IPv6Addr
|
||||
validIP = ipv4
|
||||
} else if ip.IPv4Addr != "" {
|
||||
ipv4 = ip.IPv4Addr
|
||||
validIP = ipv4
|
||||
} else {
|
||||
ipv6 = ip.IPv6Addr
|
||||
validIP = ipv6
|
||||
}
|
||||
}
|
||||
|
||||
replacements = append(replacements,
|
||||
"#SERVER.IP#", mod(validIP),
|
||||
"#SERVER.IPV4#", mod(ipv4),
|
||||
"#SERVER.IPV6#", mod(ipv6),
|
||||
)
|
||||
}
|
||||
|
||||
replacer := strings.NewReplacer(replacements...)
|
||||
return replacer.Replace(str)
|
||||
}
|
||||
|
||||
+9
-10
@@ -10,7 +10,6 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/goccy/go-json"
|
||||
"gorm.io/datatypes"
|
||||
"gorm.io/gorm"
|
||||
|
||||
pb "github.com/nezhahq/nezha/proto"
|
||||
@@ -21,15 +20,15 @@ var runtimeHolderInitMu sync.Mutex
|
||||
type Server struct {
|
||||
Common
|
||||
|
||||
Name string `json:"name"`
|
||||
UUID string `json:"uuid,omitempty" gorm:"unique"`
|
||||
Note string `json:"note,omitempty"` // 管理员可见备注
|
||||
PublicNote string `json:"public_note,omitempty"` // 公开备注
|
||||
DisplayIndex int `json:"display_index"` // 展示排序,越大越靠前
|
||||
HideForGuest bool `json:"hide_for_guest,omitempty"` // 对游客隐藏
|
||||
EnableDDNS bool `json:"enable_ddns,omitempty"` // 启用DDNS
|
||||
BillingData datatypes.JSON `gorm:"type:json" json:"billing_data,omitempty"`
|
||||
DDNSProfilesRaw string `gorm:"default:'[]';column:ddns_profiles_raw" json:"-"`
|
||||
Name string `json:"name"`
|
||||
UUID string `json:"uuid,omitempty" gorm:"unique"`
|
||||
Note string `json:"note,omitempty"` // 管理员可见备注
|
||||
PublicNote string `json:"public_note,omitempty"` // 公开备注
|
||||
DisplayIndex int `json:"display_index"` // 展示排序,越大越靠前
|
||||
HideForGuest bool `json:"hide_for_guest,omitempty"` // 对游客隐藏
|
||||
EnableDDNS bool `json:"enable_ddns,omitempty"` // 启用DDNS
|
||||
DDNSProfilesRaw string `gorm:"default:'[]';column:ddns_profiles_raw" json:"-"`
|
||||
|
||||
OverrideDDNSDomainsRaw string `gorm:"default:'{}';column:override_ddns_domains_raw" json:"-"`
|
||||
|
||||
DDNSProfiles []uint64 `gorm:"-" json:"ddns_profiles,omitempty" validate:"optional"` // DDNS配置
|
||||
|
||||
@@ -21,13 +21,13 @@ type SettingForm struct {
|
||||
BackgroundImageDay string `json:"background_image_day,omitempty" validate:"optional"`
|
||||
BackgroundImageNight string `json:"background_image_night,omitempty" validate:"optional"`
|
||||
|
||||
AgentTLS bool `json:"tls,omitempty" validate:"optional"`
|
||||
EnableIPChangeNotification bool `json:"enable_ip_change_notification,omitempty" validate:"optional"`
|
||||
EnablePlainIPInNotification bool `json:"enable_plain_ip_in_notification,omitempty" validate:"optional"`
|
||||
EnableMCP *bool `json:"enable_mcp,omitempty" validate:"optional"`
|
||||
ExpiryNotificationGroupID uint64 `json:"expiry_notification_group_id,omitempty"`
|
||||
TelegramBotToken string `json:"telegram_bot_token,omitempty" validate:"optional"`
|
||||
TelegramAdminChatID string `json:"telegram_admin_chat_id,omitempty" validate:"optional"`
|
||||
AgentTLS bool `json:"tls,omitempty" validate:"optional"`
|
||||
EnableIPChangeNotification bool `json:"enable_ip_change_notification,omitempty" validate:"optional"`
|
||||
EnablePlainIPInNotification bool `json:"enable_plain_ip_in_notification,omitempty" validate:"optional"`
|
||||
EnableMCP *bool `json:"enable_mcp,omitempty" validate:"optional"`
|
||||
ExpiryNotificationGroupID uint64 `json:"expiry_notification_group_id,omitempty"`
|
||||
TelegramBotToken string `json:"telegram_bot_token,omitempty" validate:"optional"`
|
||||
TelegramAdminChatID string `json:"telegram_admin_chat_id,omitempty" validate:"optional"`
|
||||
|
||||
SMTPServer string `json:"smtp_server,omitempty" validate:"optional"`
|
||||
SMTPUser string `json:"smtp_user,omitempty" validate:"optional"`
|
||||
@@ -35,7 +35,6 @@ type SettingForm struct {
|
||||
AdminEmail string `json:"admin_email,omitempty" validate:"optional"`
|
||||
DomainExpiryNotificationDays string `json:"domain_expiry_notification_days,omitempty" validate:"optional"`
|
||||
ServerExpiryNotificationDays string `json:"server_expiry_notification_days,omitempty" validate:"optional"`
|
||||
|
||||
}
|
||||
|
||||
type Setting struct {
|
||||
|
||||
Reference in New Issue
Block a user