mirror of
https://wget.la/https://github.com/Wxw-Gu/WechatExplorer
synced 2026-10-05 12:34:35 +08:00
Merge pull request #42 from yimizilu/fix/http-image-media-identifiers
fix: prevent HTTP image media ID collisions across conversations
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { createHash, randomUUID } from 'node:crypto'
|
||||
import { WechatDb, WechatMessage } from '../wechat-db'
|
||||
import {
|
||||
parseImageBufferDataUrlFromRow,
|
||||
@@ -156,7 +157,9 @@ export interface ImageMessageReference {
|
||||
}
|
||||
|
||||
const imageMessageReferences = new Map<string, ImageMessageReference | null>()
|
||||
let imageReferenceScope = randomUUID()
|
||||
|
||||
/** Replace the active database and invalidate connection-scoped lookup caches. */
|
||||
export function setChatDb(db: WechatDb | null): boolean {
|
||||
if (shutdownRequested) {
|
||||
db?.close()
|
||||
@@ -166,6 +169,7 @@ export function setChatDb(db: WechatDb | null): boolean {
|
||||
dbRef = db
|
||||
contactSearchIndexCache = null
|
||||
imageMessageReferences.clear()
|
||||
imageReferenceScope = randomUUID()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -367,6 +371,7 @@ export async function getContactAvatars(
|
||||
return client.getAvatarUrlsAsync(normalized)
|
||||
}
|
||||
|
||||
/** Format source rows and register image handles without merging recall archives. */
|
||||
function listSourceMessages(
|
||||
userMd5: string,
|
||||
startTime?: number,
|
||||
@@ -556,11 +561,28 @@ function listSourceMessages(
|
||||
: msg.mesLocalID || Math.random().toString()
|
||||
)
|
||||
const imageContent = contentData?.type === 'image' ? contentData : undefined
|
||||
// Local ids repeat across conversations. Scope media handles to this database
|
||||
// connection and image without changing the message id used by other clients.
|
||||
const mediaId = imageContent
|
||||
? `image:${createHash('sha256')
|
||||
.update(
|
||||
JSON.stringify([
|
||||
imageReferenceScope,
|
||||
userMd5,
|
||||
messageId,
|
||||
String(msg.serverId || ''),
|
||||
createTime,
|
||||
imageContent.md5 || '',
|
||||
imageContent.datName || ''
|
||||
])
|
||||
)
|
||||
.digest('hex')}`
|
||||
: ''
|
||||
const media = imageContent
|
||||
? {
|
||||
type: 'image' as const,
|
||||
available: Boolean(imageContent.md5 || imageContent.datName),
|
||||
url: `/api/v1/media/${encodeURIComponent(messageId)}`
|
||||
url: `/api/v1/media/${encodeURIComponent(mediaId)}`
|
||||
}
|
||||
: undefined
|
||||
if (imageContent && media) {
|
||||
@@ -571,6 +593,8 @@ function listSourceMessages(
|
||||
imageDatName: imageContent.datName,
|
||||
createTime
|
||||
}
|
||||
imageMessageReferences.set(mediaId, reference)
|
||||
// Keep old bare-id URLs working only while they are unambiguous.
|
||||
const previous = imageMessageReferences.get(messageId)
|
||||
if (
|
||||
previous &&
|
||||
@@ -598,7 +622,10 @@ function listSourceMessages(
|
||||
senderId,
|
||||
sessionId: username,
|
||||
localId,
|
||||
serverId: typeof msg.serverId === 'string' ? msg.serverId : undefined,
|
||||
serverId:
|
||||
typeof msg.serverId === 'string' || typeof msg.serverId === 'bigint'
|
||||
? String(msg.serverId)
|
||||
: undefined,
|
||||
createTime,
|
||||
recoveredFromRecallJournal,
|
||||
contentData,
|
||||
|
||||
Reference in New Issue
Block a user