feat(weixin): add WebUI QR-code login via SSE#1744
Conversation
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
e5e5905 to
a1cc579
Compare
WebUI mode cannot call Electron IPC (window.electronAPI is undefined), so add a server-sent events endpoint GET /api/channel/weixin/login that drives the existing WeixinLogin flow and streams qr/scanned/done/error events to the browser. The QR code encodes the qrcode_img_content page URL (not the raw hex ticket) — confirmed by reading the WeChat liteapp JS bundle which does Lr.toCanvas(canvas, window.location.href, ...). Also expose qrcodeData as second arg of onQR callback so both Electron (canvas render) and WebUI (QRCodeSVG) paths have what they need. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
onQR now receives (pageUrl, qrcodeData) — update existing tests to match the new signature. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
After disablePlugin, the backend emits pluginStatusChanged asynchronously (emitStatusChange is not awaited), so the event arrives after the IPC response. The event still carries hasToken: true (enabled: false), which caused the useEffect to flip loginState back to 'connected'. Fix: require pluginStatus?.enabled to be true before syncing to connected state, and apply the same guard in renderLoginArea. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
useState init used hasToken alone, so a disabled plugin with stored credentials would show 'connected' on page open. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
6df399d to
68dcaaa
Compare
Code Review:feat(weixin): add WebUI QR-code login via SSE (#1744)变更概述本 PR 为 WebUI 模式(浏览器无 方案评估结论:✅ 方案合理 整体方案与项目架构一致:SSE 路由放在 问题清单🟡 MEDIUM — EventSource 未在组件卸载时关闭,存在连接泄漏文件: 问题代码: const handleLoginWebUI = () => {
...
const es = new EventSource('/api/channel/weixin/login', { withCredentials: true });
// es 仅保存在局部变量中,组件卸载时无法关闭
...
};问题说明:如果用户在登录流程中关闭 Settings 弹窗, 修复建议:将 EventSource 存入 const eventSourceRef = useRef<EventSource | null>(null);
// handleLoginWebUI 中:
const es = new EventSource('/api/channel/weixin/login', { withCredentials: true });
eventSourceRef.current = es;
// 组件卸载清理:
useEffect(() => {
return () => {
eventSourceRef.current?.close();
eventSourceRef.current = null;
};
}, []);🟡 MEDIUM — 补丁覆盖率 60.29%,低于项目 80% 下限文件: 问题说明:Codecov 报告补丁覆盖率 60.29%(19 行未覆盖 + 8 行部分覆盖),未达到项目 ≥80% 的覆盖率要求。主要缺口包括:
修复建议:补充以下测试场景: // enableWeixinPlugin 失败路径
mockEnablePlugin.mockResolvedValueOnce({ success: false, msg: 'Error msg' });
// → 应显示错误 Message,loginState 回到 'idle'
// SSE error 事件中 'expired' 分支
es.emit('error', { message: 'QR code expired' });
// → 应显示 warning,loginState 回到 'idle'
// handleDisconnect 失败路径
mockDisablePlugin.mockResolvedValueOnce({ success: false, msg: 'Disable failed' });
// → 应显示错误 Message🔵 LOW —
|
| # | 严重级别 | 文件 | 问题 |
|---|---|---|---|
| 1 | 🟡 MEDIUM | WeixinConfigForm.tsx:277 |
EventSource 未在组件卸载时关闭 |
| 2 | 🟡 MEDIUM | WeixinConfigForm.tsx |
补丁覆盖率 60.29%,低于 80% 下限 |
| 3 | 🔵 LOW | WeixinConfigForm.tsx:312 |
onerror 与 addEventListener 重复 |
| 4 | 🔵 LOW | WeixinConfigForm.tsx:64 |
注释描述不准确 |
结论
本报告由本地 pr-review skill 生成,包含完整项目上下文,无截断限制。
- Store EventSource in a ref and close it in useEffect cleanup to prevent connection leaks when Settings modal is closed during WebUI QR login - Add tests for enableWeixinPlugin failure path, SSE error event branches (expired and non-expired), handleDisconnect failure path, and unmount cleanup Review follow-up for iOfficeAI#1744
PR Fix 验证报告原始 PR: #1744
总结: ✅ 已修复 2 个 | ❌ 未能修复 0 个
|
Code Review:feat(weixin): add WebUI QR-code login via SSE (#1744)变更概述本 PR 为 WebUI 模式下的微信登录增加了 SSE(Server-Sent Events)通道。核心改动包括:新增 方案评估结论:✅ 方案合理 方案正确区分了 Electron(IPC + 隐藏窗口截图)和 WebUI(SSE + 问题清单🔵 LOW —
|
| # | 严重级别 | 文件 | 问题 |
|---|---|---|---|
| 1 | 🔵 LOW | WeixinConfigForm.tsx:322 |
onerror 与 addEventListener('error', ...) 双重注册 |
| 2 | 🔵 LOW | weixinLoginRoutes.test.ts |
未覆盖 onError 路径 |
结论
✅ 批准合并 — 无阻塞性问题。核心功能正确,Electron 路径不受影响,测试覆盖率满足项目要求(CI 全部通过)。上述两个 LOW 级别问题可在后续 PR 中跟进修复。
本报告由本地 pr-review skill 生成,包含完整项目上下文,无截断限制。
|
✅ 已自动 review,无阻塞性问题,正在触发自动合并。 |
Summary
window.electronAPIis undefined), so the existing WeChat login button silently failedGET /api/channel/weixin/loginSSE endpoint that drives the existingWeixinLogin.tsflow and streamsqr/scanned/done/errorevents to the browserEventSource+QRCodeSVG(fromqrcode.react) to display the QR codeqrcode_img_contentpage URL (not the raw hex ticket) — confirmed by reading the WeChat liteapp JS bundle which callsLr.toCanvas(canvas, window.location.href, ...)qrcodeDataas a second argument of theonQRcallback so both Electron (canvas render) and WebUI (QRCodeSVG) paths have what they need; Electron behaviour is unchangedTest plan
🤖 Generated with Claude Code