diff --git a/database/database.go b/database/database.go index d1e6fe7..14ce774 100644 --- a/database/database.go +++ b/database/database.go @@ -420,9 +420,8 @@ func DBUpdateFrpcInstance(instance FrpcInstance) error { func DBListFrpcInstances() ([]FrpcInstance, error) { rows, err := global.FrpcDB.Query(` - SELECT fi.id, fi.userID, fi.name, fi.bootAtStart, fi.runUser, fi.configPath, fi.createdAt, fi.watchdog, u.username - FROM frpcInstances fi - JOIN userLogin u ON fi.userID = u.userID + SELECT id, userID, name, bootAtStart, runUser, configPath, createdAt, watchdog + FROM frpcInstances `) if err != nil { return nil, fmt.Errorf("failed to query all frpc instances: %w", err) @@ -433,10 +432,19 @@ func DBListFrpcInstances() ([]FrpcInstance, error) { for rows.Next() { var instance FrpcInstance var createdAtStr string - if err := rows.Scan(&instance.ID, &instance.UserID, &instance.Name, &instance.BootAtStart, &instance.RunUser, &instance.ConfigPath, &createdAtStr, &instance.Watchdog, &instance.CreatedBy); err != nil { + if err := rows.Scan(&instance.ID, &instance.UserID, &instance.Name, &instance.BootAtStart, &instance.RunUser, &instance.ConfigPath, &createdAtStr, &instance.Watchdog); err != nil { return nil, fmt.Errorf("failed to scan frpc instance: %w", err) } instance.CreatedAt, _ = time.Parse(time.RFC3339, createdAtStr) + + user, err := GetUserByID(instance.UserID) + if err != nil { + postLog.Warning(fmt.Sprintf("[DBListFrpcInstances] Failed to get user %d: %v", instance.UserID, err)) + instance.CreatedBy = "unknown" + } else { + instance.CreatedBy = user.Username + } + instances = append(instances, instance) } @@ -466,7 +474,9 @@ func GetServiceNameByInstanceID(instanceID int) (string, error) { user, err := GetUserByID(instance.UserID) if err != nil { - return "", fmt.Errorf("failed to get user info: %w", err) + postLog.Warning(fmt.Sprintf("[GetServiceNameByInstanceID] User %d not found, using fallback", instance.UserID)) + serviceName := fmt.Sprintf("superfrpc_unknown_%s", instance.Name) + return serviceName, nil } serviceName := fmt.Sprintf("superfrpc_%s_%s", user.Username, instance.Name) diff --git a/docs/api.md b/docs/api.md index 82e96dd..50b4efd 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1234,7 +1234,7 @@ X-Timestamp: 1704067200000 **Endpoint:** `/frpcAct/proxyMgr/list` **Method:** GET **Auth Required:** Yes (token) -**Permission Level:** None (any permission level) +**Permission Level:** Visitor Retrieve a list of all proxy configurations for a specific frpc instance. The proxy configurations are read from the instance's config file. @@ -1314,7 +1314,7 @@ X-Timestamp: 1704067200000 **Endpoint:** `/frpcAct/instanceMgr/list` **Method:** GET **Auth Required:** Yes (token) -**Permission Level:** Admin +**Permission Level:** Visitor Retrieve a list of all frpc instances on the server. @@ -1363,7 +1363,7 @@ X-Timestamp: 1704067200000 **Auth Required:** Yes (token) **Permission Level:** Visitor -Retrieve information about a specific frpc instance. Returns different information based on user permission level. +Retrieve information about a specific frpc instance. **Request Headers:** ``` diff --git a/handlers/instance.go b/handlers/instance.go index 6906c2e..edb8fd0 100644 --- a/handlers/instance.go +++ b/handlers/instance.go @@ -499,14 +499,15 @@ func getNumFromMap(m map[string]interface{}, key string) int { } func ListInstancesHandler(w http.ResponseWriter, r *http.Request) { - userID, err := utils.Auth(w, r, http.MethodGet, "superuser", "admin") + userID, err := utils.Auth(w, r, http.MethodGet, "visitor", "admin", "superuser") if err != nil { - utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error()) + utils.SendErrorResponse(w, http.StatusUnauthorized, "invalid token or timestamp") postLog.Warning(fmt.Sprintf("[ListInstancesHandler] Auth failed: %v", err)) return } instances, err := database.DBListFrpcInstances() + postLog.Debug(fmt.Sprintf("[ListInstancesHandler] Retrieved %d instances", len(instances))) if err != nil { postLog.Error(fmt.Sprintf("[ListInstancesHandler] Failed to get all instances: %v", err)) utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to get instances") @@ -967,11 +968,6 @@ func GetInstanceInfoHandler(w http.ResponseWriter, r *http.Request) { return } - if instance.UserID != userID { - utils.SendErrorResponse(w, http.StatusForbidden, "Instance not found") - return - } - user, err := database.GetUserByID(userID) if err != nil { postLog.Error(fmt.Sprintf("[GetInstanceInfoHandler] Failed to get user info: %v", err)) diff --git a/handlers/proxy.go b/handlers/proxy.go index a97efa5..5762105 100644 --- a/handlers/proxy.go +++ b/handlers/proxy.go @@ -295,7 +295,7 @@ func DeleteProxyHandler(w http.ResponseWriter, r *http.Request) { } func ListProxiesHandler(w http.ResponseWriter, r *http.Request) { - userID, err := utils.Auth(w, r, http.MethodGet) + _, err := utils.Auth(w, r, http.MethodGet) if err != nil { utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error()) postLog.Warning(fmt.Sprintf("[ListProxiesHandler] Auth failed: %v", err)) @@ -319,12 +319,6 @@ func ListProxiesHandler(w http.ResponseWriter, r *http.Request) { return } - if instance.UserID != userID { - postLog.Error(fmt.Sprintf("[ListProxiesHandler] Instance not found for user %d", userID)) - utils.SendErrorResponse(w, http.StatusNotFound, "Instance not found") - return - } - configContent, err := os.ReadFile(instance.ConfigPath) if err != nil { postLog.Error(fmt.Sprintf("[ListProxiesHandler] Failed to read config file %s: %v", instance.ConfigPath, err))