Your Name
c570801119
fix: 编辑器拖拽修复 — 扩大拖拽区域+退出最大化+边界限制
...
问题:
- 标签栏整体被排除导致可拖拽区域几乎为零
- 最大化/全屏后拖拽不工作
- 没有拖拽视觉提示
修复:
- 添加⠿拖拽把手图标(cursor-grab)
- 只排除button/input/select, 标签栏空白处可拖拽
- 拖拽时自动退出最大化/全屏模式
- 边界限制(不拖出屏幕)
- 拖拽结束触发Monaco重新layout
2026-05-31 02:31:56 +08:00
Your Name
cba8b3d8f6
feat: 浮动编辑器 — 拖拽+缩放+全屏+文件树
...
功能:
- 拖拽: 按住标题栏拖动编辑器面板
- 缩放: 右下角拖拽调整大小
- 最大化(⬜ ): 占满屏幕留边距
- 全屏(⤢): 完全覆盖页面
- 最小化(—): 收到底部标签栏
- 关闭(✕): 关闭全部标签
- 文件树(🌳 ): 左侧可折叠文件树, 点击文件打开/目录导航
- 文件树同步: 浏览新目录时自动更新
布局:
┌──────────────────────────────────┐
│ [🌳 ] [📄 a.conf×][📄 b.py×] [⬜ ][⤢][—][✕] │ ← 可拖拽
├────────┬─────────────────────────┤
│ 📂 .. │ │
│ 📁 dir │ Monaco Editor │
│ 📄 a │ │
│ 📄 b │ │
│ │ Ln1,Col1|ini|UTF-8|file │
└────────┴─────────────────────────┘ ← 右下角可缩放
2026-05-31 02:26:25 +08:00
Your Name
caef4a216b
fix: Monaco配置完全对齐官方默认值
...
对齐项目:
- cursorBlinking: smooth→blink(官方默认)
- 移除: cursorSmoothCaretAnimation, cursorWidth(非官方默认)
- 移除: lineHeight, padding(非官方默认)
- 移除: renderLineHighlight, smoothScrolling(非官方默认)
- 移除: scrollbar自定义尺寸(使用官方默认)
- scrollBeyondLastLine: false→true(官方默认)
- renderWhitespace: selection→none(官方默认)
- 添加: fontFamily(Cascadia Code/Fira Code/JetBrains Mono)
- 移除: quickSuggestions, insertSpaces, foldingHighlight, minimap side/scale
- 保留vs-dark主题(匹配Nexus暗色UI)
2026-05-31 02:20:04 +08:00
Your Name
507b957b4e
refactor: 编辑器改为浮动面板 + Monaco配置对齐官方
...
布局:
- 全屏覆盖 → 右下角浮动面板(70vw×65vh)
- 文件列表始终可见, 编辑器不遮挡
- 最大化/还原按钮(⬜ )
- 最小化到底部标签栏
- 移除文件树(文件列表已在背景可见)
Monaco配置对齐官方demo:
- fontSize 13→14, lineHeight 20
- wordWrap on→off(水平滚动)
- 新增: folding, matchBrackets, cursorBlinking smooth
- 新增: cursorSmoothCaretAnimation, smoothScrolling
- 新增: padding, renderLineHighlight all, renderWhitespace selection
- 新增: suggestOnTriggerCharacters, quickSuggestions
- 新增: links, colorDecorators
- 新增: tabSize 4
2026-05-31 02:14:56 +08:00
Your Name
c70424a224
docs: Monaco IDE编辑器 changelog + 审计报告
2026-05-31 02:08:31 +08:00
Your Name
e8c1acba9f
fix: 审计8个FINDING修复 (IDE编辑器+终端)
...
- H-01 [MEDIUM] esc() 加引号转义('"\') 防止onclick XSS
- H-02 [MEDIUM] initialPath 路径白名单校验(仅允许字母数字/.-_)
- H-03 [LOW] doNewFile 文件名白名单正则(替代简单的includes('/'))
- H-08 [LOW] Monaco CDN SRI — 已知限制, 版本锁定@0.45.0
- H-13 [MEDIUM] showModal 移除已删除的modalTextarea引用
- H-20 [LOW] initialPath仅首次连接cd, 不影响恢复的标签
- H-26 [MEDIUM] esc()跨文件一致性 — files.html对齐terminal.html
- H-30 [LOW] esc()注释更新
2026-05-31 02:06:42 +08:00
Your Name
34786737b4
fix: IDE编辑器语法错误 — 多余花括号
2026-05-31 01:56:15 +08:00
Your Name
be633f3e58
feat: IDE编辑器重构 — 多标签+文件树+最小化+状态栏
...
Nexus CI/CD / test (push) Waiting to run
Nexus CI/CD / deploy (push) Blocked by required conditions
Nexus Pre-commit Checks / quick-check (push) Waiting to run
- 全屏IDE面板替代模态框编辑器
- 多文件标签页: 独立Monaco实例, 切换保持状态
- 左侧文件树: 基于当前目录, 点击文件打开, 点击目录导航
- 最小化/恢复: 底部最小化栏显示所有打开的文件标签
- 状态栏: 光标位置+语言+编码+未保存指示器
- Ctrl+S保存 + 未保存关闭确认
- 标签栏: 点击切换, ×关闭, amber色未保存标记
- 文件树同步: 浏览新目录时自动更新文件树
- 模态框保留用于非编辑操作(重命名/删除/新建等)
2026-05-31 01:50:34 +08:00
Your Name
00a3309005
feat: 服务器列表加「文件」按钮直达文件管理
...
- servers.html: renderActions 加「文件」链接(琥珀色) → /app/files.html?server_id=X
- files.html: 支持 server_id URL参数, 自动选中服务器并浏览 /www/wwwroot
2026-05-31 01:33:52 +08:00
Your Name
3d15200cfa
chore: 移除Monaco debug日志
2026-05-31 01:28:57 +08:00
Your Name
d8aca5bf18
fix: Monaco预加载移入files.html(解决api.js缓存问题)
2026-05-31 01:26:59 +08:00
Your Name
cb60af4483
debug: Monaco preload 加日志诊断
2026-05-31 01:22:45 +08:00
Your Name
5a5adafb39
feat: Monaco编辑器+右键菜单+排序筛选+chmod+压缩解压+新建文件
...
编辑器增强:
- E-2 Monaco集成: 70vh全屏编辑器, 暗色主题, bracket着色
- E-3 Ctrl+S保存快捷键 + 未保存指示器
- E-4 语言自动检测(30+扩展名映射)
- Monaco预加载: 登录后CDN后台加载, 打开编辑器秒开
- fallback: Monaco未就绪时退回textarea
文件管理增强:
- F-1 右键菜单: 预览/下载/重命名/权限/复制路径/终端/压缩/解压/删除
- F-2 新建文件按钮(📄 +)
- F-3 chmod权限修改(右键→输入权限如755)
- F-4 排序切换(名称/大小/时间)
- F-5 文件类型筛选下拉(.conf/.log/.sh/.py等)
- F-6 压缩(tar.gz)
- F-7 解压(tar.gz/zip)
2026-05-31 01:10:22 +08:00
Your Name
c0296b9d8e
fix: 预加载文件大小 30KB → 1MB
2026-05-31 01:04:44 +08:00
Your Name
ca4aceba3e
fix: 面包屑点击事件委托 — 作用域不在fileListEl内
...
面包屑(#breadcrumbPath)和文件列表(#fileList)是兄弟节点, 不是父子关系
事件委托绑在fileListEl上无法捕获面包屑点击
修复: 给#breadcrumbPath加独立click事件委托
2026-05-31 00:57:58 +08:00
Your Name
b5dfa8a870
feat: 文件管理器集成SSH终端
...
- files.html: 工具栏加「🖥 终端」按钮(绿色),点击在新标签页打开SSH终端
- files.html: openTerminal() 传递 server_id + 当前路径到 terminal.html
- terminal.html: 支持 path URL参数,连接成功后自动 cd 到指定目录
- 打开方式: /app/terminal.html?server_id=8&path=/www/wwwroot
- 右键菜单也会集成「打开终端」选项
2026-05-31 00:53:00 +08:00
Your Name
17cdc96bb0
feat: 文件预加载+缓存 — 双击秒开编辑器
...
- api.js: Monaco编辑器CDN预加载(登录后后台加载)
- files.html: 文件内容预加载(目录浏览后自动预读≤30KB文本文件)
- files.html: 文件缓存(_fileCache), 双击已缓存文件直接打开
- files.html: 切换服务器时清空缓存
- 预加载策略: 最多10个文件, 仅文本类型, ≤30KB
2026-05-31 00:46:04 +08:00
Your Name
6012af0b4d
fix: 双击编辑器冲突 — 延迟区分单击/双击
2026-05-31 00:25:02 +08:00
Your Name
9bdf7e420f
feat: 文件管理器4项改进
...
1. 切换服务器自动重置路径为 /www/wwwroot
2. 默认目录 /www/wwwroot(而非根目录 /)
3. 双击文件打开编辑器(doPreview textarea模态框)
4. 双击目录进入目录(browseDir)
2026-05-31 00:17:22 +08:00
Your Name
40d672fdbb
fix: 面包屑双斜杠bug (/tmp显示为//tmp)
2026-05-31 00:11:47 +08:00
Your Name
557c8d28c1
docs: files迭代审计报告
2026-05-30 23:46:12 +08:00
Your Name
9f7be66356
fix: 审计5个FINDING修复 (files迭代)
...
- H-15 [MEDIUM] download端点加100MB大小限制
- H-02 [LOW] Content-Disposition filename sanitize(替换特殊字符)
- H-12 [LOW] FileDownload/FileRead/FileWrite path加max_length=4096
- H-27 [LOW] doPreview保存失败解析错误详情显示detail
- H-29 [INFO] esc()函数加注释说明用途
- H-01 [HIGH] 远程路径限制 — ACCEPTED_RISK(用户明确决策)
2026-05-30 23:44:35 +08:00
Your Name
ac38442383
docs: files.html 全面迭代 changelog
2026-05-30 23:36:49 +08:00
Your Name
14131f98f0
feat: files.html 全面迭代 — 15项改进
...
安全+后端:
- P2-1 符号链接解析(l权限检测+name/target分离)
- P2-7 新增 /api/sync/download 端点(SFTP流式下载)
- P2-8 新增 /api/sync/read-file + /write-file 端点(base64编码避免shell注入)
前端全面重写:
- P1-1 目录删除二次确认(自定义模态框+输入目录名)
- P2-2/2-3 事件委托替代内联onclick(data-action+data-path)
- P2-4 上传进度条(XHR.upload.onprogress)
- P2-5 文件大小可读化(B/KB/MB/GB)
- P2-6 文件类型图标(30+扩展名映射)
- P2-7 下载按钮+逻辑
- P2-8 文件预览/编辑弹窗(读取+修改+保存)
- P2-9 自定义模态框替代prompt/confirm
- P2-10 批量选择+批量删除(checkbox+全选+底部操作栏)
- P3-1 文件名搜索框(前端实时过滤)
- P3-2 符号链接🔗 图标+target tooltip
- P3-3 空目录状态(图标+上传引导按钮)
- P3-4 服务器刷新按钮
- P3-5 操作loading状态(进度条) 2>&1
2026-05-30 23:34:24 +08:00
Your Name
64503c0260
fix: IP校验改用endpoint级HTTPException替代Pydantic validator
...
model_validator/field_validator在自定义RequestValidationError handler下
无法正确序列化为JSON,导致500。改用endpoint级_validate_ip_list()辅助函数
抛HTTPException(400),避免Pydantic→FastAPI序列化链路问题。
2026-05-30 22:48:41 +08:00
Your Name
d19f5af807
fix: IP格式校验用field_validator替代model_validator
...
model_validator(mode='after')抛出ValueError时FastAPI不能正确序列化为422
→ 导致500 TypeError: Object of type ValueError is not JSON serializable
改用field_validator(mode='before')由Pydantic正常捕获返回422
2026-05-30 22:44:26 +08:00
Your Name
463841a740
docs: settings安全加固审计报告
2026-05-30 22:35:40 +08:00
Your Name
36fde6e6ed
fix: 审计7个FINDING修复
...
Nexus CI/CD / test (push) Waiting to run
Nexus CI/CD / deploy (push) Blocked by required conditions
Nexus Pre-commit Checks / quick-check (push) Waiting to run
- F-1 [MEDIUM] IpAllowlistSaveRequest 加 IP/CIDR/域名格式校验
- F-2 [MEDIUM] _is_private_host 改为 async DNS 解析 (不再阻塞事件循环)
- F-3 [LOW] hot-reload int转换失败改 logger.warning 而非静默pass
- F-4 [LOW] 提取 _verify_reauth 辅助函数,消除4处重复re-auth代码
- F-5 [LOW] ChangePasswordRequest.totp_code 加 min_length=6 约束
- F-6 [LOW] revealTelegramToken 空catch改 console.error+toast
- F-7 [LOW] toggleApiKeyVisibility 空catch改 console.error+toast
2026-05-30 22:34:45 +08:00
Your Name
1a61fae590
docs: settings 安全加固+UX迭代 changelog
2026-05-30 22:02:45 +08:00
Your Name
a50f17941d
fix: settings 安全加固 + UX 迭代 — 10项修复
...
安全修复:
- S-01 SSRF: parse-subscription 加私有IP封禁+重定向限制+响应大小限制
- S-02 值校验: PUT /{key} 加 key 白名单 + INT 范围校验(1-1000/1-100/10-600)
- S-05 重登录: 改密码成功后跳转login.html+绿色提示
- S-07 审计: add_manual_ips/remove_allowlist_ip 补全审计日志
- S-09 TOTP: 已启用TOTP时改密码需输入验证码
UX改进:
- UX-01: 密码框focus ring + 设置项input type映射(number/url/text)
- UX-02: 改密码按钮loading状态(disabled+提交中...)
- UX-03: 3处空catch块→console.error+toast
- UX-04: 保存失败时reloadSettings恢复原值
- UX-05: IP格式校验(前端正则+后端Pydantic model_validator)
2026-05-30 21:58:13 +08:00
Your Name
362b28199f
docs: settings 巡检 + Bot Token 脱敏 changelog
2026-05-30 21:18:34 +08:00
Your Name
5213def150
fix: Telegram Bot Token 脱敏 — GET 不返回明文,reveal 需密码验证
...
- 后端 SENSITIVE_KEYS 加入 telegram_bot_token,GET /settings/ 返回脱敏值
- 新增 POST /settings/telegram/reveal-token 端点(密码验证 + 审计日志)
- 前端 Telegram 区域独立渲染:Bot Token 默认脱敏,点"显示"需输入密码
- Chat ID 保持可编辑(非敏感信息)
- Bot Token 输入框默认 type=password,可切换明文/遮掩
2026-05-30 21:12:41 +08:00
Your Name
5166660f3a
fix: GET /api/settings/ip-allowlist 被 /{key} 路由拦截 → 404
...
/{key} 路由在 ip-allowlist 之前定义,FastAPI 将 ip-allowlist
当作 setting key 查找,找不到返回 404。
修复:将 GET /ip-allowlist 路由移到 /{key} 之前(FastAPI 路由优先级)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-05-30 20:42:42 +08:00
Your Name
48ef06babb
chore: gitignore 添加 MCP 工具目录 + 清理测试截图
...
- .megamemory/ (知识图谱)
- .playwright-mcp/ (浏览器状态/截图)
- tmp/ (临时文件)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-05-30 20:39:47 +08:00
Your Name
ede7fbaa64
fix: settings PUT 后热更新内存 — 无需重启即生效
...
问题:修改 Telegram 等设置后需要重启服务器才能生效,
因为 load_settings_from_db() 只在启动时运行。
修复:PUT /api/settings/{key} 写入 DB 后,
同步更新 settings 内存对象(DB_OVERRIDE_MAP 映射 + INT_SETTINGS 类型转换)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-05-30 20:28:51 +08:00
Your Name
4c4d41b8f5
docs: add changelog and audit for ruff cleanup
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-05-30 20:10:28 +08:00
Your Name
32feb1b6db
fix: 全站 ruff 清零 — 77 errors → 0
...
Fixes:
- F821: install.py site_url 未定义(NameError)、sync_v2.py os 未导入、script_jobs.py LOG f-string
- F401: 移除 22 个未使用导入(models/__init__.py、install.py、auth.py 等)
- B904: 20 个 except 块 raise 添加 from e/from None
- S110: 20 个有意的 try-except-pass 添加 noqa 注释(SSH清理/DDL幂等/WS断连)
- B007: 3 个未使用循环变量重命名(dirs→_dirs、server_id→_server_id)
- F541: 3 个无占位符 f-string 修正
- F841: auth.py 未使用 ip_address 变量移除
- S105: auth_service.py Redis key prefix 误报 noqa
- B023: script_execution_flush.py 循环变量绑定修复
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-05-30 20:07:45 +08:00
Your Name
ebe276ea29
docs: add changelog and audit for servers iteration
...
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-05-30 19:50:07 +08:00
Your Name
84282e87ae
feat: servers list iteration — server-side pagination/search/sort/status filter
...
Backend:
- server_repo.py: get_paginated() adds search/sort_by/sort_order/is_online params
with whitelist-validated sorting and DB-level pagination
- servers.py: list_servers() adds search/sort_by/sort_order/is_online Query params
with Redis post-filter for is_online accuracy
- servers.py: fix all 12 pre-existing ruff errors (unused imports, B904, S110, F541)
- servers.py: fix F821 bug — agent_port undefined in upgrade_agent()
Frontend:
- servers.html: complete rewrite with server-side pagination, debounced search,
clickable column sorting, status filter dropdown, auto-refresh toggle,
keyboard shortcuts (↑↓/jk/Esc//r), CSV export, skeleton loading,
empty state with contextual hints, pagination controls (first/prev/nums/next/last)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-05-30 19:45:53 +08:00
Your Name
de8d860244
fix: handle legacy agent heartbeat without server_id + migrate on_event to lifespan
...
- AgentHeartbeat.server_id changed to Optional[int] — missing server_id
now returns 200 (discarded) instead of 422, stopping retry loops
- web/agent/agent.py: on_event("startup") → FastAPI lifespan pattern
- Added exponential backoff on consecutive heartbeat failures (cap 5min)
- Agent stops heartbeat loop on "discarded" response from central
- main.py: promoted temporary debug 422 handler to production-grade
- uninstall.sh: added legacy agent cleanup (pkill patterns, crontab,
/opt/multisync-agent path)
- Confirmed servers.html batch buttons work correctly (disabled state
is correct when no agents installed)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-30 18:20:14 +08:00
Your Name
3f50a40d25
feat: Agent 安装/卸载/升级脚本全面迭代
...
install.sh:
- 新增 Step 0:停旧服务 + 杀端口占用(fuser/ss/netstat 兜底)
- 修正步骤编号 [1/5] → [0/7]
- pip 依赖版本提取为脚本顶部变量,方便统一维护
uninstall.sh:
- 加 pkill 杀残留 Agent 进程
- 加 fuser 杀端口占用
- 清理 /etc/sudoers.d/nexus-agent 残留
- root 用户跳过 sudo 前缀
_sudo_wrap:
- NOPASSWD 命令白名单替代 ALL=(ALL)(仅 systemctl/apt/yum/rm 等)
- 降低 SSH 超时后 sudoers 残留的风险
升级 API:
- restart 前加 fuser -k 杀端口占用(单台+批量)
- install_agent_remote 检查 stdout 中的 FAILED 标记
卸载后清理:
- 清空 agent_api_key(之前只清 agent_version)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-30 16:11:09 +08:00
Your Name
dc48f71b25
feat: 创建 Agent 卸载脚本 uninstall.sh
...
之前卸载功能调用了不存在的 uninstall.sh,导致 404 下载失败。
脚本功能:停止 systemd 服务 → 禁用并删除 unit → 删除 /opt/nexus-agent → 删除日志
支持非 root 用户(自动检测 sudo 权限)。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-30 14:35:33 +08:00
Your Name
913fd16bb9
fix: Agent 升级命令添加 sudo 前缀(非 root 用户)
...
systemctl restart 需要 root 权限,非 root SSH 用户必须加 sudo。
之前 _sudo_wrap 只设置了免密 sudoers 但命令本身没带 sudo,
导致升级时 "Interactive authentication required" 失败。
同时修复单台升级和批量升级的 rollback 命令。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-30 14:28:49 +08:00
Your Name
deffa8a8f4
fix: AppAuthMiddleware 验证 refresh token 格式而非 JWT 解码
...
refresh token 是 opaque 格式 (token:admin_id:token_version),不是 JWT。
之前用 pyjwt.decode() 验证必然失败,导致所有登录用户访问 /app/ 都返回 404。
改为验证格式合法性(3段、admin_id>0、token_version>=0)。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-30 05:10:39 +08:00
Your Name
64a8a18287
fix: refresh cookie path 改为 /,修复 AppAuthMiddleware 读不到 cookie
...
REFRESH_COOKIE_PATH 从 /api/auth 改为 /,这样浏览器访问 /app/ 页面时
也会发送 nexus_refresh cookie,AppAuthMiddleware 才能正确验证登录状态。
同时包含之前的 AppAuthMiddleware 定义顺序修复和 422 调试日志。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-30 05:08:21 +08:00
Your Name
cc0ca47d61
debug: 422 handler 简化 — 只记录 errors 和 content_type,不读 body
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-30 03:09:30 +08:00
Your Name
449373f24f
debug: 添加 422 验证错误日志 — 记录请求体和验证错误详情
...
诊断 Agent 心跳 422 问题,临时捕获请求体内容。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-30 03:05:30 +08:00
Your Name
730b665306
fix: AppAuthMiddleware 类定义移到 add_middleware 调用之前
...
Nexus CI/CD / test (push) Waiting to run
Nexus CI/CD / deploy (push) Blocked by required conditions
Nexus Pre-commit Checks / quick-check (push) Waiting to run
Python 模块级代码顺序执行,类必须先定义再引用。
之前 add_middleware(AppAuthMiddleware) 在第404行但类定义在第495行,
导致 NameError 服务启动失败。同时修复 _is_install_mode → is_install_mode。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-30 03:01:08 +08:00
Your Name
f5bea6f0d2
fix: AppAuthMiddleware add_middleware 重新加回
2026-05-30 02:46:11 +08:00
Your Name
c808c28edf
fix: 移除错误的 AppAuthMiddleware add_middleware(类定义在后面)
...
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-30 02:45:19 +08:00