Merge pull request 'fix: clarify blocked security events' (#29) from dev into main
Deploy Dashboard / deploy (push) Successful in 48s

This commit was merged in pull request #29.
This commit is contained in:
2026-03-07 11:48:36 +08:00
3 changed files with 52 additions and 4 deletions
+7 -4
View File
@@ -16,6 +16,7 @@ RUN apt-get update \
python3 \
ripgrep \
rsync \
tmux \
unzip \
wget \
zip \
@@ -31,20 +32,22 @@ RUN npm install -g @anthropic-ai/claude-code
RUN python3 - <<'PY'
from pathlib import Path
import re
path = Path("/usr/local/lib/node_modules/@anthropic-ai/claude-code/cli.js")
if not path.exists():
raise SystemExit(f"claude cli not found: {path}")
content = path.read_text()
old = 'F8.get("https://api.anthropic.com/api/hello",{headers:K8($)}).catch((()=>!1))'
if old not in content:
pattern = r'let A=U7\(\),q=new URL\(A\.TOKEN_URL\),K=\[`\$\{A\.BASE_API_URL\}/api/hello`,`\$\{q\.origin\}/v1/oauth/hello`\],Y=async\(_\)=>\{try\{let \$=await I8\.get\(_,\{headers:\{"User-Agent":ey\(\)\}\}\);if\(\$\.status!==200\)return\{success:!1,error:`Failed to connect to \$\{new URL\(_\)\.hostname\}: Status \$\{\$\.status\}`\};return\{success:!0\}\}catch\(\$\)\{'
replacement = 'return'
patched, count = re.subn(pattern, replacement, content, count=1)
if count != 1:
raise SystemExit("preflight patch target not found in claude cli; refusing to build")
patched = content.replace(old, "!0")
path.write_text(patched)
if old in path.read_text():
if re.search(pattern, path.read_text()):
raise SystemExit("preflight patch did not apply cleanly")
print("Applied Claude preflight bypass patch")
+1
View File
@@ -13,4 +13,5 @@ rsync
zip
unzip
make
tmux
claude
+44
View File
@@ -16,6 +16,21 @@
import { onMount } from "svelte";
import { getToken, checkAuth, setToken, setRefreshToken, currentUser, setCurrentUser, getPreferences, savePreferences } from "./lib/api.js";
const KNOWN_PAGES = new Set([
"dashboard",
"docker",
"gitea",
"files",
"terminal",
"openclaw",
"chat-digest",
"settings",
"security",
"litellm",
"cc-connect",
"info-engine",
]);
let page = $state("dashboard");
let dark = $state(false);
let sidebarOpen = $state(false);
@@ -27,6 +42,26 @@
let sidebarOrder = $state(null);
let orderSaveTimer = null;
function getRequestedPage() {
const requestedPage = new URLSearchParams(window.location.search).get("page");
return KNOWN_PAGES.has(requestedPage) ? requestedPage : null;
}
function canOpenPage(pageId) {
if (!pageId || !KNOWN_PAGES.has(pageId)) return false;
if (pageId === "settings") return userRole === "admin";
if (["litellm", "cc-connect", "info-engine"].includes(pageId)) return hasPageAccess("dashboard");
return hasPageAccess(pageId);
}
function syncPageQuery(pageId) {
const url = new URL(window.location.href);
if (pageId === "dashboard") url.searchParams.delete("page");
else url.searchParams.set("page", pageId);
if (pageId !== "terminal") url.searchParams.delete("host");
history.replaceState({}, "", `${url.pathname}${url.search}${url.hash}`);
}
async function fetchUserInfo() {
try {
const data = await checkAuth();
@@ -78,6 +113,8 @@
setRefreshToken(data.refresh_token);
authorized = true;
await fetchUserInfo();
const requestedPage = getRequestedPage();
if (canOpenPage(requestedPage)) page = requestedPage;
loading = false;
return;
}
@@ -96,6 +133,8 @@
try {
await fetchUserInfo();
authorized = true;
const requestedPage = getRequestedPage();
if (canOpenPage(requestedPage)) page = requestedPage;
} catch (e) {
console.error("Auth check failed:", e);
setToken("");
@@ -105,6 +144,11 @@
}
});
$effect(() => {
if (!authorized || loading || !canOpenPage(page)) return;
syncPageQuery(page);
});
function toggleTheme() {
dark = !dark;
if (dark) {