Skip to content

Commit b33a9bd

Browse files
committed
improvement(log): 补充图片密钥与媒体解密链路调试日志
- 为解密页关键阶段补充调试日志 - 为图片密钥获取流程补充请求、命中和回退日志 - 为媒体密钥保存与批量解密补充有效密钥日志 - 对 AES 信息做摘要输出,便于排查且避免完整泄露
1 parent b0230dc commit b33a9bd

4 files changed

Lines changed: 364 additions & 11 deletions

File tree

frontend/pages/decrypt.vue

Lines changed: 135 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,44 @@ const manualKeyErrors = reactive({
487487
})
488488
489489
const normalizeAccountId = (value) => String(value || '').trim()
490+
const summarizeAesForLog = (value) => {
491+
const raw = String(value || '').trim()
492+
if (!raw) return ''
493+
if (raw.length <= 8) return raw
494+
return `${raw.slice(0, 4)}...${raw.slice(-4)}(len=${raw.length})`
495+
}
496+
const summarizeKeyStateForLog = (xorKey, aesKey) => ({
497+
xor_key: String(xorKey || '').trim(),
498+
aes_key: summarizeAesForLog(aesKey),
499+
has_xor: !!String(xorKey || '').trim(),
500+
has_aes: !!String(aesKey || '').trim()
501+
})
502+
const formatLogError = (error) => {
503+
if (!error) return ''
504+
if (error instanceof Error) {
505+
return {
506+
name: String(error.name || 'Error'),
507+
message: String(error.message || ''),
508+
stack: String(error.stack || '')
509+
}
510+
}
511+
if (typeof error === 'object') {
512+
try {
513+
return JSON.parse(JSON.stringify(error))
514+
} catch {}
515+
}
516+
return String(error)
517+
}
518+
const logDecryptDebug = (phase, details = {}) => {
519+
if (process.client && typeof window !== 'undefined') {
520+
try {
521+
window.wechatDesktop?.logDebug?.('decrypt-page', phase, details)
522+
} catch {}
523+
}
524+
try {
525+
console.info(`[decrypt-page] ${phase}`, details)
526+
} catch {}
527+
}
490528
491529
const normalizeXorKey = (value) => {
492530
const raw = String(value || '').trim()
@@ -508,6 +546,7 @@ const normalizeAesKey = (value) => {
508546
const prefillKeysForAccount = async (account) => {
509547
const acc = normalizeAccountId(account)
510548
if (!acc) return
549+
logDecryptDebug('prefill:start', { account: acc })
511550
try {
512551
const resp = await getSavedKeys({ account: acc })
513552
if (!resp || resp.status !== 'success') return
@@ -527,22 +566,46 @@ const prefillKeysForAccount = async (account) => {
527566
if (aesKey && !String(manualKeys.aes_key || '').trim()) {
528567
manualKeys.aes_key = aesKey
529568
}
569+
logDecryptDebug('prefill:done', {
570+
request_account: acc,
571+
response_account: String(resp.account || '').trim(),
572+
db_key_present: !!dbKey,
573+
...summarizeKeyStateForLog(
574+
String(keys.image_xor_key || '').trim(),
575+
String(keys.image_aes_key || '').trim()
576+
),
577+
applied: summarizeKeyStateForLog(manualKeys.xor_key, manualKeys.aes_key)
578+
})
530579
} catch (e) {
531-
// ignore
580+
logDecryptDebug('prefill:error', { account: acc, error: formatLogError(e) })
532581
}
533582
}
534583
535584
const tryAutoFetchImageKeys = async (account) => {
536585
const acc = normalizeAccountId(account)
537586
if (!acc) return
538-
if (String(manualKeys.xor_key || '').trim() || String(manualKeys.aes_key || '').trim()) return
587+
if (String(manualKeys.xor_key || '').trim() || String(manualKeys.aes_key || '').trim()) {
588+
logDecryptDebug('auto-fetch:skip-existing', {
589+
account: acc,
590+
keys: summarizeKeyStateForLog(manualKeys.xor_key, manualKeys.aes_key)
591+
})
592+
return
593+
}
539594
540595
warning.value = '正在通过云端/本地算法自动获取图片密钥,请稍候...'
596+
logDecryptDebug('auto-fetch:start', { account: acc })
541597
try {
542598
const imgRes = await getImageKey({
543599
account: acc,
544600
db_storage_path: String(formData.db_storage_path || '').trim()
545601
})
602+
logDecryptDebug('auto-fetch:response', {
603+
account: acc,
604+
status: imgRes?.status,
605+
errmsg: String(imgRes?.errmsg || ''),
606+
data_account: String(imgRes?.data?.account || '').trim(),
607+
keys: summarizeKeyStateForLog(imgRes?.data?.xor_key, imgRes?.data?.aes_key)
608+
})
546609
547610
if (imgRes && imgRes.status === 0) {
548611
if (imgRes.data?.xor_key) manualKeys.xor_key = imgRes.data.xor_key
@@ -554,20 +617,35 @@ const tryAutoFetchImageKeys = async (account) => {
554617
}
555618
} catch (e) {
556619
warning.value = '网络请求失败,请手动填写图片密钥。'
620+
logDecryptDebug('auto-fetch:error', { account: acc, error: formatLogError(e) })
557621
}
558622
}
559623
560624
const ensureKeysForAccount = async (account) => {
561625
const acc = normalizeAccountId(account)
562626
if (!acc) return
563627
628+
logDecryptDebug('ensure-keys:start', {
629+
account: acc,
630+
previous_account: activeKeyAccount.value,
631+
current_manual: summarizeKeyStateForLog(manualKeys.xor_key, manualKeys.aes_key)
632+
})
564633
if (activeKeyAccount.value && activeKeyAccount.value !== acc) {
634+
logDecryptDebug('ensure-keys:switch-account', {
635+
from: activeKeyAccount.value,
636+
to: acc,
637+
cleared_keys: summarizeKeyStateForLog(manualKeys.xor_key, manualKeys.aes_key)
638+
})
565639
clearManualKeys()
566640
}
567641
568642
activeKeyAccount.value = acc
569643
await prefillKeysForAccount(acc)
570644
await tryAutoFetchImageKeys(acc)
645+
logDecryptDebug('ensure-keys:done', {
646+
account: acc,
647+
manual: summarizeKeyStateForLog(manualKeys.xor_key, manualKeys.aes_key)
648+
})
571649
}
572650
573651
const handleGetDbKey = async () => {
@@ -640,6 +718,11 @@ const applyManualKeys = () => {
640718
}
641719
642720
const clearManualKeys = () => {
721+
logDecryptDebug('keys:clear', {
722+
active_account: activeKeyAccount.value,
723+
manual: summarizeKeyStateForLog(manualKeys.xor_key, manualKeys.aes_key),
724+
applied: summarizeKeyStateForLog(mediaKeys.xor_key, mediaKeys.aes_key)
725+
})
643726
manualKeys.xor_key = ''
644727
manualKeys.aes_key = ''
645728
manualKeyErrors.xor_key = ''
@@ -769,6 +852,10 @@ const handleDecrypt = async () => {
769852
return
770853
}
771854
855+
logDecryptDebug('decrypt:start', {
856+
db_storage_path: String(formData.db_storage_path || '').trim(),
857+
db_key_length: String(formData.key || '').trim().length
858+
})
772859
loading.value = true
773860
error.value = ''
774861
warning.value = ''
@@ -799,6 +886,10 @@ const handleDecrypt = async () => {
799886
if (match) mediaAccount.value = match[1]
800887
}
801888
} catch (e) {}
889+
logDecryptDebug('decrypt:completed-fallback', {
890+
media_account: mediaAccount.value,
891+
accounts: Object.keys(result.account_results || {})
892+
})
802893
803894
currentStep.value = 1
804895
await ensureKeysForAccount(mediaAccount.value)
@@ -877,6 +968,10 @@ const handleDecrypt = async () => {
877968
if (match) mediaAccount.value = match[1]
878969
}
879970
} catch (e) {}
971+
logDecryptDebug('decrypt:completed-sse', {
972+
media_account: mediaAccount.value,
973+
accounts: Object.keys(data.account_results || {})
974+
})
880975
881976
try {
882977
eventSource.close()
@@ -929,6 +1024,10 @@ const decryptAllImages = async () => {
9291024
mediaDecryptResult.value = null
9301025
error.value = ''
9311026
warning.value = ''
1027+
logDecryptDebug('media-decrypt:start', {
1028+
account: mediaAccount.value,
1029+
keys: summarizeKeyStateForLog(mediaKeys.xor_key, mediaKeys.aes_key)
1030+
})
9321031
9331032
// 重置进度
9341033
resetMediaDecryptProgress()
@@ -973,9 +1072,20 @@ const decryptAllImages = async () => {
9731072
decryptProgress.fail_count = data.fail_count
9741073
mediaDecryptResult.value = data
9751074
mediaDecrypting.value = false
1075+
logDecryptDebug('media-decrypt:complete', {
1076+
account: mediaAccount.value,
1077+
total: data.total,
1078+
success_count: data.success_count,
1079+
skip_count: data.skip_count,
1080+
fail_count: data.fail_count
1081+
})
9761082
closeMediaDecryptEventSource()
9771083
} else if (data.type === 'error') {
9781084
error.value = data.message
1085+
logDecryptDebug('media-decrypt:error-event', {
1086+
account: mediaAccount.value,
1087+
message: data.message
1088+
})
9791089
mediaDecrypting.value = false
9801090
closeMediaDecryptEventSource()
9811091
}
@@ -1016,19 +1126,30 @@ const goToMediaDecryptStep = async () => {
10161126
warning.value = ''
10171127
// 校验并应用(未填写则允许直接进入,后端会使用已保存密钥或报错提示)
10181128
const ok = applyManualKeys()
1129+
logDecryptDebug('media-step:apply-manual', {
1130+
account: mediaAccount.value,
1131+
ok,
1132+
manual: summarizeKeyStateForLog(manualKeys.xor_key, manualKeys.aes_key),
1133+
applied: summarizeKeyStateForLog(mediaKeys.xor_key, mediaKeys.aes_key),
1134+
errors: { ...manualKeyErrors }
1135+
})
10191136
if (!ok || manualKeyErrors.xor_key || manualKeyErrors.aes_key) return
10201137
10211138
// 用户已输入 XOR 时,自动保存一次,避免下次重复输入(失败不影响继续)
10221139
if (mediaKeys.xor_key) {
10231140
try {
10241141
const aesVal = String(mediaKeys.aes_key || '').trim()
1142+
logDecryptDebug('media-step:save-keys', {
1143+
account: mediaAccount.value,
1144+
keys: summarizeKeyStateForLog(mediaKeys.xor_key, aesVal)
1145+
})
10251146
await saveMediaKeys({
10261147
account: mediaAccount.value || null,
10271148
xor_key: mediaKeys.xor_key,
10281149
aes_key: aesVal ? aesVal : null
10291150
})
10301151
} catch (e) {
1031-
// ignore
1152+
logDecryptDebug('media-step:save-keys-error', { account: mediaAccount.value, error: formatLogError(e) })
10321153
}
10331154
}
10341155
currentStep.value = 2
@@ -1040,14 +1161,18 @@ const skipToChat = async () => {
10401161
const ok = applyManualKeys()
10411162
if (ok && mediaKeys.xor_key) {
10421163
const aesVal = String(mediaKeys.aes_key || '').trim()
1164+
logDecryptDebug('skip-chat:save-keys', {
1165+
account: mediaAccount.value,
1166+
keys: summarizeKeyStateForLog(mediaKeys.xor_key, aesVal)
1167+
})
10431168
await saveMediaKeys({
10441169
account: mediaAccount.value || null,
10451170
xor_key: mediaKeys.xor_key,
10461171
aes_key: aesVal ? aesVal : null
10471172
})
10481173
}
10491174
} catch (e) {
1050-
// ignore
1175+
logDecryptDebug('skip-chat:save-keys-error', { account: mediaAccount.value, error: formatLogError(e) })
10511176
}
10521177
navigateTo('/chat')
10531178
}
@@ -1056,6 +1181,7 @@ const skipToChat = async () => {
10561181
onMounted(async () => {
10571182
if (process.client && typeof window !== 'undefined') {
10581183
const selectedAccount = sessionStorage.getItem('selectedAccount')
1184+
logDecryptDebug('mounted:selected-account-raw', { raw: selectedAccount || '' })
10591185
if (selectedAccount) {
10601186
try {
10611187
const account = JSON.parse(selectedAccount)
@@ -1068,9 +1194,14 @@ onMounted(async () => {
10681194
}
10691195
// 清除sessionStorage
10701196
sessionStorage.removeItem('selectedAccount')
1197+
logDecryptDebug('mounted:selected-account-parsed', {
1198+
account_name: String(account.account_name || '').trim(),
1199+
data_dir: String(account.data_dir || '').trim()
1200+
})
10711201
await ensureKeysForAccount(mediaAccount.value)
10721202
} catch (e) {
10731203
console.error('解析账户信息失败:', e)
1204+
logDecryptDebug('mounted:selected-account-error', { error: formatLogError(e) })
10741205
}
10751206
}
10761207
}

0 commit comments

Comments
 (0)