Commit Graph

33 Commits

  • docs: add社媒 links (Twitter / Telegram) to README
    Hero badges + a 交流与关注 section: x.com/gloridust1024, t.me/WechatOnCloud.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • fix(P0): unique persistent machine-id per instance + manual reset
    All instances shared the image-baked machine-id (a67bf09f...), so Tencent
    saw every WechatOnCloud account worldwide as one "device" — a textbook
    device-farm signal triggering risk control and the forced-logout loop
    reported across old and new versions.
    
    - docker/woc-identity.sh: new /custom-cont-init.d/00-woc-identity hook —
      generates a unique machine-id on first start, persists it in the data
      volume (survives restart/upgrade/recreate), writes /etc/machine-id +
      /var/lib/dbus/machine-id, removes /.dockerenv. Existing instances get a
      fresh unique id on first upgraded start (volume lacks the file).
    - regenInstanceMachineId + POST /api/admin/instances/:id/regen-machine-id:
      roll a brand-new device id and restart, for accounts re-flagged by risk
      control. Gated on the hook being present (old image → instructs upgrade).
    - Admin 实例卡片「安全」弹窗新增「重置设备 ID 并重启」。
    
    Verified: two fresh containers get distinct machine-ids; id persists across
    restart; regen (rm persisted file + restart) yields a new persistent id.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • ci: optional Docker Hub mirror in release workflow
    - release.yml: dual-push to GHCR + Docker Hub when vars.DOCKERHUB_USERNAME
      is set; falls back to GHCR-only when unset (no behavior change for forks).
    - .env.example: surface docker.io as a first-class WOC_IMAGE_PREFIX option.
    - doc/发布到GHCR.md: document the one-time Variable + Secret setup and the
      prerequisite of pre-creating the public repos on hub.docker.com.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
  • docs(security): clarify multi-host allowlist + echo rejected host in 400
    - .env.example: surface multi-domain syntax (PANEL_ALLOWED_HOSTS=a,b,c),
      IPv6 literal example, and reverse-proxy troubleshooting tip.
    - index.ts: 400 response includes the rejected `host` and a hint pointing
      at PANEL_ALLOWED_HOSTS — drops the diagnostic floor when reverse-proxy
      Host-passthrough is misconfigured.
    
    Follow-up to #13 (DNS-rebinding allowlist).
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
  • Merge pull request #13 from aaronjmars/security/host-allowlist-dns-rebinding
    fix(security): gate panel Host header to block DNS rebinding
  • fix(security): gate panel Host header to block DNS rebinding
    Without Host validation, a malicious page the operator visits can use DNS
    rebinding to point a hostname at the panel's loopback / LAN IP and drive
    every authenticated API from the operator's own browser — including the
    docker.sock-backed admin endpoints. The README's "intranet-only" guidance
    does not cover this: the browser is the trust-boundary crossing.
    
    Add an onRequest hook (plus a Host check on raw WebSocket upgrades) that
    allows loopback + RFC1918 LAN by default and accepts public hostnames via
    PANEL_ALLOWED_HOSTS (documented in .env.example and threaded through
    docker-compose.yml). 35 inject()-driven assertions; tsc --noEmit clean.
    
    Detected by Aeon + manual review (DNS-rebinding-gate axis).
    Severity: high
    CWE-346 (Origin Validation Error)
  • Merge pull request #12 from huglemon/fix/cjk-ime-paste-fallback
    修复中文 IME 输入大量丢字:增加容器内剪贴板粘贴兜底路径
  • feat: 超管密码离线找回 + 改密/重置二次确认 + GHCR 手动构建文档
    - 密码找回:accounts.json 给用户加 "resetPassword": true(兼容 reset_password),
      重启面板即把其密码重置为 PANEL_ADMIN_PASSWORD(默认 wechat)、解禁并清除标记
    - 改密/重置密码弹窗新增「再次输入新密码」二次确认:两次不一致则拦截,
      避免浏览器自动填充/手误把密码静默设成非预期值导致锁死
    - README:补充方式 B(本机 buildx 手动多架构构建推送 GHCR)+ Release 的 latest 注意事项
      + 「重置超管密码(离线找回)」操作步骤
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
  • feat: 音视频/文件传输 + 产品 UX 改进 + 镜像源可切换
    媒体链路(生产 HTTPS 下可用,含降级)
    - 音频(听):PulseAudio + KasmVNC 工具条,开箱即用
    - 麦克风(说):virtmic 管道源已就绪,运行时需 HTTPS(非 HTTPS 前端提示)
    - 摄像头(视频):docker.ts 条件化 v4l2 设备直通 + 加 video 组;无设备/无 HTTPS 时优雅降级,音频麦克风不受影响
    - WOC_VIDEO_DEVICES 显式指定或经 /host-dev 自动探测
    
    文件传输(原生拖拽)
    - 面板侧拖拽上传 + 下载:dockerode putArchive/getArchive 到实例 ~/Desktop(持久卷)
    - 纯 JS 单文件 tar 编解码(免依赖),文本/二进制均无损;全程走面板鉴权与权限校验
    
    安全 & UX
    - 默认密码告警条 + mustChangePassword 追踪(兼容旧账号文件迁移)
    - 会话过期(401) 自动跳登录;桌面连接 loading 态
    - 停止/未创建实例一键启动(新增 /api/admin/instances/:id/start)
    - 统一牛奶布艺弹窗 + Toast,替换 Admin 原生 alert/confirm/prompt
    - 密码可见切换;实例重命名;退出二次确认;空状态改用品牌终端图标
    
    其它
    - gen-icons 生成终端风格图标(此前仅空白绿块,影响 Docker/CI 产物)
    - 镜像源可切换 WOC_IMAGE_PREFIX(国内反代/ACR);品牌名「云微」
    - 文档:.env.example / docker-compose 增加音视频(v4l2loopback/HTTPS)、镜像源、视频设备说明
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
  • 品牌更名为「云微」并替换为终端风格图标
    - 面板/PWA/iOS/fnOS 显示名统一改为「云微」(英文项目名 WechatOnCloud 保留)
    - favicon 改为绿底 macOS 终端风格(>_ 提示符),重新编译 180/192/512 PNG
    - 登录页 logo 复用同款终端图标
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>