Files
wecom_it_smart_desk/docs/09-部署运维/03-RELEASE-NOTES-v0.7.1-20260623.md
T

6.8 KiB

Release Notes v0.7.1

📅 发布日期:2026-06-23 | 类型:🔐 安全 + 功能 | 紧急度:🟡 重要 🔄 补充:2026-06-24 hotfix #116/#118/#119/#120 已部署(详见文末"补充 hotfix"小节)

🎯 本版本重点

  1. 修复扫码登录 iOS NSURLErrorCannotFindHost — 企微 App 用户扫码不再报错
  2. 完整 MFA + RBAC 权限体系 — 5 角色细粒度权限 + 高危操作二次认证
  3. H5 员工端企微 OAuth 登录 — 员工不再需要输账号密码
  4. 🆕 扫码登录去掉手机 confirm 步骤 — 企微 App 无确认 UI,扫码成功 = 直接登录

🔐 安全修复

#109 P0:扫码登录 NSURLError 修复

问题:用户企微 App 访问 https://itsupport.servyou.com.cn/itportal/,扫描二维码后跳转报 NSURLErrorCannotFindHost(iOS WebView DNS 解析失败)

根因:backend/app/config.py 新字段 qrcode_oauth_callback 用了 pydantic 默认行为,不剥环境变量前缀

  • 字段名:qrcode_oauth_callback
  • pydantic-settings 期望 env:QRCODE_OAUTH_CALLBACK
  • 实际 env:WECOM_QRCODE_CALLBACK(带前缀,匹配不上)
  • 结果:settings.qrcode_oauth_callback = "",qrcode_service 走兜底返回相对路径 /api/auth_qrcode/scan
  • iOS WebView 拼接相对路径失败 → DNS 解析错误

修复:

from pydantic import Field

class Settings(BaseSettings):
    qrcode_oauth_callback: str = Field(
        default="",
        validation_alias="WECOM_QRCODE_CALLBACK",
    )

部署:docker commit + restart + 验证,详见 phase1-progress#109-hotfix-二轮修复

RBAC 5 角色 × 4 资源 × 4 操作 × 3 范围

  • 5 角色:super_admin / admin / agent / user / guest
  • 4 资源:user / conversation / config / audit_log
  • 4 操作:read / create / update / delete
  • 3 范围:all / department / self

高危路由白名单 + 中间件

5 类高危操作需 OTP 二次认证:

  • role_change(角色变更)
  • config_change(配置变更)
  • data_export(数据导出)
  • account_disable(账户禁用)
  • account_create_reset(账户创建/重置)

新功能

后端扫码登录(端点 4 个)

端点 方法 说明
/api/auth_qrcode/create POST 生成二维码(含 PNG base64)
/api/auth_qrcode/poll/{ticket} POST 扫码端轮询
/api/auth_qrcode/scan POST 企微回调
/api/auth_qrcode/confirm POST 用户确认登录

后端 MFA + pyotp(端点 5 个)

端点 方法 说明
/api/mfa/status GET 查询绑定状态
/api/mfa/bind/start POST 开始绑定(返回 secret + QR)
/api/mfa/bind/confirm POST 确认绑定
/api/mfa/verify POST 验证 OTP
/api/mfa/disable POST 禁用 MFA

前端 MFA UI

  • MfaBind.vue — 绑定弹窗
  • useHighRiskOtp.ts composable — 高危操作 OTP 弹窗
  • Login.vue / TopBar.vue — 集成 MFA 状态显示
  • 路由 + store 全链路集成

H5 员工端 OAuth 登录

  • 部署路径:https://itsupport.servyou.com.cn/itdesk/
  • 自动 OAuth 静默授权(snsapi_base)
  • 会话列表 + 消息收发
  • 已完成 E2E 验证(#104)

🛠️ 部署要点

必备环境变量

# /opt/wecom-it-desk/.env
WECOM_QRCODE_CALLBACK=https://itsupport.servyou.com.cn/api/auth_qrcode/scan
WECOM_SSO_ENABLED=true
WECOM_SSO_CALLBACK_BASE=https://itsupport.servyou.com.cn

部署清单

  • Backend commit 78f60c6(v0.7.1-dev)
  • docker 镜像 wecom-it-desk-backend:latest 已 commit 新 config
  • 容器已重启 + /api/ready 200
  • H5 dist 已部署到 /opt/wecom-it-desk/nginx/html/itdesk/
  • nginx 已 reload
  • /api/auth_qrcode/create 返回绝对 URL
  • Gitea push(等用户重授权 token)
  • 企微 App 实际扫码验证

⚠️ 已知问题

  1. Gitea push 阻塞:workbuddy-claude token 2026-06-15 被吊销,需去 Gitea Web 重授权
  2. #108 still pending:v0.7.1-dev 78f60c6 未推到 origin
  3. /api/admin/ IP 白名单仍是 0.0.0.0/0(临时方案),v1.0 前必须收窄

📚 相关文档

📊 改动统计

  • 代码:22 文件 / +4705 行
  • 测试:78 passed + 4 xfail + 33 pre-existing failures(已分类)
  • 文档:5 新增 / 3 更新
  • Agent:4 并行 worktree 合并

🔄 补充 hotfix(2026-06-24 部署)

#116 P0 + #118 P0:扫码端点 405 + ticket≠state

问题:

  • 坐席扫码登录报 405 Method Not Allowed
  • 企微 OAuth 回调走 GET(?code=xxx&state=<ticket>),旧代码只支持 POST
  • 即使改双方法,Optional[str] = NoneQuery() 装饰器,FastAPI 当 body 参数处理
  • 函数参数叫 ticket,企微用 state,参数名不匹配

修复:backend/app/api/auth_qrcode.py scan 端点

@router.api_route("/scan", methods=["GET", "POST"], response_model=None)
async def scan_qrcode(
    body: Optional[QrcodeScanRequest] = None,
    ticket: Optional[str] = Query(None, description="兼容旧参数名"),
    state: Optional[str] = Query(None, description="企微 OAuth state 标准参数名"),
    code: Optional[str] = Query(None, description="企微 OAuth 授权码"),
    redis_client = Depends(dep_redis),
):
    if body is not None:
        final_ticket, final_code = body.ticket, body.code
    else:
        final_ticket = state or ticket  # 优先 state(企微标准),回退 ticket
        final_code = code

部署:deploy-staging/hotfix-116-qrcode-scan-get/ — webcli v7 一键,20/20 pytest 过

#119:webcli v7 全自动部署链路

复用 jumpserver Playwright + Luna webcli + OTP 自动,实现 18-31KB 命令脚本单次输入,2-3 分钟跑完。

#120 P0:扫码成功 = 自动登录(去掉 confirm)

问题:企微 App 端没有"确认登录" UI,旧 confirm 步骤在生产永远走不通(用户报告"扫码成功后,手机端没有出现确认登录按钮")

用户决策:方案 A — 扫码成功 = 自动登录(推荐),2026-06-24 拍板

修复:backend/app/services/qrcode_service.py process_scan 默认 auto_confirm=True

  • 扫码成功直接写 qrcode:confirm:{ticket}(含 token)
  • 前端 poll 立即拿到 status=confirmed + token
  • 跳过手机 confirm 步骤
  • 默认 roles=["user"],admin/agent 走 portal 端角色选择

测试:20/20 pytest 过(test_scan_then_poll_returns_confirmed + test_scan_auto_confirm_writes_confirm_key 等)

部署:deploy-staging/hotfix-120-qrcode-auto-confirm/ — webcli v7 一键,容器内 /api/ready 200 OK

残留:外部域名 https://itsupport.servyou.com.cn/api/ready 不通(nginx /api/ upstream 配错 + 8000 端口未暴露),等 #48 修复。容器内 backend 完全健康。