feat: monitor API key management UI #9
@@ -7,6 +7,7 @@ interface ServerRow {
|
||||
display_name: string
|
||||
online: boolean
|
||||
openclaw_version?: string | null
|
||||
plugin_version?: string | null
|
||||
cpu_pct?: number | null
|
||||
mem_pct?: number | null
|
||||
disk_pct?: number | null
|
||||
@@ -36,6 +37,8 @@ interface ServerItem {
|
||||
identifier: string
|
||||
display_name: string
|
||||
online: boolean
|
||||
openclaw_version?: string | null
|
||||
plugin_version?: string | null
|
||||
}
|
||||
|
||||
export default function MonitorPage() {
|
||||
@@ -95,9 +98,21 @@ export default function MonitorPage() {
|
||||
await loadAdminData()
|
||||
}
|
||||
|
||||
const createChallenge = async (id: number) => {
|
||||
const r = await api.post<{ identifier: string; challenge_uuid: string; expires_at: string }>('/monitor/admin/servers/' + id + '/challenge')
|
||||
alert('identifier=' + r.data.identifier + ' | challenge_uuid=' + r.data.challenge_uuid + ' | expires_at=' + r.data.expires_at)
|
||||
const generateApiKey = async (id: number) => {
|
||||
const r = await api.post<{ server_id: number; api_key: string; message: string }>('/monitor/admin/servers/' + id + '/api-key')
|
||||
const apiKey = r.data.api_key
|
||||
try {
|
||||
await navigator.clipboard.writeText(apiKey)
|
||||
alert('API key generated and copied to clipboard:\n\n' + apiKey)
|
||||
} catch {
|
||||
alert('API key generated:\n\n' + apiKey + '\n\nPlease copy and store it securely. It will not be shown again.')
|
||||
}
|
||||
}
|
||||
|
||||
const revokeApiKey = async (id: number) => {
|
||||
if (!confirm('Revoke this server API key? The plugin will stop authenticating until a new key is generated.')) return
|
||||
await api.delete('/monitor/admin/servers/' + id + '/api-key')
|
||||
alert('API key revoked.')
|
||||
}
|
||||
|
||||
if (loading) return <div className="loading">Monitor loading...</div>
|
||||
@@ -139,6 +154,7 @@ export default function MonitorPage() {
|
||||
CPU {s.cpu_pct ?? '-'}% · MEM {s.mem_pct ?? '-'}% · DISK {s.disk_pct ?? '-'}% · SWAP {s.swap_pct ?? '-'}%
|
||||
</div>
|
||||
<div className="text-dim">OpenClaw: {s.openclaw_version || '-'}</div>
|
||||
<div className="text-dim">Plugin: {s.plugin_version || '-'}</div>
|
||||
<div className="text-dim">Agents: {s.agents?.length || 0}</div>
|
||||
</div>
|
||||
))}
|
||||
@@ -162,7 +178,8 @@ export default function MonitorPage() {
|
||||
{servers.map((s) => (
|
||||
<li key={s.server_id}>
|
||||
{s.display_name} ({s.identifier})
|
||||
<button className="btn-secondary" onClick={() => createChallenge(s.server_id)} style={{ marginLeft: 8 }}>Generate Challenge</button>
|
||||
<button className="btn-secondary" onClick={() => generateApiKey(s.server_id)} style={{ marginLeft: 8 }}>Generate API Key</button>
|
||||
<button className="btn-secondary" onClick={() => revokeApiKey(s.server_id)} style={{ marginLeft: 8 }}>Revoke API Key</button>
|
||||
<button className="btn-danger" onClick={() => deleteServer(s.server_id)} style={{ marginLeft: 8 }}>Delete</button>
|
||||
</li>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user