feat: add public.agents table and its set_updated_at trigger.
This commit is contained in:
parent
e48c23fab5
commit
3ffd39cc8b
@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@ -81,8 +82,17 @@ func (h *handler) listAgentNodes(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Add panic recovery for this handler
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Printf("PANIC in listAgentNodes: %v\n", r)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "internal_error", "message": fmt.Sprintf("%v", r)})
|
||||
}
|
||||
}()
|
||||
|
||||
registeredHosts, registeredNames := registeredNodeMetadata(h.agentStatusReader)
|
||||
hosts := parseProxyNodeHosts(h.publicURL, registeredHosts)
|
||||
|
||||
if len(hosts) == 0 {
|
||||
c.JSON(http.StatusOK, []vlessNode{})
|
||||
return
|
||||
|
||||
@ -722,10 +722,26 @@ func runServer(ctx context.Context, cfg *config.Config, logger *slog.Logger) err
|
||||
} else {
|
||||
agents := agentRegistry.Agents()
|
||||
logger.Info("loaded agents from store", "count", len(agents))
|
||||
for _, agent := range agents {
|
||||
logger.Info("loaded agent", "id", agent.ID, "name", agent.Name, "groups", agent.Groups)
|
||||
}
|
||||
}
|
||||
|
||||
// Start background sync task to keep in-memory registry updated from DB
|
||||
go func() {
|
||||
ticker := time.NewTicker(1 * time.Minute)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
if err := agentRegistry.Load(ctx); err != nil {
|
||||
logger.Warn("failed to reload agents from store", "err", err)
|
||||
} else {
|
||||
// logger.Debug("reloaded agents from store", "count", len(agentRegistry.Agents()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Start background cleanup task for stale agents (e.g., those that haven't heartbeated for 10 minutes)
|
||||
go runAgentCleanup(ctx, st, logger)
|
||||
}
|
||||
|
||||
@ -54,8 +54,19 @@ const (
|
||||
// AuthMiddleware is a middleware that validates JWT access tokens
|
||||
func (s *TokenService) AuthMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
var token string
|
||||
authHeader := c.GetHeader("Authorization")
|
||||
if authHeader == "" {
|
||||
|
||||
if authHeader != "" && strings.HasPrefix(authHeader, bearerPrefix) {
|
||||
token = strings.TrimPrefix(authHeader, bearerPrefix)
|
||||
} else {
|
||||
// Fallback to session cookie
|
||||
if cookie, err := c.Cookie("xc_session"); err == nil {
|
||||
token = cookie
|
||||
}
|
||||
}
|
||||
|
||||
if token == "" {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{
|
||||
"error": "missing authorization header",
|
||||
})
|
||||
@ -63,16 +74,6 @@ func (s *TokenService) AuthMiddleware() gin.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(authHeader, bearerPrefix) {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{
|
||||
"error": "invalid authorization header format",
|
||||
})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
token := strings.TrimPrefix(authHeader, bearerPrefix)
|
||||
|
||||
claims, err := s.ValidateAccessToken(token)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user