fixed permission withour create new session, only restarted session
This commit is contained in:
+94
-14
@@ -983,6 +983,8 @@ wss.on("connection", (ws) => {
|
||||
ws.send(JSON.stringify({ type: "active_session", sessionKey: activeSessionKey }));
|
||||
} else if (msg.action === "create_session") {
|
||||
handleCreateSession(ws, msg.sessionName);
|
||||
} else if (msg.action === "restart_session") {
|
||||
handleRestartSession(ws);
|
||||
} else if (msg.action === "list_brain") {
|
||||
handleListBrain(ws);
|
||||
} else if (msg.action === "read_brain_file") {
|
||||
@@ -1314,6 +1316,56 @@ async function handleCreateSession(clientWs, sessionName) {
|
||||
}
|
||||
}
|
||||
|
||||
// ── Session neu starten (Container Restart) ────────────
|
||||
async function handleRestartSession(clientWs) {
|
||||
try {
|
||||
log("info", "server", "Starte aria-core Container neu (Session Restart)...");
|
||||
clientWs.send(JSON.stringify({ type: "session_restarted", status: "restarting" }));
|
||||
|
||||
// Container neu starten via Docker API
|
||||
const http = require("http");
|
||||
await new Promise((resolve, reject) => {
|
||||
const req = http.request({
|
||||
socketPath: "/var/run/docker.sock",
|
||||
path: "/containers/aria-core/restart?t=5",
|
||||
method: "POST",
|
||||
}, (res) => {
|
||||
let body = "";
|
||||
res.on("data", d => body += d);
|
||||
res.on("end", () => {
|
||||
if (res.statusCode === 204 || res.statusCode === 200) resolve();
|
||||
else reject(new Error(`Restart fehlgeschlagen: HTTP ${res.statusCode} ${body}`));
|
||||
});
|
||||
});
|
||||
req.on("error", reject);
|
||||
req.end();
|
||||
});
|
||||
|
||||
log("info", "server", "aria-core Container neu gestartet");
|
||||
// Warten bis Gateway wieder erreichbar (max 30s)
|
||||
for (let i = 0; i < 15; i++) {
|
||||
await new Promise(r => setTimeout(r, 2000));
|
||||
try {
|
||||
await dockerExec("aria-core", "echo ok");
|
||||
log("info", "server", "aria-core ist wieder erreichbar");
|
||||
clientWs.send(JSON.stringify({
|
||||
type: "session_restarted", status: "ok",
|
||||
info: "aria-core neu gestartet — Permissions werden bei der naechsten Nachricht geladen",
|
||||
}));
|
||||
// Aktive Session beibehalten
|
||||
for (const c of browserClients) {
|
||||
c.send(JSON.stringify({ type: "active_session", sessionKey: activeSessionKey }));
|
||||
}
|
||||
return;
|
||||
} catch {}
|
||||
}
|
||||
clientWs.send(JSON.stringify({ type: "session_restarted", status: "timeout", error: "aria-core antwortet nicht nach 30s" }));
|
||||
} catch (err) {
|
||||
log("error", "server", `Session Restart fehlgeschlagen: ${err.message}`);
|
||||
clientWs.send(JSON.stringify({ type: "session_restarted", status: "error", error: err.message }));
|
||||
}
|
||||
}
|
||||
|
||||
// ── Brain Viewer ────────────────────────────────────────
|
||||
|
||||
async function handleListBrain(clientWs) {
|
||||
@@ -1401,6 +1453,8 @@ const OPENCLAW_SETTINGS_PATHS = [
|
||||
"/home/node/.openclaw/settings.json",
|
||||
"/home/node/.openclaw/agents/main/agent/settings.json",
|
||||
"/home/node/.openclaw/config.json",
|
||||
"/home/node/.claude/settings.json", // Claude Code User-Level
|
||||
"/home/node/.openclaw/workspace/.claude/settings.json", // Claude Code Projekt-Level
|
||||
];
|
||||
|
||||
async function findSettingsFile() {
|
||||
@@ -1479,41 +1533,67 @@ async function handleSavePermissions(clientWs, allowedTools) {
|
||||
try {
|
||||
log("info", "server", `Speichere ${allowedTools.length} Tool-Berechtigungen in alle Settings-Pfade`);
|
||||
|
||||
// Bestehende Settings lesen und mergen
|
||||
// Schreiben in ALLE moeglichen Pfade damit OpenClaw es sicher findet
|
||||
// In ALLE moeglichen Pfade schreiben, in BEIDEN Formaten:
|
||||
// 1. allowedTools: ["Bash", "Read", ...] — OpenClaw Format
|
||||
// 2. permissions.allow: ["Bash(*)", "Read(*)", ...] — Claude Code Format
|
||||
const script = [
|
||||
'const fs=require("fs");const path=require("path");',
|
||||
`const paths=${JSON.stringify(OPENCLAW_SETTINGS_PATHS)};`,
|
||||
`const tools=${JSON.stringify(allowedTools)};`,
|
||||
// Claude Code Format: Tool-Namen mit (*) Glob-Pattern
|
||||
'const ccAllow=tools.map(t=>t+"(*)");',
|
||||
'for(const f of paths){',
|
||||
'let s={};try{s=JSON.parse(fs.readFileSync(f,"utf8"));}catch(e){}',
|
||||
// OpenClaw Format
|
||||
's.allowedTools=tools;',
|
||||
// Claude Code Format
|
||||
'if(!s.permissions)s.permissions={};',
|
||||
's.permissions.allow=ccAllow;',
|
||||
's.permissions.deny=[];',
|
||||
'const dir=path.dirname(f);',
|
||||
'try{fs.mkdirSync(dir,{recursive:true});}catch(e){}',
|
||||
'fs.writeFileSync(f,JSON.stringify(s,null,2));',
|
||||
'}',
|
||||
// Verify: ersten Pfad zuruecklesen
|
||||
`const v=JSON.parse(fs.readFileSync(paths[0],"utf8"));`,
|
||||
'process.stdout.write(JSON.stringify(v.allowedTools||[]));',
|
||||
// Verify: alle Pfade zuruecklesen
|
||||
'const result={};',
|
||||
'for(const f of paths){',
|
||||
'try{const d=JSON.parse(fs.readFileSync(f,"utf8"));',
|
||||
'result[f]={allowedTools:d.allowedTools||[],permsAllow:d.permissions&&d.permissions.allow||[]};}',
|
||||
'catch(e){result[f]={error:e.message};}',
|
||||
'}',
|
||||
'process.stdout.write(JSON.stringify(result));',
|
||||
].join("");
|
||||
const b64 = Buffer.from(script).toString("base64");
|
||||
const verifyRaw = await dockerExec("aria-core", `echo ${b64} | base64 -d | node`);
|
||||
|
||||
// Verify: gespeicherte Daten mit gewuenschten vergleichen
|
||||
// Verify: gespeicherte Daten pruefen
|
||||
let verifyResult = {};
|
||||
let verified = false;
|
||||
let savedTools = [];
|
||||
let verifyDetails = [];
|
||||
try {
|
||||
savedTools = JSON.parse(verifyRaw.trim());
|
||||
verified = Array.isArray(savedTools)
|
||||
&& savedTools.length === allowedTools.length
|
||||
&& allowedTools.every(t => savedTools.includes(t));
|
||||
} catch {}
|
||||
verifyResult = JSON.parse(verifyRaw.trim());
|
||||
verified = true;
|
||||
for (const [fpath, data] of Object.entries(verifyResult)) {
|
||||
if (data.error) {
|
||||
verifyDetails.push(`${fpath}: FEHLER ${data.error}`);
|
||||
verified = false;
|
||||
} else {
|
||||
const ok = data.allowedTools.length === allowedTools.length
|
||||
&& allowedTools.every(t => data.allowedTools.includes(t));
|
||||
const ccOk = data.permsAllow.length === allowedTools.length;
|
||||
verifyDetails.push(`${fpath}: allowedTools=${ok?"OK":"FEHLER"} permissions.allow=${ccOk?"OK":"FEHLER"} (${data.allowedTools.length}/${data.permsAllow.length} Tools)`);
|
||||
if (!ok) verified = false;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
verifyDetails.push(`Parse-Fehler: ${e.message}`);
|
||||
}
|
||||
log("info", "server", `Verify:\n${verifyDetails.join("\n")}`);
|
||||
|
||||
if (!verified) {
|
||||
log("error", "server", `Verify fehlgeschlagen! Erwartet: ${JSON.stringify(allowedTools)}, Gelesen: ${verifyRaw}`);
|
||||
clientWs.send(JSON.stringify({
|
||||
type: "permissions_saved", ok: false,
|
||||
error: `Verify fehlgeschlagen — Datei wurde nicht korrekt geschrieben. Erwartet ${allowedTools.length} Tools, gelesen: ${savedTools.length}`,
|
||||
error: `Verify fehlgeschlagen:\n${verifyDetails.join("\n")}`,
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user