1111
All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 30s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 47s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 47s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 1m3s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 45s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 58s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 51s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 1m6s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 50s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 45s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 59s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 51s

This commit is contained in:
Flik
2025-12-29 19:23:09 +08:00
parent 4116d8934c
commit ab81e08100
16 changed files with 846 additions and 36 deletions

View File

@@ -20,6 +20,7 @@ type ServerConfig struct {
type JSPluginConfig struct {
Name string `yaml:"name"`
Path string `yaml:"path"` // JS 文件路径
SigPath string `yaml:"sig_path,omitempty"` // 签名文件路径 (默认为 path + ".sig")
AutoPush []string `yaml:"auto_push,omitempty"` // 自动推送到的客户端 ID 列表
Config map[string]string `yaml:"config,omitempty"` // 插件配置
AutoStart bool `yaml:"auto_start,omitempty"` // 是否自动启动
@@ -27,9 +28,12 @@ type JSPluginConfig struct {
// PluginStoreSettings 扩展商店设置
type PluginStoreSettings struct {
URL string `yaml:"url"` // 扩展商店URL例如 GitHub 仓库的 raw URL
// 保留结构体以便未来扩展,但不暴露 URL 配置
}
// 官方插件商店(不可配置)
const OfficialPluginStoreURL = "https://git.92coco.cn:8443/flik/GoTunnel-Plugins/raw/branch/main/store.json"
// ServerSettings 服务端设置
type ServerSettings struct {
BindAddr string `yaml:"bind_addr"`

View File

@@ -37,6 +37,7 @@ type PluginData struct {
type JSPlugin struct {
Name string `json:"name"`
Source string `json:"source"`
Signature string `json:"signature"` // 官方签名 (Base64)
Description string `json:"description"`
Author string `json:"author"`
AutoPush []string `json:"auto_push"`

View File

@@ -93,6 +93,9 @@ func (s *SQLiteStore) init() error {
return err
}
// 迁移:添加 signature 列
s.db.Exec(`ALTER TABLE js_plugins ADD COLUMN signature TEXT NOT NULL DEFAULT ''`)
return nil
}
@@ -323,7 +326,7 @@ func (s *SQLiteStore) GetAllJSPlugins() ([]JSPlugin, error) {
defer s.mu.RUnlock()
rows, err := s.db.Query(`
SELECT name, source, description, author, auto_push, config, auto_start, enabled
SELECT name, source, signature, description, author, auto_push, config, auto_start, enabled
FROM js_plugins
`)
if err != nil {
@@ -336,7 +339,7 @@ func (s *SQLiteStore) GetAllJSPlugins() ([]JSPlugin, error) {
var p JSPlugin
var autoPushJSON, configJSON string
var autoStart, enabled int
err := rows.Scan(&p.Name, &p.Source, &p.Description, &p.Author,
err := rows.Scan(&p.Name, &p.Source, &p.Signature, &p.Description, &p.Author,
&autoPushJSON, &configJSON, &autoStart, &enabled)
if err != nil {
return nil, err
@@ -359,9 +362,9 @@ func (s *SQLiteStore) GetJSPlugin(name string) (*JSPlugin, error) {
var autoPushJSON, configJSON string
var autoStart, enabled int
err := s.db.QueryRow(`
SELECT name, source, description, author, auto_push, config, auto_start, enabled
SELECT name, source, signature, description, author, auto_push, config, auto_start, enabled
FROM js_plugins WHERE name = ?
`, name).Scan(&p.Name, &p.Source, &p.Description, &p.Author,
`, name).Scan(&p.Name, &p.Source, &p.Signature, &p.Description, &p.Author,
&autoPushJSON, &configJSON, &autoStart, &enabled)
if err != nil {
return nil, err
@@ -390,9 +393,9 @@ func (s *SQLiteStore) SaveJSPlugin(p *JSPlugin) error {
_, err := s.db.Exec(`
INSERT OR REPLACE INTO js_plugins
(name, source, description, author, auto_push, config, auto_start, enabled)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
`, p.Name, p.Source, p.Description, p.Author,
(name, source, signature, description, author, auto_push, config, auto_start, enabled)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
`, p.Name, p.Source, p.Signature, p.Description, p.Author,
string(autoPushJSON), string(configJSON), autoStart, enabled)
return err
}

View File

@@ -59,6 +59,7 @@ type ServerInterface interface {
type JSPluginInstallRequest struct {
PluginName string `json:"plugin_name"`
Source string `json:"source"`
Signature string `json:"signature"`
RuleName string `json:"rule_name"`
RemotePort int `json:"remote_port"`
Config map[string]string `json:"config"`
@@ -589,14 +590,8 @@ func (h *APIHandler) handleStorePlugins(rw http.ResponseWriter, r *http.Request)
}
cfg := h.app.GetConfig()
storeURL := cfg.PluginStore.URL
if storeURL == "" {
h.jsonResponse(rw, map[string]interface{}{
"plugins": []StorePluginInfo{},
"store_url": "",
})
return
}
storeURL := config.OfficialPluginStoreURL
_ = cfg // 保留以便未来扩展
// 从远程URL获取插件列表
client := &http.Client{Timeout: 10 * time.Second}
@@ -939,6 +934,7 @@ func (h *APIHandler) pushJSPluginToClient(rw http.ResponseWriter, pluginName, cl
req := JSPluginInstallRequest{
PluginName: p.Name,
Source: p.Source,
Signature: p.Signature,
RuleName: p.Name,
Config: p.Config,
AutoStart: p.AutoStart,

View File

@@ -54,6 +54,7 @@ type Server struct {
type JSPluginEntry struct {
Name string
Source string
Signature string
AutoPush []string
Config map[string]string
AutoStart bool
@@ -873,6 +874,7 @@ func (s *Server) InstallJSPluginToClient(clientID string, req router.JSPluginIns
installReq := protocol.JSPluginInstallRequest{
PluginName: req.PluginName,
Source: req.Source,
Signature: req.Signature,
RuleName: req.RuleName,
RemotePort: req.RemotePort,
Config: req.Config,
@@ -1035,6 +1037,7 @@ func (s *Server) autoPushJSPlugins(cs *ClientSession) {
req := router.JSPluginInstallRequest{
PluginName: jp.Name,
Source: jp.Source,
Signature: jp.Signature,
RuleName: jp.Name,
Config: jp.Config,
AutoStart: jp.AutoStart,