general: Bring back USYNC calls for LID getting, and improve
This commit is contained in:
+65
-29
@@ -1,5 +1,5 @@
|
||||
import { LRUCache } from 'lru-cache'
|
||||
import type { SignalKeyStoreWithTransaction } from '../Types'
|
||||
import type { LIDMapping, SignalKeyStoreWithTransaction } from '../Types'
|
||||
import type { ILogger } from '../Utils/logger'
|
||||
import { isLidUser, isPnUser, jidDecode } from '../WABinary'
|
||||
|
||||
@@ -12,15 +12,22 @@ export class LIDMappingStore {
|
||||
private readonly keys: SignalKeyStoreWithTransaction
|
||||
private readonly logger: ILogger
|
||||
|
||||
constructor(keys: SignalKeyStoreWithTransaction, logger: ILogger) {
|
||||
private pnToLIDFunc?: (jids: string[]) => Promise<LIDMapping[] | undefined>
|
||||
|
||||
constructor(
|
||||
keys: SignalKeyStoreWithTransaction,
|
||||
logger: ILogger,
|
||||
pnToLIDFunc?: (jids: string[]) => Promise<LIDMapping[] | undefined>
|
||||
) {
|
||||
this.keys = keys
|
||||
this.pnToLIDFunc = pnToLIDFunc
|
||||
this.logger = logger
|
||||
}
|
||||
|
||||
/**
|
||||
* Store LID-PN mapping - USER LEVEL
|
||||
*/
|
||||
async storeLIDPNMappings(pairs: { lid: string; pn: string }[]): Promise<void> {
|
||||
async storeLIDPNMappings(pairs: LIDMapping[]): Promise<void> {
|
||||
// Validate inputs
|
||||
const pairMap: { [_: string]: string } = {}
|
||||
for (const { lid, pn } of pairs) {
|
||||
@@ -78,41 +85,70 @@ export class LIDMappingStore {
|
||||
* Get LID for PN - Returns device-specific LID based on user mapping
|
||||
*/
|
||||
async getLIDForPN(pn: string): Promise<string | null> {
|
||||
if (!isPnUser(pn)) return null
|
||||
return (await this.getLIDsForPNs([pn]))?.[0]?.lid || null
|
||||
}
|
||||
|
||||
const decoded = jidDecode(pn)
|
||||
if (!decoded) return null
|
||||
async getLIDsForPNs(pns: string[]): Promise<LIDMapping[] | null> {
|
||||
const usyncFetch: string[] = []
|
||||
// mapped from pn to lid mapping to prevent duplication in results later
|
||||
const successfulPairs: { [_: string]: LIDMapping } = {}
|
||||
for (const pn of pns) {
|
||||
if (!isPnUser(pn)) continue
|
||||
|
||||
// Check cache first for PN → LID mapping
|
||||
const pnUser = decoded.user
|
||||
let lidUser = this.mappingCache.get(`pn:${pnUser}`)
|
||||
const decoded = jidDecode(pn)
|
||||
if (!decoded) continue
|
||||
|
||||
if (!lidUser) {
|
||||
// Cache miss - check database
|
||||
const stored = await this.keys.get('lid-mapping', [pnUser])
|
||||
lidUser = stored[pnUser]
|
||||
// Check cache first for PN → LID mapping
|
||||
const pnUser = decoded.user
|
||||
let lidUser = this.mappingCache.get(`pn:${pnUser}`)
|
||||
|
||||
if (lidUser) {
|
||||
this.mappingCache.set(`pn:${pnUser}`, lidUser)
|
||||
this.mappingCache.set(`lid:${lidUser}`, pnUser)
|
||||
if (!lidUser) {
|
||||
// Cache miss - check database
|
||||
const stored = await this.keys.get('lid-mapping', [pnUser])
|
||||
lidUser = stored[pnUser]
|
||||
|
||||
if (lidUser) {
|
||||
this.mappingCache.set(`pn:${pnUser}`, lidUser)
|
||||
this.mappingCache.set(`lid:${lidUser}`, pnUser)
|
||||
} else {
|
||||
this.logger.trace(`No LID mapping found for PN user ${pnUser}; batch getting from USync`)
|
||||
usyncFetch.push(pn)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
lidUser = lidUser.toString()
|
||||
if (!lidUser) {
|
||||
this.logger.warn(`Invalid or empty LID user for PN ${pn}: lidUser = "${lidUser}"`)
|
||||
return null
|
||||
}
|
||||
|
||||
// Push the PN device ID to the LID to maintain device separation
|
||||
const pnDevice = decoded.device !== undefined ? decoded.device : 0
|
||||
const deviceSpecificLid = `${lidUser}:${pnDevice}@lid`
|
||||
|
||||
this.logger.trace(`getLIDForPN: ${pn} → ${deviceSpecificLid} (user mapping with device ${pnDevice})`)
|
||||
successfulPairs[pn] = { lid: deviceSpecificLid, pn }
|
||||
}
|
||||
|
||||
console.log(this.pnToLIDFunc)
|
||||
if (usyncFetch.length > 0) {
|
||||
console.log(usyncFetch)
|
||||
const result = await this.pnToLIDFunc?.(usyncFetch) // this function already adds LIDs to mapping
|
||||
if (result && result.length > 0) {
|
||||
this.storeLIDPNMappings(result)
|
||||
for (const pair of result) {
|
||||
const lidUser = jidDecode(pair.lid)?.user
|
||||
if (lidUser) {
|
||||
successfulPairs[pair.pn] = pair
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.logger.trace(`No LID mapping found for PN user ${pnUser}`)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
lidUser = lidUser.toString()
|
||||
if (!lidUser) {
|
||||
this.logger.warn(`Invalid or empty LID user for PN ${pn}: lidUser = "${lidUser}"`)
|
||||
return null
|
||||
}
|
||||
|
||||
// Push the PN device ID to the LID to maintain device separation
|
||||
const pnDevice = decoded.device !== undefined ? decoded.device : 0
|
||||
const deviceSpecificLid = `${lidUser}:${pnDevice}@lid`
|
||||
|
||||
this.logger.trace(`getLIDForPN: ${pn} → ${deviceSpecificLid} (user mapping with device ${pnDevice})`)
|
||||
return deviceSpecificLid
|
||||
return Object.values(successfulPairs)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user