Agent and websocket investigations work fine

This commit is contained in:
Harshavardhan Musanalli
2025-10-27 19:13:39 +01:00
parent 0a8b2dc202
commit 8832450a1f
8 changed files with 1694 additions and 19 deletions

View File

@@ -2,6 +2,7 @@ package auth
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"io"
@@ -395,6 +396,104 @@ func (am *AuthManager) loadRefreshTokenFromBackup() (string, error) {
return refreshToken, nil
}
// GetCurrentAgentID retrieves the agent ID from cache or JWT token
func (am *AuthManager) GetCurrentAgentID() (string, error) {
// First try to read from local cache
agentID, err := am.loadCachedAgentID()
if err == nil && agentID != "" {
return agentID, nil
}
// Cache miss - extract from JWT token and cache it
token, err := am.LoadToken()
if err != nil {
return "", fmt.Errorf("failed to load token: %w", err)
}
// Extract agent ID from JWT 'sub' field
agentID, err = am.extractAgentIDFromJWT(token.AccessToken)
if err != nil {
return "", fmt.Errorf("failed to extract agent ID from JWT: %w", err)
}
// Cache the agent ID for future use
if err := am.cacheAgentID(agentID); err != nil {
// Log warning but don't fail - we still have the agent ID
fmt.Printf("Warning: Failed to cache agent ID: %v\n", err)
}
return agentID, nil
}
// extractAgentIDFromJWT decodes the JWT token and extracts the agent ID from 'sub' field
func (am *AuthManager) extractAgentIDFromJWT(tokenString string) (string, error) {
// Basic JWT decoding without verification (since we trust Supabase)
parts := strings.Split(tokenString, ".")
if len(parts) != 3 {
return "", fmt.Errorf("invalid JWT token format")
}
// Decode the payload (second part)
payload := parts[1]
// Add padding if needed for base64 decoding
for len(payload)%4 != 0 {
payload += "="
}
decoded, err := base64.URLEncoding.DecodeString(payload)
if err != nil {
return "", fmt.Errorf("failed to decode JWT payload: %w", err)
}
// Parse JSON payload
var claims map[string]interface{}
if err := json.Unmarshal(decoded, &claims); err != nil {
return "", fmt.Errorf("failed to parse JWT claims: %w", err)
}
// The agent ID is in the 'sub' field (subject)
if agentID, ok := claims["sub"].(string); ok && agentID != "" {
return agentID, nil
}
return "", fmt.Errorf("agent ID (sub) not found in JWT claims")
}
// loadCachedAgentID reads the cached agent ID from local storage
func (am *AuthManager) loadCachedAgentID() (string, error) {
agentIDPath := filepath.Join(TokenStorageDir, "agent_id")
data, err := os.ReadFile(agentIDPath)
if err != nil {
return "", fmt.Errorf("failed to read cached agent ID: %w", err)
}
agentID := strings.TrimSpace(string(data))
if agentID == "" {
return "", fmt.Errorf("cached agent ID is empty")
}
return agentID, nil
}
// cacheAgentID stores the agent ID in local cache
func (am *AuthManager) cacheAgentID(agentID string) error {
// Ensure the directory exists
if err := am.EnsureTokenStorageDir(); err != nil {
return fmt.Errorf("failed to ensure storage directory: %w", err)
}
agentIDPath := filepath.Join(TokenStorageDir, "agent_id")
// Write agent ID to file with secure permissions
if err := os.WriteFile(agentIDPath, []byte(agentID), 0600); err != nil {
return fmt.Errorf("failed to write agent ID cache: %w", err)
}
return nil
}
func (am *AuthManager) getTokenPath() string {
if am.config.TokenPath != "" {
return am.config.TokenPath