feat: 后端限速实现 + 前端i18n全面国际化 + 安全与代码质量修复
后端: - trafficmgr: 实现 tc htb 限速(ApplyRateLimit/RemoveRateLimit),自动推导接口名 - 各协议服务: 代码质量改进与错误处理增强 前端: - protocols.js: 170个硬编码中文字符串全部转为 i18n key,中英文双语翻译 - 提取 fmtBytes() 到 utils/format.js 公共模块(消除 4 处重复) - router.js: 添加路由级权限守卫,非管理员无法直接 URL 访问管理页 - Tunnels.vue: SSE 日志流改用 fetch+ReadableStream,token 放 Authorization header - VPNUsers.vue: 修复 catch 块中文硬编码 fallback - 新增 TaskProgress 组件、taskmgr 后端任务管理
This commit is contained in:
1 parent
021d012478
commit
91974fc30f
26 files changed
+1977
-377
No files matched your search
@@ -31,10 +31,7 @@ func (s *Service) Available() (bool, string) {
|
||||
}
|
||||
|
||||
func (s *Service) Validate(cfg map[string]interface{}) (map[string]interface{}, error) {
|
||||
out := map[string]interface{}{}
|
||||
for k, v := range cfg {
|
||||
out[k] = v
|
||||
}
|
||||
out := service.CloneConfig(cfg)
|
||||
if service.Str(out, "ip_range") == "" {
|
||||
out["ip_range"] = "10.9.0.100-10.9.0.200"
|
||||
}
|
||||
@@ -42,7 +39,7 @@ func (s *Service) Validate(cfg map[string]interface{}) (map[string]interface{},
|
||||
out["local_ip"] = "10.9.0.1"
|
||||
}
|
||||
if service.Str(out, "dns") == "" {
|
||||
out["dns"] = "223.5.5.5"
|
||||
out["dns"] = service.DefaultDNS()
|
||||
}
|
||||
if service.Str(out, "ike_proposal") == "" {
|
||||
out["ike_proposal"] = "aes256-sha256-modp2048,aes128-sha1-modp1024"
|
||||
@@ -108,7 +105,7 @@ func (s *Service) Create(t *model.Tunnel) error {
|
||||
secrets["password"] = pw
|
||||
}
|
||||
// 允许仅依赖拨号用户表(VPNUser)而无隧道级默认密码。
|
||||
dialUsers, err := loadDialUsers(t.ID)
|
||||
dialUsers, err := service.LoadDialUsers(t.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -202,34 +199,9 @@ func (s *Service) RefreshAuth(t *model.Tunnel) error {
|
||||
return s.Create(t)
|
||||
}
|
||||
|
||||
type dialUser struct {
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
func loadDialUsers(tunnelID uint) ([]dialUser, error) {
|
||||
if store.DB == nil {
|
||||
return nil, nil
|
||||
}
|
||||
var users []model.VPNUser
|
||||
if err := store.DB.Where("tunnel_id = ? AND enabled = ? AND source = ?", tunnelID, true, "local").Find(&users).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]dialUser, 0, len(users))
|
||||
for _, u := range users {
|
||||
if u.DialSecret == "" {
|
||||
continue
|
||||
}
|
||||
pw, err := store.DecryptSecret(u.DialSecret)
|
||||
if err != nil || pw == "" {
|
||||
continue
|
||||
}
|
||||
out = append(out, dialUser{Username: u.Username, Password: pw})
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func buildChapSecrets(defaultUser, defaultPass string, users []dialUser) string {
|
||||
func buildChapSecrets(defaultUser, defaultPass string, users []service.DialUser) string {
|
||||
var b strings.Builder
|
||||
b.WriteString("# client server secret IP addresses\n")
|
||||
seen := map[string]bool{}
|
||||
@@ -361,6 +333,9 @@ func (s *Service) Delete(t *model.Tunnel) error { return s.Stop(t) }
|
||||
// it; without this guard a later instance would look started but accept no VPN
|
||||
// sessions. Network namespaces can deliberately lift this restriction later.
|
||||
func (s *Service) ensureExclusiveListener(t *model.Tunnel) error {
|
||||
if store.DB == nil {
|
||||
return nil
|
||||
}
|
||||
var count int64
|
||||
if err := store.DB.Model(&model.Tunnel{}).Where("protocol = ? AND state = ? AND id <> ?", "l2tp", "running", t.ID).Count(&count).Error; err != nil {
|
||||
return fmt.Errorf("检查 L2TP 监听冲突失败: %w", err)
|
||||
@@ -372,10 +347,7 @@ func (s *Service) ensureExclusiveListener(t *model.Tunnel) error {
|
||||
}
|
||||
|
||||
func (s *Service) unload(bin, confPath string) error {
|
||||
// swanctl reports an error when an object was never loaded. Treat that as
|
||||
// success so Stop/Delete remain idempotent after a partial failed startup.
|
||||
_, _ = service.Run(bin, "--unload-conns", "--file", confPath)
|
||||
_, _ = service.Run(bin, "--unload-creds", "--file", confPath)
|
||||
service.SwanctlUnload(bin, confPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user