mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-03-25 15:25:50 +00:00
fix(auth): avoid logout on export-only clear and harden db key auto-fetch
This commit is contained in:
@@ -1347,6 +1347,7 @@ function registerIpcHandlers() {
|
||||
}
|
||||
}
|
||||
|
||||
if (clearCache) {
|
||||
try {
|
||||
const wxidConfigsRaw = cfg.get('wxidConfigs') as Record<string, any> | undefined
|
||||
if (wxidConfigsRaw && typeof wxidConfigsRaw === 'object') {
|
||||
@@ -1369,6 +1370,7 @@ function registerIpcHandlers() {
|
||||
} catch (error) {
|
||||
warnings.push(`清理账号配置失败: ${String(error)}`)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
@@ -2172,7 +2174,7 @@ function registerIpcHandlers() {
|
||||
|
||||
// 密钥获取
|
||||
ipcMain.handle('key:autoGetDbKey', async (event) => {
|
||||
return keyService.autoGetDbKey(60_000, (message, level) => {
|
||||
return keyService.autoGetDbKey(180_000, (message, level) => {
|
||||
event.sender.send('key:dbKeyStatus', { message, level })
|
||||
})
|
||||
})
|
||||
|
||||
@@ -509,6 +509,58 @@ export class KeyService {
|
||||
return false
|
||||
}
|
||||
|
||||
private isLoginRelatedText(value: string): boolean {
|
||||
const normalized = String(value || '').replace(/\s+/g, '').toLowerCase()
|
||||
if (!normalized) return false
|
||||
const keywords = [
|
||||
'登录',
|
||||
'扫码',
|
||||
'二维码',
|
||||
'请在手机上确认',
|
||||
'手机确认',
|
||||
'切换账号',
|
||||
'wechatlogin',
|
||||
'qrcode',
|
||||
'scan'
|
||||
]
|
||||
return keywords.some((keyword) => normalized.includes(keyword))
|
||||
}
|
||||
|
||||
private async detectWeChatLoginRequired(pid: number): Promise<boolean> {
|
||||
if (!this.ensureUser32()) return false
|
||||
let loginRequired = false
|
||||
|
||||
const enumWindowsCallback = this.koffi.register((hWnd: any, _lParam: any) => {
|
||||
if (!this.IsWindowVisible(hWnd)) return true
|
||||
const title = this.getWindowTitle(hWnd)
|
||||
if (!this.isWeChatWindowTitle(title)) return true
|
||||
|
||||
const pidBuf = Buffer.alloc(4)
|
||||
this.GetWindowThreadProcessId(hWnd, pidBuf)
|
||||
const windowPid = pidBuf.readUInt32LE(0)
|
||||
if (windowPid !== pid) return true
|
||||
|
||||
if (this.isLoginRelatedText(title)) {
|
||||
loginRequired = true
|
||||
return false
|
||||
}
|
||||
|
||||
const children = this.collectChildWindowInfos(hWnd)
|
||||
for (const child of children) {
|
||||
if (this.isLoginRelatedText(child.title) || this.isLoginRelatedText(child.className)) {
|
||||
loginRequired = true
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}, this.WNDENUMPROC_PTR)
|
||||
|
||||
this.EnumWindows(enumWindowsCallback, 0)
|
||||
this.koffi.unregister(enumWindowsCallback)
|
||||
|
||||
return loginRequired
|
||||
}
|
||||
|
||||
private async waitForWeChatWindowComponents(pid: number, timeoutMs = 15000): Promise<boolean> {
|
||||
if (!this.ensureUser32()) return true
|
||||
const startTime = Date.now()
|
||||
@@ -605,6 +657,7 @@ export class KeyService {
|
||||
|
||||
const keyBuffer = Buffer.alloc(128)
|
||||
const start = Date.now()
|
||||
let loginRequiredDetected = false
|
||||
|
||||
try {
|
||||
while (Date.now() - start < timeoutMs) {
|
||||
@@ -624,6 +677,9 @@ export class KeyService {
|
||||
const level = levelOut[0] ?? 0
|
||||
if (msg) {
|
||||
logs.push(msg)
|
||||
if (this.isLoginRelatedText(msg)) {
|
||||
loginRequiredDetected = true
|
||||
}
|
||||
onStatus?.(msg, level)
|
||||
}
|
||||
}
|
||||
@@ -635,6 +691,15 @@ export class KeyService {
|
||||
} catch { }
|
||||
}
|
||||
|
||||
const loginRequired = loginRequiredDetected || await this.detectWeChatLoginRequired(pid)
|
||||
if (loginRequired) {
|
||||
return {
|
||||
success: false,
|
||||
error: '微信已启动但尚未完成登录,请先在微信客户端完成登录后再重试自动获取密钥。',
|
||||
logs
|
||||
}
|
||||
}
|
||||
|
||||
return { success: false, error: '获取密钥超时', logs }
|
||||
}
|
||||
|
||||
|
||||
@@ -305,9 +305,14 @@ function Sidebar() {
|
||||
if (result.warning) {
|
||||
detailLines.push('', `注意:${result.warning}`)
|
||||
}
|
||||
window.alert(`账号数据清理完成。\n\n${detailLines.join('\n')}\n\n为保障数据安全,WeFlow 已清除该账号本地缓存/导出相关数据。若需再次获取数据,请手动登录微信客户端并重新在 WeFlow 完成配置。`)
|
||||
const followupHint = shouldClearCacheData
|
||||
? '若需再次获取数据,请手动登录微信客户端并重新在 WeFlow 完成配置。'
|
||||
: '你可以继续使用当前登录状态,无需重新登录。'
|
||||
window.alert(`账号数据清理完成。\n\n${detailLines.join('\n')}\n\n为保障数据安全,WeFlow 已清除该账号本地缓存/导出相关数据。${followupHint}`)
|
||||
resetClearDialogState()
|
||||
if (shouldClearCacheData) {
|
||||
window.location.reload()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('清理账号数据失败:', error)
|
||||
window.alert('清理失败,请稍后重试。')
|
||||
|
||||
@@ -36,6 +36,18 @@ interface WxidOption {
|
||||
modifiedTime: number
|
||||
}
|
||||
|
||||
const formatDbKeyFailureMessage = (error?: string, logs?: string[]): string => {
|
||||
const base = String(error || '自动获取密钥失败').trim()
|
||||
const tailLogs = Array.isArray(logs)
|
||||
? logs
|
||||
.map(item => String(item || '').trim())
|
||||
.filter(Boolean)
|
||||
.slice(-6)
|
||||
: []
|
||||
if (tailLogs.length === 0) return base
|
||||
return `${base};最近状态:${tailLogs.join(' | ')}`
|
||||
}
|
||||
|
||||
function SettingsPage() {
|
||||
const {
|
||||
isDbConnected,
|
||||
@@ -725,7 +737,10 @@ function SettingsPage() {
|
||||
setIsManualStartPrompt(true)
|
||||
setDbKeyStatus('需要手动启动微信')
|
||||
} else {
|
||||
showMessage(result.error || '自动获取密钥失败', false)
|
||||
if (result.error?.includes('尚未完成登录')) {
|
||||
setDbKeyStatus('请先在微信完成登录后重试')
|
||||
}
|
||||
showMessage(formatDbKeyFailureMessage(result.error, result.logs), false)
|
||||
}
|
||||
}
|
||||
} catch (e: any) {
|
||||
|
||||
@@ -23,6 +23,18 @@ interface WelcomePageProps {
|
||||
standalone?: boolean
|
||||
}
|
||||
|
||||
const formatDbKeyFailureMessage = (error?: string, logs?: string[]): string => {
|
||||
const base = String(error || '自动获取密钥失败').trim()
|
||||
const tailLogs = Array.isArray(logs)
|
||||
? logs
|
||||
.map(item => String(item || '').trim())
|
||||
.filter(Boolean)
|
||||
.slice(-6)
|
||||
: []
|
||||
if (tailLogs.length === 0) return base
|
||||
return `${base};最近状态:${tailLogs.join(' | ')}`
|
||||
}
|
||||
|
||||
function WelcomePage({ standalone = false }: WelcomePageProps) {
|
||||
const navigate = useNavigate()
|
||||
const { isDbConnected, setDbConnected, setLoading } = useAppStore()
|
||||
@@ -292,7 +304,10 @@ function WelcomePage({ standalone = false }: WelcomePageProps) {
|
||||
setIsManualStartPrompt(true)
|
||||
setDbKeyStatus('需要手动启动微信')
|
||||
} else {
|
||||
setError(result.error || '自动获取密钥失败')
|
||||
if (result.error?.includes('尚未完成登录')) {
|
||||
setDbKeyStatus('请先在微信完成登录后重试')
|
||||
}
|
||||
setError(formatDbKeyFailureMessage(result.error, result.logs))
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user