Commit Graph

38 Commits

Author SHA1 Message Date
Nexus Agent 722917bfc9 fix(api): API 全量巡检 B1–B6 修复 server_ids 上限与 pending 审计
限制健康检查/推送/脚本执行的 server_ids 规模,补齐 pending 重试失败与删除审计,并附分批巡检报告。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 23:57:46 +08:00
Nexus Deploy 4ba45abf38 feat(servers): 凭据轮询登录与连接失败列表
- 密码/SSH密钥预设增加用户名;快速添加(IP)轮询全部预设尝试 SSH 登录
- 成功入 servers 列表;失败写入 pending_servers 并支持重试/删除
- 新增 credential_poller、try_ssh_login 与 add-by-ip/pending API
2026-06-06 20:08:48 +08:00
Nexus Deploy a2ae74d582 release: BUG fixes batch 1-6, full bug scan docs, Ubuntu/Linux dev
- Backend: auth refresh reuse, schedule/retry/sync/agent/files fixes
- Frontend: push WS, files ETag browse, vite build assets
- Docs: audit/changelog, production deploy gate, bug scan registry B7-77
- Deploy: deploy-production.sh, prune assets, gate logs
2026-06-04 14:01:14 +08:00
Your Name 67dac0168f feat: 文件管理器复制粘贴守卫、2MB编辑限制、一键配置sudoers、编辑器外观重构
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 02:20:22 +08:00
Your Name 832e34fd98 fix: 修复 6 个 MEDIUM 级 Bug (锁定/重试/调度/分页/SSH池/token_version)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 01:29:06 +08:00
Your Name d93c518a14 feat(files): POSIX paths, elevation, recursive chmod, access hints and docs
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-01 19:54:18 +08:00
Your Name 6183047fd6 fix: 全站 bug 审查修复 (前端9项 + 后端5项)
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
前端修复:
- P0: App.vue http 未导入导致全局搜索崩溃
- P1: TOTP 登录流程断裂 (TotpRequiredError 非 ApiError 子类)
- P1: ServersPage 编辑服务器 domain 被端口字符串污染
- P1: PushPage Set[0] 无效 → values().next().value
- P1: SettingsPage API 返回字符串未转数字
- P2: api/index.ts getList 重复定义移除
- P2: LoginPage 锁定倒计时 now ref + watch 更新
- P2: TerminalPage 路径验证正则放松 (允许空格/中文)
- P2: useWebSocket CONNECTING/CLOSING 状态关闭旧连接

后端修复:
- P1: websocket.py redis.keys() → scan_iter() 避免阻塞
- P1: auth_service.py TTL 仅在 key 无 TTL 时设置
- P1: servers.py 批量操作加 asyncio.Lock 避免并发 session commit
- P2: settings.py asyncio.get_event_loop() → get_running_loop()
- P2: settings.py datetime.utcfromtimestamp() → datetime.fromtimestamp(tz=utc)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 11:24:55 +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 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 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 ac66f5b4e7 fix: 卸载Agent后清除Redis心跳(之前只清MySQL导致在线状态残留)
卸载Agent后只更新MySQL is_online=False,但前端读Redis覆盖为True。
修复: uninstall_agent_remote + batch_uninstall_agent 都增加redis.delete(heartbeat:{id})

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 23:57:06 +08:00
Your Name 6dd0b487b7 fix: install.sh 和 upgrade_agent 增加 rsync 自动安装
推送功能依赖目标服务器安装 rsync,但 install.sh 仅安装 Python 包。
现在 install.sh 步骤2/6检测并自动安装 rsync(apt/yum/dnf)。
upgrade_agent / batch_upgrade_agent 流程中也增加 rsync 检测,
已有服务器点击"升级 Agent"即可自动补装 rsync。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 23:45:01 +08:00
Your Name 82c297776a feat: 推送页面 5 项迭代 — WS实时进度 + 分组选择 + 历史增强 + 文件操作 + 推送校验
F1: broadcast_sync_progress() + batch_id + 前端WS逐台更新
F2: get_paginated() platform_id/node_id + /categories端点 + 筛选下拉框
F4: _sync_log_to_dict() 补全字段 + diff_summary捕获 + 可展开详情面板
F7: /local-file-ops端点 + 文件管理器删除/重命名
F8: /verify端点 md5sum对比 + 推送后校验UI

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 21:01:27 +08:00
Your Name 77b332c037 fix: 远程安装按钮修复 + install.sh sudo/venv兼容 + api_base_url管理
- 修复详情面板"远程安装"按钮始终禁用:s._base_url 改为从新API获取全局API_BASE_URL
- 新增 GET /api/servers/meta/api_base_url 端点
- api_base_url 加入 DB_OVERRIDE_MAP + 启动迁移逻辑
- install.sh 非 root 用户自动 sudo 检测 + NOPASSWD 配置
- 后端 _sudo_wrap 辅助函数应用于 4 个 Agent 操作端点
- install.sh venv 创建加 || true 兼容 set -e(缺 python3-venv 不再直接退出)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 14:33:19 +08:00
Your Name fd9b7d85b5 fix: 批量安装按钮检测 + 审计日志中文化 + terminal断开反馈
1. updateBatchBar() hasAgent 判断从 agent_api_key_set 改为 agent_version
2. 所有后端 AuditLog detail 字段统一中文
3. audit.html 操作/目标类型中文映射
4. terminal.html 断开覆盖层 + 重新连接按钮
5. Agent os_release 上报 + 前端系统版本拆分

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 02:17:35 +08:00
Your Name 869f64ac18 Fix install.sh venv robustness + batch install API error reporting
install.sh: detect incomplete venv (missing activate), auto-install
python3-venv and retry instead of silently failing.

servers.py batch install: preserve server_name on exception, detect
"Status: FAILED" in stdout, return error details when stderr is empty,
increase SSH timeout to 180s.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 00:53:00 +08:00
Your Name 1c70e597a3 Fix Agent install 404 + add command input bar + fix install pipe error hiding
1. Mount /agent/ static files for install.sh/agent.py (was 404)
2. Replace curl|bash pipe with temp-file download to catch curl errors
3. Add command input bar to terminal.html bottom
4. Fix terminal CSS layout for flex with command bar

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 22:57:32 +08:00
Your Name a1b0b2c514 feat: Terminal sidebar+panel, SSH key fix, auth cleanup, pre-deploy gates
- terminal.html: left sidebar (default open), right server panel with server list
- servers.py: fix SSH key double-encryption in update_server, auth method switch cleanup
- servers.html: auth switch clears opposite credentials (key↔password)
- deploy/pre_deploy_check.sh: 3-gate pre-deploy check (changelog/audit/test)
- mcp/Nexus_server.py: deploy() runs gate check before git pull+restart
- docs/audit/: audit record template + today's audit results
- CLAUDE.md: add gate enforcement rules and progress bar discipline

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-26 09:16:05 +08:00
Your Name fb4e51ec5a fix: move static routes before /{id} to fix route conflict
/batch/install-agent, /batch/upgrade-agent, /import, and
/import/template were registered after /{id}, causing FastAPI
to match 'batch' and 'import' as the {id} parameter.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-26 00:25:25 +08:00
Your Name 8cd091add8 feat: CSV batch import, SFTP upload, batch Agent operations
Add three missing frontend management features:
1. Server CSV import (POST /api/servers/import) with injection prevention
2. SFTP file upload (POST /api/sync/upload) with path traversal protection
3. Batch Agent install/upgrade with Semaphore concurrency control

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-26 00:17:43 +08:00
Your Name ccb78ed980 feat: SSH key preset system — dropdown + backend auto-resolve
- Add SshKeyPreset model + repo (encrypted_private_key, public_key)
- Add ssh_key_preset_id to Server model + schemas
- Add CRUD + reveal API routes (/api/ssh-key-presets/)
- servers.py: auto-resolve ssh_key_preset_id → decrypt → set ssh_key_private
- servers.html: key preset dropdown in key auth section, hides path/textarea on select
- Mirror password preset pattern: zero frontend credential exposure

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-25 22:49:57 +08:00
Your Name cdd0be328a fix: 六轮深度扫描 — 47项Bug修复、安全加固、死代码清理
Critical runtime bugs:
- terminal.html WebSSH完全不可用(URL前缀/JSON解析/Content-Type三处错误)
- servers.py路由遮蔽:/logs被/{id}拦截,3个前端页面同步日志查询失败
- scripts.html startExecPoll()→startExecPolling(),长任务快速执行崩溃
- agent.py {value!r!s:.50}格式串非法,agent发非数值时ValueError
- alerts.html d.daily.reduce()无null检查,API返回空数据时TypeError

Resource leak / stability:
- websocket.py僵尸连接未关闭TCP,文件描述符泄漏
- websocket.py _last_alert_time字典无限增长(加1小时过期清理)
- asyncssh_pool.py全忙时超过MAX_CONNECTIONS无限增长
- self_monitor.py Telegram告警无冷却,宕机时每30秒刷屏
- schedule_runner.py一次性调度执行超60秒会重复触发
- 限速脚本EXPIRE每次重置窗口可绕过(改用Lua原子脚本)

Security:
- JWT access token加token_version声明,改密码后旧token立失效(零宽限)
- INSTALL_MODE导入时常量→动态函数,安装后JWT认证不再残留禁用
- install.py /lock端点加管理员存在性验证,防止阻断安装
- ServerUpdate schema移除connectivity只读字段,防止伪造连接状态

Frontend fixes:
- doExec()缺r.ok检查、commands.html null检查
- _server_to_dict()补last_checked_at+ssh_key_public
- _field_match()逗号cron表达式修复
- alerts类型显示、SSH会话名称、搜索高亮定位
- 一次性/循环定时任务(run_mode+fire_at+自动禁用)

Dead code removed (400+ lines):
- SyncService batch_push/_push_single等5个方法(零调用者)
- 5个未使用schema(SyncCommands/SyncConfig/SyncSftp/FileDeploy/PaginatedResponse)
- 6个零调用service方法、3个无前端API端点
- 4个未使用import

Schema migrations:
- push_schedules: run_mode + fire_at列,cron_expr改NULL
- servers: 7个新列 + ssh_key_private/public VARCHAR(500)→TEXT

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-24 16:26:40 +08:00
Your Name 9bba58a529 feat: Telegram test+ChatID, Agent IP allowlist/upgrade, alert history page
Telegram:
- POST /api/settings/telegram/test: send test message (checks token+chat_id)
- GET /api/settings/telegram/chats: call getUpdates, return up to 5 chats
- settings.html: test button + detect chat IDs with click-to-fill

Agent IP allowlist (web/agent/agent.py):
- allowed_ips config: list of trusted IPs/CIDRs from config.json
- _ip_allowed(): checks exact IP, CIDR (ipaddress module), hostname
- verify_api_key(): now checks IP allowlist before API key
- /health: also checks IP allowlist
- install.sh: auto-extracts central server IP from --url, adds to allowed_ips

Agent auto-upgrade (server/api/servers.py):
- POST /api/servers/{id}/upgrade-agent: SSH → curl new agent.py → systemctl restart
- servers.html: 升级 Agent button in Agent tab (only when online)

Alert history (new page):
- domain/models: AlertLog table (server_id, type, value, is_recovery, created_at)
- migrations.py: CREATE TABLE IF NOT EXISTS alert_logs
- websocket.py: _save_alert_log() called from broadcast_alert/recovery
- settings.py: GET /api/alert-history/ (paginated, filters), GET /stats
- main.py: register alert_history_router
- alerts.html: new page with stats cards, top-servers bar chart, alert list
- layout.js: 🔔 告警中心 added to sidebar nav

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-23 18:27:12 +08:00
Your Name d2832567c7 feat: push logs view in commands.html + paginated sync log API
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
sync_log_repo.py:
- get_all_paginated(): server_id/status/sync_mode/trigger_type filters +
  server name JOIN + total count for pagination

server/api/servers.py GET /servers/logs:
- Add server_id/status/sync_mode/trigger_type/offset/limit query params
- Return {items, total, offset, limit} instead of plain list

web/app/commands.html (renamed title to '操作日志'):
- Third view: '推送日志' with paginated table
- Columns: 状态(dot badge) / 服务器 / 模式 / 触发方式 / 源路径 /
  目标路径 / 文件数 / 耗时 / 操作人 / 开始时间
- Filters: 服务器 + 状态(success/failed/running) + 模式 (incremental/full/...)
- Pagination controls with prev/next page (50 per page)
- Error message in row title attribute (hover for details)

web/app/push.html:
- Update loadHistory() to handle new {items, total} response format

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-23 17:20:53 +08:00
Your Name 14dc29f241 feat: Agent install tab with copy command + one-click remote install via SSH
server/api/servers.py:
- POST /{id}/install-agent: SSH-execute install.sh on managed server using
  stored credentials; requires API_BASE_URL + agent_api_key; 120s timeout
- GET /{id}/agent-install-cmd: return pre-filled curl command for copy-paste

web/app/servers.html:
- New 'Agent 安装' tab in server detail panel
  - Shows Agent online/offline status badge
  - Warns if NEXUS_API_BASE_URL or API Key is missing
  - Displays ready-to-copy curl install command with port auto-filled
  - ' 一键远程安装' button (SSH exec): disabled if already online
  - Scrollable install log output panel
  - Tab uses shared showDetailTab() + loadAgentInstall() / remoteInstallAgent()
- Explains: script auto-installs Python, downloads agent.py, writes config,
  sets up systemd, opens firewall port

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-23 17:16:14 +08:00
Your Name 9c063a788f feat: time drift detection between agent and central server
Agent (web/agent/agent.py):
- Heartbeat now includes system_info.agent_time (UTC ISO string)

Central (server/api/agent.py):
- On each heartbeat, compare agent_time vs central datetime.now(utc)
- Thresholds: warn >= 30s, crit >= 60s (affects TOTP/cron accuracy)
- Stores time_drift_seconds + drift_level in Redis heartbeat key
- Sends Telegram alert (5-min cooldown) when drift >= 60s critical

API (server/api/servers.py):
- List and detail endpoints expose time_drift_seconds + drift_level from Redis

Frontend (web/app/servers.html):
- driftBadge(): shows clock emoji badge next to server name
  - amber badge: >=30s (warn)
  - red badge: >=60s (crit)
  - tooltip shows exact drift and NTP check hint
  - no badge when drift < 30s or no data

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-23 17:04:34 +08:00
Your Name 752a24497c feat: Phase 2 security audit fixes + script execution platform
Security (P0/P1/P2):
- WebSSH: dedicated short-lived token, server_id binding, 4003 close code
- Remove /api/agent/exec from control plane (RCE surface eliminated)
- Global JWT middleware (JwtAuthMiddleware) with install-mode bypass
- decrypt_value: failure returns None, never leaks ciphertext
- Telegram: sanitize_external_message strips sensitive fields
- Agent auth: startup enforces non-empty API key, compare_digest
- Credentials: password_set bool flag, no plaintext in API responses
- audit_log: writes admin_username + ip_address on all CUD ops
- Install lock: all /api/install/* except GET /status return 403 post-install
- WebSocket dedup: publish once, subscribers deliver locally

Script execution platform:
- script_jobs.py / script_job_callback.py: async batching and callback
- script_execution_store.py / script_callback_rate.py: Redis-backed state
- script_execution_flush.py: background flusher to MySQL
- scripts.html / script-executions.html: full execution UI
- agent_url.py: centralised URL builder

Frontend:
- All 13 pages migrated from CDN to /app/vendor/ (no external deps)
- vendor/: alpinejs, tailwindcss-browser, xterm, xterm-addon-*, qrious
- Dashboard WebSocket real-time alerts; 8h JWT session timeout

Tests:
- test_security_unit.py: 15 unit tests (JWT, sanitize, vendor, install 403)
- test_api.py: env-configurable admin credentials

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-23 15:26:56 +08:00
Your Name d744d7df8e 安全与质量修复: P0-4/P0-5 + P1-6~P1-13 (8项)
P0-4: install.py _write_env() 值加引号转义,防止含#$\等字符的密码破坏.env格式
P0-5: install.py _build_redis_url() URL编码redis密码,防止@:等字符破坏URL解析
P1-6: auth_service.py _decode_access_token() 验证exp/sub声明存在,拒绝畸形JWT
P1-7: websocket.py + webssh.py WebSocket JWT验证增加updated_at检查,密码修改后令牌失效
P1-8: auth.py 无refresh_token的logout返回更明确的提示信息
P1-9: install.py create_admin增加_is_installed()检查,防止.env存在后重复创建
P1-10: servers.py server_stats() 改用SQL聚合查询,避免加载全部服务器对象
P1-11: heartbeat_flush.py 移除get_redis()永不返回None的死代码
P1-13: sync_engine_v2.py completed/failed计数器加asyncio.Lock防止并发竞态

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 23:04:40 +08:00
Your Name 938d26927f P1/P2: 后端安全与稳定性修复
- Agent per-server API Key认证 (agent.py)
- JWT updated_at校验与会话超时 (auth_jwt.py)
- 服务器凭据Fernet加密存储+密码脱敏 (servers.py)
- WebSSH服务器级授权检查 (webssh.py)
- Config同步去重+回滚机制 (sync_engine_v2.py)
- DB层分页offset/limit (server_repo.py)
- session.py logger修复 + @property死代码清理
- 心跳刷入rollback误用修复 (heartbeat_flush.py)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 22:28:57 +08:00
Your Name c03fe97d18 UX优化: 同步日志显示服务器名 + redis_url可编辑
- 同步日志API: JOIN Server表返回server_name字段
- 推送历史: 显示服务器名称替代操作人
- 仪表盘最近同步: 显示服务器名称替代server_id
- redis_url从SENSITIVE_KEYS移除(非密码,用户需可编辑)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 11:10:20 +08:00
Your Name 305f8d5689 P1: 全局JWT保护 + 审计日志补全 — scripts/assets/servers
- scripts.py: 所有9个端点添加JWT认证 + CUD操作审计日志
- assets.py: 所有GET端点添加JWT + 写操作审计日志补全
- servers.py: GET端点JWT保护(上轮未提交)
- WSL全量验证通过: ALL CHECKS PASSED
2026-05-22 08:55:34 +08:00
Your Name 55b7cbe904 fix: P1安全加固 — 全局JWT保护 + 审计日志补全 + 敏感字段过滤
Settings API:
- 所有端点添加JWT认证(get_current_admin)
- 不可改项(secret_key/api_key/encryption_key/database_url)禁止PUT修改
- 敏感字段GET响应自动脱敏(前8位+...)
- Schedules/Presets/Retry CRUD添加JWT+审计日志

Servers API:
- POST/PUT/DELETE添加JWT认证
- 服务器增删改写审计日志

Assets API:
- Platform/Node写操作添加JWT认证
- Platform创建添加审计日志
2026-05-22 08:46:09 +08:00
Your Name c9a99f4fb3 fix: 全项目文档对齐 + 代码清理
代码修复:
- web/agent/agent.py: datetime.utcnow() → datetime.now(timezone.utc)
- requirements.txt: 移除 paramiko==3.5.0 (已无活跃引用)
- 删除 server/infrastructure/ssh/pool.py (DEPRECATED, 无引用)

连接池三层对齐 (config.py/.env.example/session.py):
- DB_POOL_SIZE 100→160, DB_MAX_OVERFLOW 100→120
- 基于 MySQL max_connections=400, install.php 公式

文档修复 (21项):
- P0: 硬编码域名/IP替换为配置变量占位符
- P1: 10个过时设计文档加归档标注 (引用旧文件结构)
- P2: step-3-webssh报告 paramiko引用修正
- 6份审查报告连接池参数勘误 100/100→160/120
- ECC安全报告 EC5 datetime.utcnow 标记已修复
- docs/README.md 文档索引重写
- docs/memory/mem_nexus_overview.md 移除硬编码凭证
- docs/project/tech-stack-inventory.md paramiko标记已移除

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 08:19:56 +08:00
Your Name a584792603 feat: Pydantic request models + pagination + JWT auto-refresh
- server/api/schemas.py: New shared Pydantic models for all API routes
  (ServerCreate/Update/Push/Check, SyncFiles/Commands/Config/Sftp/Browse,
  ScriptCreate/Update/Execute, ScheduleCreate/Update, PlatformCreate/Update,
  NodeCreate/Update, PaginatedResponse)
- servers.py: Replace raw dict with Pydantic models, add pagination
  (page/per_page params, response now includes items/total/pages)
- sync_v2.py: Replace raw dict with SyncFiles/Commands/Config/Sftp/Browse
- scripts.py: Replace raw dict with ScriptCreate/Update/Execute
- assets.py: Replace raw dict with PlatformCreate/Update, NodeCreate/Update
- web/app/api.js: Shared JS auth module with JWT auto-refresh (2min
  before expiry), 401 retry with refresh token, doLogout with
  sendBeacon to backend, backward-compatible ah() alias
- web/app/servers.html: Use api.js, handle paginated response format

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 23:18:49 +08:00
Your Name 1a27327036 fix: PHP frontend JWT auth + API endpoints + missing tables + branding
- login.php: Fix JWT response format (success/access_token vs status=ok),
  store JWT tokens in session, support TOTP 202 flow
- api_client.php: Dual auth (JWT Bearer + X-API-Key fallback), add
  auto-refresh on 401, fix API endpoints (checkServerHealth → array,
  getServerLogs, getAuditLogs, getDashboardStats field mapping)
- api_proxy.php: Fix check_all to use /api/servers/check (not per-server),
  fix get_logs to support global endpoint, restart_multisync → restart_nexus
- install.php: Add 4 missing tables (platforms, nodes, ssh_sessions,
  command_logs), fix table creation order for FK dependencies, add JWT
  columns to admins, add new indexes, add platform_id/node_id/protocols/
  extra_attrs/connectivity to servers
- logout.php: Call /api/auth/logout to invalidate JWT refresh token
- index.php: Use JWT Bearer auth for API calls
- server_service.py: Implement real check_all_servers with concurrent
  httpx Agent health checks (was stub)
- servers.py: Add GET /api/servers/logs global sync logs endpoint
- Branding: MultiSync → Nexus across all PHP files (sidebar, titles,
  TOTP issuer, version strings)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 23:11:30 +08:00
Your Name 814e11588e feat: P1 background tasks + server stats endpoint
1. schedule_runner.py: cron-based schedule execution every 60s
   - Parses 5-field cron expressions (*, */N, ranges, lists)
   - Triggers SyncEngineV2.sync_files for due schedules
   - Prevents re-trigger within same minute
2. retry_runner.py: automatic retry of failed pushes every 5min
   - Exponential backoff (60s base, doubles per retry, max 64x)
   - Respects max_retries from PushRetryJob model
3. GET /api/servers/stats: dashboard aggregation endpoint
   - Returns total/online/offline counts + category breakdown
   - Reads real-time status from Redis, falls back to MySQL
   - Registered before /{id} to avoid path collision
4. main.py: register schedule_runner + retry_runner as background tasks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 22:58:17 +08:00
Your Name 539c33ef42 feat: Nexus 6.0 6-step implementation (Step 0-5)
Step 0: Infrastructure hardening — Redis BlockingConnectionPool,
WebSocket two-layer (memory+Redis Pub/Sub), JWT auth, DB session leak fix
Step 1: Data layer — 4 new tables (platforms/nodes/command_logs/ssh_sessions),
data migration (category→Node), repos + API routes
Step 2: Auth layer — JWT middleware on all routes, TOTP JWT integration
Step 3: Web SSH — asyncssh connection pool, /ws/terminal endpoint,
xterm.js frontend, Koko protocol
Step 4: Sync engine v2 — file/command/config/SFTP modes, parallel execution
Step 5: Frontend migration — 12 Tailwind CSS v4 + Alpine.js pages,
PHP-FPM removal from nginx config

21 Python backend + 12 HTML frontend + 2 deploy configs + 3 test files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 22:11:38 +08:00
Your Name f9045a8404 refactor: 仓库结构扁平化 + PHP前端合并到Nexus仓库
- 将 Nexus/Nexus/* 移到仓库根目录(消除双层嵌套)
- 删除旧的多层空壳目录 (server/, web/, agent/, deploy/, docs/)
- 将PHP前端 (web/) 合并进Nexus仓库 — 统一管理
- 部署时 git clone Nexus 仓库即可,不再需要两个仓库

目录结构:
  server/     ← Python FastAPI后端
  web/        ← PHP前端 (install.php, config.php, etc)
  deploy/     ← Supervisor + Shell健康检查
  docs/       ← 部署文档
  tests/      ← 测试
  .env        ← 不在git中 (install.php生成)
  .gitignore  ← 排除 .env, SECRETS.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 17:24:21 +08:00