Initial commit

This commit is contained in:
2026-06-30 15:14:37 +08:00
commit 15dab96872
311 changed files with 95639 additions and 0 deletions
+172
View File
@@ -0,0 +1,172 @@
package config
import (
"crypto/rand"
"encoding/hex"
"fmt"
"os"
"path/filepath"
"github.com/google/uuid"
"github.com/spf13/viper"
)
// Config 全局配置结构
type Config struct {
App AppConfig `mapstructure:"app"`
Server ServerConfig `mapstructure:"server"`
Database DatabaseConfig `mapstructure:"database"`
JWT JWTConfig `mapstructure:"jwt"`
Log LogConfig `mapstructure:"log"`
Encryption EncryptionConfig `mapstructure:"encryption"`
WireGuard WireGuardConfig `mapstructure:"wireguard"`
STUN STUNConfig `mapstructure:"stun"`
TURN TURNConfig `mapstructure:"turn"`
}
// AppConfig 应用配置
type AppConfig struct {
Version string `mapstructure:"version"` // 版本号
BuildDate string `mapstructure:"build_date"` // 构建日期
}
// ServerConfig 服务器配置
type ServerConfig struct {
Port int `mapstructure:"port"`
Mode string `mapstructure:"mode"` // debug, release, test
StaticPath string `mapstructure:"static_path"` // 前端静态文件目录
}
// DatabaseConfig 数据库配置
type DatabaseConfig struct {
Type string `mapstructure:"type"`
Path string `mapstructure:"path"`
}
// JWTConfig JWT 配置
type JWTConfig struct {
Secret string `mapstructure:"secret"`
AccessTokenDur string `mapstructure:"access_token_duration"`
RefreshTokenDur string `mapstructure:"refresh_token_duration"`
}
// LogConfig 日志配置
type LogConfig struct {
Level string `mapstructure:"level"`
Format string `mapstructure:"format"`
Output string `mapstructure:"output"`
MaxSize int `mapstructure:"max_size"`
MaxBackups int `mapstructure:"max_backups"`
MaxAge int `mapstructure:"max_age"`
}
// EncryptionConfig 加密配置
type EncryptionConfig struct {
NetworkSecretKey string `mapstructure:"network_secret_key"`
}
// WireGuardConfig WireGuard 配置(固定使用用户态)
type WireGuardConfig struct {
// 已删除 PreferredMode 字段 - 统一使用 wireguard-go 用户态
}
// STUNConfig STUN 配置
type STUNConfig struct {
DefaultServers []string `mapstructure:"default_servers"` // 默认 STUN 服务器列表
SelectionStrategy string `mapstructure:"selection_strategy"` // 选择策略:auto, domestic, international, custom
AutoTest bool `mapstructure:"auto_test"` // 是否启用自动测试
TestInterval int `mapstructure:"test_interval"` // 测试间隔(秒)
Timeout int `mapstructure:"timeout"` // 超时时间(秒)
}
// TURNConfig TURN 配置
type TURNConfig struct {
DefaultServers []TURNServerConfig `mapstructure:"default_servers"` // 默认 TURN 服务器列表
}
// TURNServerConfig TURN 服务器配置
type TURNServerConfig struct {
URL string `mapstructure:"url"` // TURN 服务器 URL
Username string `mapstructure:"username"` // 用户名
Credential string `mapstructure:"credential"` // 凭证
AuthType string `mapstructure:"auth_type"` // 鉴权方式:credential, token, secret
}
// Load 加载配置文件
func Load(configPath string) (*Config, error) {
// 如果未指定配置文件路径,使用默认路径
if configPath == "" {
configPath = "config.yaml"
}
// 检查配置文件是否存在
if _, err := os.Stat(configPath); os.IsNotExist(err) {
// 尝试从示例文件复制
examplePath := "configs/config.example.yaml"
if _, err := os.Stat(examplePath); err == nil {
// 创建目录
dir := filepath.Dir(configPath)
if dir != "." {
os.MkdirAll(dir, 0755)
}
// 复制示例配置
data, _ := os.ReadFile(examplePath)
os.WriteFile(configPath, data, 0644)
}
}
// 读取配置文件
viper.SetConfigFile(configPath)
viper.AutomaticEnv()
if err := viper.ReadInConfig(); err != nil {
return nil, fmt.Errorf("读取配置文件失败:%w", err)
}
var config Config
if err := viper.Unmarshal(&config); err != nil {
return nil, fmt.Errorf("解析配置文件失败:%w", err)
}
// 自动填充默认值
if config.Server.Port == 0 {
config.Server.Port = 9531
}
if config.Server.Mode == "" {
config.Server.Mode = "release"
}
// 自动生成 JWT Secret
if config.JWT.Secret == "" {
config.JWT.Secret = generateJWTSecret()
}
// 自动生成加密密钥
if config.Encryption.NetworkSecretKey == "" {
config.Encryption.NetworkSecretKey = generateEncryptionKey()
}
return &config, nil
}
// generateJWTSecret 使用 crypto/rand 生成随机 JWT Secret
func generateJWTSecret() string {
b := make([]byte, 32)
_, err := rand.Read(b)
if err != nil {
// 极端情况回退(几乎不会发生)
return uuid.New().String()
}
return hex.EncodeToString(b)
}
// generateEncryptionKey 使用 crypto/rand 生成加密密钥
func generateEncryptionKey() string {
key := make([]byte, 32)
_, err := rand.Read(key)
if err != nil {
// 极端情况回退(几乎不会发生)
return uuid.New().String() + uuid.New().String()
}
return hex.EncodeToString(key)
}