From c711899e4d9d3689ae5573525e80fd2771847a4f Mon Sep 17 00:00:00 2001 From: duffyduck Date: Thu, 12 Mar 2026 02:05:01 +0100 Subject: [PATCH] added check claude credentials in log server and changelog altered --- CHANGELOG.md | 4 ++- diagnostic/index.html | 12 +++++++ diagnostic/server.js | 81 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80b54d2..bb28509 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,9 @@ Alle Änderungen am Projekt. Format: [Keep a Changelog](https://keepachangelog.c **Diagnostic Container — Selbstcheck-UI** - Neuer Container `aria-diagnostic` mit Web-UI auf Port 3001 - Status-Karten: OpenClaw Gateway, RVS, Claude Proxy — jeweils mit Dot-Indicator -- Claude Proxy Test: Prüft Erreichbarkeit (`/v1/models`) und sendet Test-Prompt an Claude +- Claude Proxy Test: Prüft Erreichbarkeit (`/v1/models`) und sendet Test-Prompt an Claude — zeigt verfügbare Modelle als Tags + `DEFAULT_MODEL` Hinweis für docker-compose.yml +- Auth-Check: "Auth prüfen" Button zeigt Inhalt von `/root/.config/claude/` im Proxy-Container (Dateien + `.credentials.json`) — per Docker Exec API +- Docker Exec API: Generische `dockerExec()` Funktion für Befehle in laufenden Containern (via Docker Socket) - Chat-Test: Nachrichten direkt über Gateway oder via RVS senden - Tabbed Logs: Separate Tabs für Alle, Gateway, RVS, Proxy, Server — mit Zähler pro Tab - Autoscroll-Pause: Automatisch wenn hochgescrollt, "Nach unten" Button zum Fortsetzen diff --git a/diagnostic/index.html b/diagnostic/index.html index 3ce566c..e2036fe 100644 --- a/diagnostic/index.html +++ b/diagnostic/index.html @@ -107,7 +107,9 @@
+ + @@ -283,6 +285,12 @@ if (msg.models && msg.models.length) showProxyModels(msg.models); return; } + if (msg.type === 'proxy_auth') { + const el = document.getElementById('proxy-auth'); + el.style.display = 'block'; + el.textContent = msg.error ? `Fehler: ${msg.error}` : msg.info; + return; + } if (msg.type === 'docker_logs') { showDockerLogs(msg); return; @@ -315,6 +323,10 @@ send({ action: 'test_proxy', text: 'Antworte mit genau einem Wort: Ping' }); } + function checkProxyAuth() { + send({ action: 'check_proxy_auth' }); + } + function loadDockerLogs() { if (!DOCKER_TABS.includes(activeTab)) return; send({ action: 'docker_logs', tab: activeTab, tail: 200 }); diff --git a/diagnostic/server.js b/diagnostic/server.js index bbd26a9..d227579 100644 --- a/diagnostic/server.js +++ b/diagnostic/server.js @@ -374,6 +374,15 @@ async function testProxy(prompt) { log("info", "proxy", `Fuer docker-compose.yml (DEFAULT_MODEL): ${models.map(m => m.replace("openai/", "")).join(" | ")}`); } + // Schritt 1b: Auth-Dateien im Proxy-Container pruefen + try { + const authInfo = await dockerExec("aria-proxy", "ls -la /root/.config/claude/ 2>&1 && echo '---' && cat /root/.config/claude/.credentials.json 2>/dev/null | head -c 500 || echo '(keine .credentials.json)'"); + log("info", "proxy", `Auth-Dateien im Container:\n${authInfo}`); + broadcast({ type: "proxy_auth", info: authInfo }); + } catch (authErr) { + log("warn", "proxy", `Auth-Check fehlgeschlagen: ${authErr.message}`); + } + // Schritt 2: Chat Completion testen (kurzer Prompt) const testPrompt = prompt || "Antworte mit genau einem Wort: Ping"; log("info", "proxy", `Sende Test-Prompt: "${testPrompt}"`); @@ -416,6 +425,18 @@ async function testProxy(prompt) { } } +async function checkProxyAuth() { + try { + log("info", "proxy", "Pruefe Auth-Dateien im Proxy-Container..."); + const authInfo = await dockerExec("aria-proxy", "echo '=== /root/.config/claude/ ===' && ls -la /root/.config/claude/ 2>&1 && echo '' && echo '=== .credentials.json ===' && cat /root/.config/claude/.credentials.json 2>/dev/null || echo '(nicht vorhanden)'"); + log("info", "proxy", `Auth-Dateien:\n${authInfo}`); + broadcast({ type: "proxy_auth", info: authInfo }); + } catch (err) { + log("error", "proxy", `Auth-Check fehlgeschlagen: ${err.message}`); + broadcast({ type: "proxy_auth", info: null, error: err.message }); + } +} + // ── Docker Container Logs ──────────────────────────────── const CONTAINER_MAP = { @@ -476,6 +497,64 @@ async function handleDockerLogs(ws, tab, tail) { } } +// ── Docker Exec (Befehl in Container ausfuehren) ──────── + +function dockerExec(containerName, cmd) { + return new Promise((resolve, reject) => { + const createBody = JSON.stringify({ + AttachStdout: true, AttachStderr: true, + Cmd: Array.isArray(cmd) ? cmd : ["sh", "-c", cmd], + }); + + const createReq = http.request({ + socketPath: "/var/run/docker.sock", + path: `/containers/${containerName}/exec`, + method: "POST", + headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(createBody) }, + }, (res) => { + let data = ""; + res.on("data", (c) => data += c); + res.on("end", () => { + if (res.statusCode !== 201) return reject(new Error(`Exec create: HTTP ${res.statusCode} — ${data.slice(0, 200)}`)); + const execId = JSON.parse(data).Id; + + // Exec starten + const startBody = JSON.stringify({ Detach: false }); + const startReq = http.request({ + socketPath: "/var/run/docker.sock", + path: `/exec/${execId}/start`, + method: "POST", + headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(startBody) }, + }, (sRes) => { + const chunks = []; + sRes.on("data", (c) => chunks.push(c)); + sRes.on("end", () => { + // Docker multiplexed stream: 8-byte header pro Frame + const raw = Buffer.concat(chunks); + const lines = []; + let offset = 0; + while (offset < raw.length) { + if (offset + 8 > raw.length) { lines.push(raw.slice(offset).toString("utf-8").trim()); break; } + const size = raw.readUInt32BE(offset + 4); + if (size === 0 || offset + 8 + size > raw.length) { lines.push(raw.slice(offset).toString("utf-8").trim()); break; } + const line = raw.slice(offset + 8, offset + 8 + size).toString("utf-8").trimEnd(); + if (line) lines.push(line); + offset += 8 + size; + } + resolve(lines.join("\n")); + }); + }); + startReq.on("error", reject); + startReq.write(startBody); + startReq.end(); + }); + }); + createReq.on("error", reject); + createReq.write(createBody); + createReq.end(); + }); +} + // ── Hilfsfunktionen ───────────────────────────────────── function waitForMessage(ws, timeoutMs) { @@ -529,6 +608,8 @@ wss.on("connection", (ws) => { connectRVS(); } else if (msg.action === "test_proxy") { testProxy(msg.text); + } else if (msg.action === "check_proxy_auth") { + checkProxyAuth(); } else if (msg.action === "docker_logs") { handleDockerLogs(ws, msg.tab, msg.tail); }