From 24322b613d65a63ea49be1c8a4f1abfa95e8f1fa Mon Sep 17 00:00:00 2001 From: Akizon77 Date: Fri, 21 Nov 2025 15:31:01 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=B7=BB=E5=8A=A0=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E8=A7=A6=E5=8F=91=E9=80=BB=E8=BE=91=E4=BB=A5=E5=A2=9E?= =?UTF-8?q?=E5=BC=BA=E5=AE=A2=E6=88=B7=E7=AB=AF=E5=92=8C=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E7=9A=84=E8=B7=9F=E8=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/api_rpc/client.go | 31 +++++++++++++++++++++++ internal/api_v1/admin/client.go | 13 ++++++++++ internal/api_v1/client/autoDiscovery.go | 6 +++++ internal/api_v1/client/report.go | 19 +++++++++++++- internal/api_v1/client/task.go | 7 +++++ internal/api_v1/client/uploadBasicInfo.go | 9 ++++++- internal/api_v1/login.go | 8 ++++++ internal/api_v1/oauth.go | 5 ++++ internal/client/client.go | 7 +++++ internal/database/accounts/2fa.go | 20 +++++++++++++-- internal/database/accounts/accounts.go | 15 +++++++++++ internal/database/accounts/sessions.go | 5 ++++ internal/database/tasks/tasks.go | 7 +++++ internal/renewal/renewal.go | 6 +++++ 14 files changed, 154 insertions(+), 4 deletions(-) create mode 100644 internal/api_rpc/client.go create mode 100644 internal/client/client.go diff --git a/internal/api_rpc/client.go b/internal/api_rpc/client.go new file mode 100644 index 0000000..db68ec0 --- /dev/null +++ b/internal/api_rpc/client.go @@ -0,0 +1,31 @@ +package api_rpc + +import ( + "context" + + "github.com/komari-monitor/komari/pkg/rpc" +) + +const GroupClient = "client" + +func init() { + RegisterWithGroupAndMeta("register", GroupClient, registerClient, &rpc.MethodMeta{ + Name: "RegisterClient", + Description: "Register a new client with the server (Auto discovery).", + Params: []rpc.ParamMeta{ + { + Name: "name", + Type: "string", + Description: "The name of the client to register.", + }, + }, + }) +} + +func registerClient(ctx context.Context, req *rpc.JsonRpcRequest) (any, *rpc.JsonRpcError) { + var params struct { + Name string `json:"name"` + } + req.BindParams(¶ms) + return nil, rpc.MakeError(rpc.InternalError, "Not impl yet", nil) +} diff --git a/internal/api_v1/admin/client.go b/internal/api_v1/admin/client.go index 8d9d45d..b7f486c 100644 --- a/internal/api_v1/admin/client.go +++ b/internal/api_v1/admin/client.go @@ -4,9 +4,11 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/gookit/event" "github.com/komari-monitor/komari/internal/database/auditlog" "github.com/komari-monitor/komari/internal/database/clients" "github.com/komari-monitor/komari/internal/database/records" + "github.com/komari-monitor/komari/internal/eventType" "github.com/komari-monitor/komari/internal/ws" ) @@ -30,6 +32,10 @@ func AddClient(c *gin.Context) { } user_uuid, _ := c.Get("uuid") auditlog.Log(c.ClientIP(), user_uuid.(string), "create client:"+uuid, "info") + event.Trigger(eventType.ClientCreated, event.M{ + "client": uuid, + "token": token, + }) c.JSON(http.StatusOK, gin.H{"status": "success", "uuid": uuid, "token": token, "message": ""}) } @@ -52,6 +58,10 @@ func EditClient(c *gin.Context) { } user_uuid, _ := c.Get("uuid") auditlog.Log(c.ClientIP(), user_uuid.(string), "edit client:"+uuid, "info") + event.Trigger(eventType.ClientUpdated, event.M{ + "client": uuid, + "data": req, + }) c.JSON(http.StatusOK, gin.H{"status": "success"}) } @@ -70,6 +80,9 @@ func RemoveClient(c *gin.Context) { c.JSON(200, gin.H{"status": "success"}) ws.DeleteConnectedClients(uuid) ws.DeleteLatestReport(uuid) + event.Trigger(eventType.ClientDeleted, event.M{ + "client": uuid, + }) } func ClearRecord(c *gin.Context) { diff --git a/internal/api_v1/client/autoDiscovery.go b/internal/api_v1/client/autoDiscovery.go index c7ce835..1bd3806 100644 --- a/internal/api_v1/client/autoDiscovery.go +++ b/internal/api_v1/client/autoDiscovery.go @@ -2,9 +2,11 @@ package client import ( "github.com/gin-gonic/gin" + "github.com/gookit/event" api "github.com/komari-monitor/komari/internal/api_v1" "github.com/komari-monitor/komari/internal/conf" "github.com/komari-monitor/komari/internal/database/clients" + "github.com/komari-monitor/komari/internal/eventType" "github.com/komari-monitor/komari/pkg/utils" ) @@ -37,5 +39,9 @@ func RegisterClient(c *gin.Context) { api.RespondError(c, 500, "Failed to create client: "+err.Error()) return } + event.Trigger(eventType.ClientCreated, event.M{ + "client": uuid, + "token": token, + }) api.RespondSuccess(c, gin.H{"uuid": uuid, "token": token}) } diff --git a/internal/api_v1/client/report.go b/internal/api_v1/client/report.go index 420b80d..10c8e2b 100644 --- a/internal/api_v1/client/report.go +++ b/internal/api_v1/client/report.go @@ -11,12 +11,14 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/gookit/event" "github.com/gorilla/websocket" api "github.com/komari-monitor/komari/internal/api_v1" "github.com/komari-monitor/komari/internal/common" "github.com/komari-monitor/komari/internal/database/clients" "github.com/komari-monitor/komari/internal/database/models" "github.com/komari-monitor/komari/internal/database/tasks" + "github.com/komari-monitor/komari/internal/eventType" "github.com/komari-monitor/komari/internal/notifier" "github.com/komari-monitor/komari/internal/ws" "github.com/patrickmn/go-cache" @@ -123,13 +125,18 @@ func WebSocketReport(c *gin.Context) { go oldConn.Close() } ws.SetConnectedClients(uuid, conn) - log.Printf("Client %s is reconnect success, connID: %d", uuid, conn.ID) + //log.Printf("Client %s is reconnect success, connID: %d", uuid, conn.ID) go notifier.OnlineNotification(uuid, conn.ID) defer func() { ws.DeleteClientConditionally(uuid, conn) notifier.OfflineNotification(uuid, conn.ID) }() + event.Trigger(eventType.ClientWebsocketConnected, event.M{ + "client": uuid, + "online": len(ws.GetConnectedClients()), + "connID": conn.ID, + }) // 首先处理第一次ws conn收到的消息 processMessage(conn, message, uuid) @@ -143,8 +150,18 @@ func WebSocketReport(c *gin.Context) { } break // 任何读错误(包括超时)都意味着连接已断开,退出循环 } + event.Trigger(eventType.ClientMessageReceived, event.M{ + "client": uuid, + "type": "websocket", + "message": string(message), + }) processMessage(conn, message, uuid) } + event.Trigger(eventType.ClientWebsocketDisconnected, event.M{ + "client": uuid, + "online": len(ws.GetConnectedClients()), + "connID": conn.ID, + }) } // 将消息处理逻辑提取到一个函数中,方便复用 diff --git a/internal/api_v1/client/task.go b/internal/api_v1/client/task.go index 80907db..eee997d 100644 --- a/internal/api_v1/client/task.go +++ b/internal/api_v1/client/task.go @@ -4,9 +4,11 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/gookit/event" "github.com/komari-monitor/komari/internal/database/clients" "github.com/komari-monitor/komari/internal/database/models" "github.com/komari-monitor/komari/internal/database/tasks" + "github.com/komari-monitor/komari/internal/eventType" ) func TaskResult(c *gin.Context) { @@ -33,4 +35,9 @@ func TaskResult(c *gin.Context) { } c.JSON(200, gin.H{"status": "success", "message": "Task result updated successfully"}) + event.Trigger(eventType.TaskUpdated, event.M{ + "task": req.TaskId, + "client": clientId, + "data": req, + }) } diff --git a/internal/api_v1/client/uploadBasicInfo.go b/internal/api_v1/client/uploadBasicInfo.go index 2c21b33..5519234 100644 --- a/internal/api_v1/client/uploadBasicInfo.go +++ b/internal/api_v1/client/uploadBasicInfo.go @@ -3,8 +3,10 @@ package client import ( "net" + "github.com/gookit/event" "github.com/komari-monitor/komari/internal/conf" "github.com/komari-monitor/komari/internal/database/clients" + "github.com/komari-monitor/komari/internal/eventType" "github.com/komari-monitor/komari/internal/geoip" "github.com/gin-gonic/gin" @@ -80,6 +82,11 @@ func UploadBasicInfo(c *gin.Context) { c.JSON(500, gin.H{"status": "error", "error": err}) return } - + event.Trigger(eventType.ClientMessageReceived, event.M{ + "client": cbi["uuid"], + "type": "basic_info", + "data": cbi, + }) c.JSON(200, gin.H{"status": "success"}) + } diff --git a/internal/api_v1/login.go b/internal/api_v1/login.go index 294bbc6..2ec1195 100644 --- a/internal/api_v1/login.go +++ b/internal/api_v1/login.go @@ -93,5 +93,13 @@ func Logout(c *gin.Context) { accounts.DeleteSession(session) c.SetCookie("session_token", "", -1, "/", "", false, true) auditlog.Log(c.ClientIP(), "", "logged out", "logout") + event.Trigger(eventType.UserLogout, event.M{ + "ip": c.ClientIP(), + "ua": c.Request.UserAgent(), + "header": c.Request.Header, + "referrer": c.Request.Referer(), + "host": c.Request.Host, + }) c.Redirect(302, "/") + } diff --git a/internal/api_v1/oauth.go b/internal/api_v1/oauth.go index 27813b8..97046f2 100644 --- a/internal/api_v1/oauth.go +++ b/internal/api_v1/oauth.go @@ -88,7 +88,12 @@ func OAuthCallback(c *gin.Context) { return } auditlog.Log(c.ClientIP(), user.UUID, "bound external account (OAuth)"+fmt.Sprintf(",sso_id: %s", sso_id), "login") + event.Trigger(eventType.UserOidcBound, event.M{ + "user": user.UUID, + "sso_id": sso_id, + }) c.Redirect(302, "/admin") + return } diff --git a/internal/client/client.go b/internal/client/client.go new file mode 100644 index 0000000..b5edfcf --- /dev/null +++ b/internal/client/client.go @@ -0,0 +1,7 @@ +package client + +import "fmt" + +func Create(name string) error { + return fmt.Errorf("not implemented") +} diff --git a/internal/database/accounts/2fa.go b/internal/database/accounts/2fa.go index 3960a0c..4569515 100644 --- a/internal/database/accounts/2fa.go +++ b/internal/database/accounts/2fa.go @@ -3,8 +3,10 @@ package accounts import ( "image" + "github.com/gookit/event" "github.com/komari-monitor/komari/internal/database/dbcore" "github.com/komari-monitor/komari/internal/database/models" + "github.com/komari-monitor/komari/internal/eventType" "github.com/pquerna/otp/totp" ) @@ -29,7 +31,14 @@ func Generate2Fa() (string, image.Image, error) { func Enable2Fa(uuid, secret string) error { db := dbcore.GetDBInstance() - return db.Model(&models.User{}).Where("uuid = ?", uuid).Update("two_factor", secret).Error + err := db.Model(&models.User{}).Where("uuid = ?", uuid).Update("two_factor", secret).Error + if err != nil { + event.Trigger(eventType.UserTwoFaAdded, event.M{ + "user": uuid, + }) + return err + } + return nil } func Verify2Fa(uuid, code string) (bool, error) { @@ -54,5 +63,12 @@ func Verify2Fa(uuid, code string) (bool, error) { func Disable2Fa(uuid string) error { db := dbcore.GetDBInstance() - return db.Model(&models.User{}).Where("uuid = ?", uuid).Update("two_factor", "").Error + err := db.Model(&models.User{}).Where("uuid = ?", uuid).Update("two_factor", "").Error + if err != nil { + return err + } + event.Trigger(eventType.UserTwoFaRemoved, event.M{ + "user": uuid, + }) + return nil } diff --git a/internal/database/accounts/accounts.go b/internal/database/accounts/accounts.go index bf4941c..c4c2ece 100644 --- a/internal/database/accounts/accounts.go +++ b/internal/database/accounts/accounts.go @@ -7,8 +7,10 @@ import ( "os" "time" + "github.com/gookit/event" "github.com/komari-monitor/komari/internal/database/dbcore" "github.com/komari-monitor/komari/internal/database/models" + "github.com/komari-monitor/komari/internal/eventType" "github.com/komari-monitor/komari/pkg/utils" "github.com/google/uuid" @@ -179,5 +181,18 @@ func UpdateUser(uuid string, name, password, sso_type *string) error { if password != nil { DeleteAllSessions() } + if name != nil { + event.Trigger(eventType.UserUpdateUsername, event.M{ + "user": uuid, + }) + } else if password != nil { + event.Trigger(eventType.UserUpdatePassword, event.M{ + "user": uuid, + }) + } else if sso_type != nil && *sso_type == "" { + event.Trigger(eventType.UserOidcUnbound, event.M{ + "user": uuid, + }) + } return nil } diff --git a/internal/database/accounts/sessions.go b/internal/database/accounts/sessions.go index a7b8ce6..5752182 100644 --- a/internal/database/accounts/sessions.go +++ b/internal/database/accounts/sessions.go @@ -6,10 +6,12 @@ import ( "net" "time" + "github.com/gookit/event" "github.com/komari-monitor/komari/internal/conf" "github.com/komari-monitor/komari/internal/database/dbcore" "github.com/komari-monitor/komari/internal/database/models" messageevent "github.com/komari-monitor/komari/internal/database/models/messageEvent" + "github.com/komari-monitor/komari/internal/eventType" "github.com/komari-monitor/komari/internal/geoip" "github.com/komari-monitor/komari/internal/messageSender" "github.com/komari-monitor/komari/pkg/utils" @@ -97,6 +99,9 @@ func DeleteSession(session string) (err error) { if result.Error != nil { return result.Error } + event.Trigger(eventType.UserSessionRevoked, event.M{ + "session": session, + }) return nil } diff --git a/internal/database/tasks/tasks.go b/internal/database/tasks/tasks.go index 4ec51fd..93c4195 100644 --- a/internal/database/tasks/tasks.go +++ b/internal/database/tasks/tasks.go @@ -3,8 +3,10 @@ package tasks import ( "time" + "github.com/gookit/event" "github.com/komari-monitor/komari/internal/database/dbcore" "github.com/komari-monitor/komari/internal/database/models" + "github.com/komari-monitor/komari/internal/eventType" ) func CreateTask(taskId string, clients []string, command string) error { @@ -32,6 +34,11 @@ func CreateTask(taskId string, clients []string, command string) error { if len(taskResults) > 0 { return db.Create(&taskResults).Error } + event.Trigger(eventType.TaskCreated, event.M{ + "task": taskId, + "clients": clients, + "command": command, + }) return nil } func GetTaskByTaskId(taskId string) (*models.Task, error) { diff --git a/internal/renewal/renewal.go b/internal/renewal/renewal.go index ad3e927..25a64c9 100644 --- a/internal/renewal/renewal.go +++ b/internal/renewal/renewal.go @@ -4,10 +4,12 @@ import ( "fmt" "time" + "github.com/gookit/event" "github.com/komari-monitor/komari/internal/database/auditlog" "github.com/komari-monitor/komari/internal/database/clients" "github.com/komari-monitor/komari/internal/database/models" messageevent "github.com/komari-monitor/komari/internal/database/models/messageEvent" + "github.com/komari-monitor/komari/internal/eventType" "github.com/komari-monitor/komari/internal/messageSender" "github.com/komari-monitor/komari/internal/ws" ) @@ -112,6 +114,10 @@ func CheckAndAutoRenewal(client models.Client) { Emoji: "🔄", Message: fmt.Sprintf("• %s until %s\n", client.Name, newExpireTime.Format("2006-01-02")), }) + event.Trigger(eventType.ClientRenewed, event.M{ + "client": client, + "new_expire_at": newExpireTime, + }) } }