main
mula.liu 2026-03-10 19:04:49 +08:00
parent 94092c1a79
commit 85ff2fd17a
3 changed files with 32 additions and 2 deletions

View File

@ -352,12 +352,23 @@ def _is_panel_protected_api_path(path: str) -> bool:
"/api/health/cache",
}:
return False
# Bot-scoped APIs are protected by the bot's own access password only.
if _is_bot_panel_management_api_path(raw):
return True
# Bot-scoped content/chat APIs are protected by the bot's own access password only.
if _extract_bot_id_from_api_path(raw):
return False
return True
def _is_bot_panel_management_api_path(path: str) -> bool:
raw = str(path or "").strip()
if not raw.startswith("/api/bots/"):
return False
if not _extract_bot_id_from_api_path(raw):
return False
return raw.endswith("/start") or raw.endswith("/stop") or raw.endswith("/deactivate") or raw == f"/api/bots/{_extract_bot_id_from_api_path(raw)}"
@app.middleware("http")
async def bot_access_password_guard(request: Request, call_next):
if request.method.upper() == "OPTIONS":

View File

@ -22,6 +22,18 @@ server {
proxy_set_header X-Forwarded-Proto $scheme;
}
location /public/ {
proxy_pass http://nanobot_backend/public/;
proxy_http_version 1.1;
proxy_request_buffering off;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ws/monitor/ {
proxy_pass http://nanobot_backend/ws/monitor/;
proxy_http_version 1.1;

View File

@ -376,6 +376,8 @@ function workspaceFileAction(path: string): 'preview' | 'download' | 'unsupporte
const WORKSPACE_LINK_PREFIX = 'https://workspace.local/open/';
const WORKSPACE_ABS_PATH_PATTERN = /\/root\/\.nanobot\/workspace\/[^\s<>"'`)\],,。!?;:]+/gi;
const WORKSPACE_RELATIVE_PATH_PATTERN =
/(^|[\s(\[])(\/[^\s<>"'`)\]]+\.(?:md|markdown|json|txt|log|csv|tsv|yaml|yml|toml|html|htm|pdf|png|jpg|jpeg|gif|webp|svg))(?![A-Za-z0-9_./-])/gim;
function buildWorkspaceLink(path: string) {
return `${WORKSPACE_LINK_PREFIX}${encodeURIComponent(path)}`;
@ -403,11 +405,16 @@ function decorateWorkspacePathsForMarkdown(text: string) {
return `[${markdownPath}](${buildWorkspaceLink(normalized)})`;
},
);
return normalizedExistingLinks.replace(WORKSPACE_ABS_PATH_PATTERN, (fullPath) => {
const withAbsoluteLinks = normalizedExistingLinks.replace(WORKSPACE_ABS_PATH_PATTERN, (fullPath) => {
const normalized = normalizeDashboardAttachmentPath(fullPath);
if (!normalized) return fullPath;
return `[${fullPath}](${buildWorkspaceLink(normalized)})`;
});
return withAbsoluteLinks.replace(WORKSPACE_RELATIVE_PATH_PATTERN, (full, prefix: string, rawPath: string) => {
const normalized = normalizeDashboardAttachmentPath(rawPath);
if (!normalized) return full;
return `${prefix}[${rawPath}](${buildWorkspaceLink(normalized)})`;
});
}
function normalizeAttachmentPaths(raw: unknown): string[] {