diff --git a/backend/api/handlers.go b/backend/api/handlers.go index 84a385c..ee55ec8 100644 --- a/backend/api/handlers.go +++ b/backend/api/handlers.go @@ -252,6 +252,11 @@ func (h *Handler) heartbeat(w http.ResponseWriter, r *http.Request) { h.db.UpdateAgentVersion(req.AgentID, req.AgentVersion) } + // Genutzten API-Key speichern (aus Middleware-Kontext) + if keyInfo := GetAPIKeyFromContext(r); keyInfo != nil { + h.db.UpdateAgentAPIKey(req.AgentID, keyInfo.Key) + } + if err := h.db.SaveSystemData(req.AgentID, &req.SystemData); err != nil { if strings.Contains(err.Error(), "nicht gefunden") { writeError(w, http.StatusNotFound, "Agent nicht gefunden") diff --git a/backend/db/postgres.go b/backend/db/postgres.go index bbeb76a..85ad234 100644 --- a/backend/db/postgres.go +++ b/backend/db/postgres.go @@ -140,6 +140,7 @@ func (d *Database) migrate() error { d.db.Exec("ALTER TABLE agents ADD COLUMN IF NOT EXISTS agent_version TEXT NOT NULL DEFAULT ''") d.db.Exec("ALTER TABLE agents ADD COLUMN IF NOT EXISTS update_requested BOOLEAN NOT NULL DEFAULT FALSE") d.db.Exec("ALTER TABLE agents ADD COLUMN IF NOT EXISTS platform TEXT NOT NULL DEFAULT 'freebsd'") + d.db.Exec("ALTER TABLE agents ADD COLUMN IF NOT EXISTS last_api_key TEXT NOT NULL DEFAULT ''") // Agent-Firmware Tabelle (Multi-Plattform) d.db.Exec(`CREATE TABLE IF NOT EXISTS agent_firmware ( @@ -627,6 +628,10 @@ func (d *Database) UpdateAgentVersion(id, version string) error { return err } +func (d *Database) UpdateAgentAPIKey(id, apiKey string) { + d.db.Exec("UPDATE agents SET last_api_key = $1 WHERE id = $2", apiKey, id) +} + // Update-Request Flag setzen/lesen/loeschen func (d *Database) SetUpdateRequest(id string, requested bool) error { _, err := d.db.Exec("UPDATE agents SET update_requested = $1 WHERE id = $2", requested, id) @@ -1099,7 +1104,7 @@ func (d *Database) UnassignAgentCustomer(agentID string) error { } func (d *Database) GetAgentsByCustomer(customerID int) ([]models.AgentResponse, error) { - rows, err := d.db.Query("SELECT id, name, hostname, ip, opnsense_version, registered_at, last_heartbeat, customer_id, agent_version FROM agents WHERE customer_id = $1 ORDER BY name", customerID) + rows, err := d.db.Query("SELECT id, name, hostname, ip, opnsense_version, registered_at, last_heartbeat, customer_id, agent_version, last_api_key FROM agents WHERE customer_id = $1 ORDER BY name", customerID) if err != nil { return nil, err } @@ -1110,7 +1115,7 @@ func (d *Database) GetAgentsByCustomer(customerID int) ([]models.AgentResponse, var a models.Agent var lastHB sql.NullTime var custID sql.NullInt64 - if err := rows.Scan(&a.ID, &a.Name, &a.Hostname, &a.IP, &a.OPNsenseVersion, &a.RegisteredAt, &lastHB, &custID, &a.AgentVersion); err != nil { + if err := rows.Scan(&a.ID, &a.Name, &a.Hostname, &a.IP, &a.OPNsenseVersion, &a.RegisteredAt, &lastHB, &custID, &a.AgentVersion, &a.LastAPIKey); err != nil { return nil, err } if lastHB.Valid { diff --git a/backend/models/agent.go b/backend/models/agent.go index 333e608..efc46f8 100644 --- a/backend/models/agent.go +++ b/backend/models/agent.go @@ -15,6 +15,7 @@ type Agent struct { LastHeartbeat *time.Time `json:"last_heartbeat,omitempty"` CustomerID *int `json:"customer_id,omitempty"` UpdateRequested bool `json:"update_requested"` + LastAPIKey string `json:"last_api_key,omitempty"` } // AgentResponse erweitert Agent um den berechneten Status diff --git a/frontend/src/pages/Customers.jsx b/frontend/src/pages/Customers.jsx index 370e8fc..fc3ee23 100644 --- a/frontend/src/pages/Customers.jsx +++ b/frontend/src/pages/Customers.jsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react' import api from '../api/client' import { copyToClipboard } from '../utils/clipboard' -import { Plus, Trash2, Edit2, X, Check, ChevronDown, ChevronRight, Copy, Key, Monitor } from 'lucide-react' +import { Plus, Trash2, Edit2, X, Check, ChevronDown, ChevronRight, Copy, Key, Monitor, AlertTriangle } from 'lucide-react' const PERM_LABELS = { agent: { label: 'Agent', color: 'text-blue-400 bg-blue-900/30 border-blue-700/50' }, @@ -232,16 +232,32 @@ function CustomerKeyPanel({ customerId }) { {agents.length === 0 ? (