optimize: WeChat QR code auth flow and channel reliability
- Generate QR code server-side when iLink API returns SPA page URL (added qrcode + image crates for PNG generation) - Strip bot_token from frontend response (new WeixinQrcodeStatusPublic type) - Add request timeouts and shared HTTP client for QR code endpoints - Fix TOCTOU race on reply_context double-lock (single lock scope) - Extract do_send() helper to deduplicate sendmessage logic; resend now checks ret field for context expiry instead of HTTP status only - Cap pending_messages buffer at 50 to prevent unbounded memory growth - Generate stable X-WECHAT-UIN per backend instance instead of per request - Extract ILINK_CHANNEL_VERSION constant (was hardcoded in 4 places) - Add 5-minute client-side QR expiry timeout in frontend dialog - Track consecutive polling errors and show warning after 3 failures - Stabilise onAuthSuccess/onClose callback refs to prevent polling restarts - Replace dead i18n key weixinOpenQrcode with weixinPollError Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use crate::app_error::AppCommandError;
|
||||
use crate::chat_channel::backends::weixin::{WeixinQrcodeInfo, WeixinQrcodeStatus};
|
||||
use crate::chat_channel::backends::weixin::{WeixinQrcodeInfo, WeixinQrcodeStatusPublic};
|
||||
use crate::chat_channel::manager::ChatChannelManager;
|
||||
use crate::chat_channel::types::ChannelType;
|
||||
use crate::db::service::{chat_channel_message_log_service, chat_channel_service};
|
||||
@@ -351,7 +351,7 @@ pub async fn weixin_check_qrcode_core(
|
||||
db: &AppDatabase,
|
||||
channel_id: i32,
|
||||
qrcode: &str,
|
||||
) -> Result<WeixinQrcodeStatus, AppCommandError> {
|
||||
) -> Result<WeixinQrcodeStatusPublic, AppCommandError> {
|
||||
let result = crate::chat_channel::backends::weixin::weixin_check_qrcode(qrcode)
|
||||
.await
|
||||
.map_err(AppCommandError::from)?;
|
||||
@@ -386,7 +386,10 @@ pub async fn weixin_check_qrcode_core(
|
||||
}
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
// Return only the status — never expose bot_token to the frontend
|
||||
Ok(WeixinQrcodeStatusPublic {
|
||||
status: result.status,
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -569,6 +572,6 @@ pub async fn weixin_check_qrcode(
|
||||
db: tauri::State<'_, AppDatabase>,
|
||||
channel_id: i32,
|
||||
qrcode: String,
|
||||
) -> Result<WeixinQrcodeStatus, AppCommandError> {
|
||||
) -> Result<WeixinQrcodeStatusPublic, AppCommandError> {
|
||||
weixin_check_qrcode_core(&db, channel_id, &qrcode).await
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user