Async + Multi Cache (#1741)
* fix: handle invalid signatureKeyPublic types in sender-key-state
- added extra check to ensure signatureKeyPublic is either a base64 string or a Buffer
- fallback to empty buffer when unexpected object type is received
- prevents ERR_INVALID_ARG_TYPE error in Buffer.from
* adjusted based on @jlucaso1 recommmendation
* fix: handle chain key objects for skmsg group message decryption
previously, some sender chain keys were stored or retrieved as plain objects
(e.g. { '0': 85, '1': 100, ... }) instead of Buffers. this caused
"ERR_INVALID_ARG_TYPE" during initial decryption of skmsg group messages.
this fixes any chain key object is converted to a proper Buffer
before being passed to SenderChainKey.
* fix: add more robust checks and fallbacks
* feat: async cache
feat: async caching
* fix: linting issues
* fix: mget logic
---------
Co-authored-by: αѕтяσχ11 <devastro0010@gmail.com>
This commit is contained in:
+35
-20
@@ -245,30 +245,40 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
}
|
||||
|
||||
const toFetch: string[] = []
|
||||
// Deduplicate and normalize JIDs
|
||||
jids = deduplicateLidPnJids(Array.from(new Set(jids)))
|
||||
const jidsWithUser = jids
|
||||
.map(jid => {
|
||||
const decoded = jidDecode(jid)
|
||||
const user = decoded?.user
|
||||
const device = decoded?.device
|
||||
const isExplicitDevice = typeof device === 'number' && device >= 0
|
||||
|
||||
for (let jid of jids) {
|
||||
const decoded = jidDecode(jid)
|
||||
const user = decoded?.user
|
||||
const device = decoded?.device
|
||||
const isExplicitDevice = typeof device === 'number' && device >= 0
|
||||
if (isExplicitDevice && user) {
|
||||
deviceResults.push({
|
||||
user,
|
||||
device,
|
||||
wireJid: jid
|
||||
})
|
||||
return null
|
||||
}
|
||||
|
||||
// Handle explicit device JIDs directly
|
||||
if (isExplicitDevice && user) {
|
||||
deviceResults.push({
|
||||
user,
|
||||
device,
|
||||
wireJid: jid // Preserve exact JID format for wire protocol
|
||||
})
|
||||
continue
|
||||
}
|
||||
jid = jidNormalizedUser(jid)
|
||||
return { jid, user }
|
||||
})
|
||||
.filter(jid => jid !== null)
|
||||
|
||||
// For user JIDs, normalize and prepare for device enumeration
|
||||
jid = jidNormalizedUser(jid)
|
||||
let mgetDevices: undefined | Record<string, JidWithDevice[] | undefined>
|
||||
|
||||
if (useCache && userDevicesCache.mget) {
|
||||
const usersToFetch = jidsWithUser.map(j => j?.user).filter(Boolean) as string[]
|
||||
mgetDevices = await userDevicesCache.mget(usersToFetch)
|
||||
}
|
||||
|
||||
for (const { jid, user } of jidsWithUser) {
|
||||
if (useCache) {
|
||||
const devices = userDevicesCache.get(user!) as JidWithDevice[]
|
||||
const devices =
|
||||
mgetDevices?.[user!] ||
|
||||
(userDevicesCache.mget ? undefined : ((await userDevicesCache.get(user!)) as JidWithDevice[]))
|
||||
if (devices) {
|
||||
const isLidJid = jid.includes('@lid')
|
||||
const devicesWithWire = devices.map(d => ({
|
||||
@@ -342,8 +352,13 @@ export const makeMessagesSocket = (config: SocketConfig) => {
|
||||
}
|
||||
}
|
||||
|
||||
for (const key in deviceMap) {
|
||||
userDevicesCache.set(key, deviceMap[key]!)
|
||||
if (userDevicesCache.mset) {
|
||||
// if the cache supports mset, we can set all devices in one go
|
||||
await userDevicesCache.mset(Object.entries(deviceMap).map(([key, value]) => ({ key, value })))
|
||||
} else {
|
||||
for (const key in deviceMap) {
|
||||
if (deviceMap[key]) await userDevicesCache.set(key, deviceMap[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user