Agent and websocket investigations work fine
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user