feat: integrate tctoken lifecycle with expiration, pruning and re-issuance (PR #2339)
Surgical integration of WhiskeySockets/Baileys PR #2339 preserving all InfiniteAPI customizations (biz nodes, DSM skip, carousel, Prometheus, circuit breaker, LID mapping, CTWA recovery, identity debounce). Changes: - tc-token-utils.ts: rolling bucket expiration (28d/4 buckets), LID resolution, monotonicity guard, storeTcTokensFromIqResult parser - messages-send.ts: proactive fetch if missing/expired, fire-and-forget re-issuance on bucket boundary, getPrivacyTokens timestamp param - messages-recv.ts: persistent JID index for cross-session pruning, pruneExpiredTcTokens on connect (max 1x/24h), session_refreshed re-issuance, error 463/479 handling in handleBadAck - chats.ts: self-detection in profilePictureUrl, LID resolver in presenceSubscribe - socket.ts: granular stream error logging (device_removed, xml, ack) - Auth.ts: senderTimestamp field on tctoken type - Types/index.ts: sessionInvalidated = 516 disconnect reason - decode-wa-message.ts: SERVER_ERROR_CODES constant (463, 479, 421, 475) - generics.ts: enhanced getErrorCodeFromStreamError with device_removed - baileys-logger.ts: logTcToken function following [BAILEYS] prefix pattern Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+27
-4
@@ -50,6 +50,8 @@ import {
|
||||
type BinaryNode,
|
||||
getBinaryNodeChild,
|
||||
getBinaryNodeChildren,
|
||||
isLidUser,
|
||||
isPnUser,
|
||||
jidDecode,
|
||||
jidNormalizedUser,
|
||||
reduceBinaryNodeToDictionary,
|
||||
@@ -695,9 +697,26 @@ export const makeChatsSocket = (config: SocketConfig) => {
|
||||
const profilePictureUrl = async (jid: string, type: 'preview' | 'image' = 'preview', timeoutMs?: number) => {
|
||||
const baseContent: BinaryNode[] = [{ tag: 'picture', attrs: { type, query: 'url' } }]
|
||||
|
||||
const tcTokenContent = await buildTcTokenFromJid({ authState, jid, baseContent })
|
||||
// WA Web only includes tctoken for user JIDs (not groups/newsletters)
|
||||
// and never for own profile pic (Chat model for self has no tcToken).
|
||||
// Including tctoken for own JID causes the server to never respond.
|
||||
const normalizedJid = jidNormalizedUser(jid)
|
||||
const isUserJid = isPnUser(normalizedJid) || isLidUser(normalizedJid)
|
||||
const me = authState.creds.me
|
||||
const isSelf =
|
||||
me && (normalizedJid === jidNormalizedUser(me.id) || (me.lid && normalizedJid === jidNormalizedUser(me.lid)))
|
||||
let content: BinaryNode[] | undefined = baseContent
|
||||
|
||||
jid = jidNormalizedUser(jid)
|
||||
if(isUserJid && !isSelf) {
|
||||
content = await buildTcTokenFromJid({
|
||||
authState,
|
||||
jid: normalizedJid,
|
||||
baseContent,
|
||||
getLIDForPN: signalRepository.lidMapping.getLIDForPN.bind(signalRepository.lidMapping)
|
||||
})
|
||||
}
|
||||
|
||||
jid = normalizedJid
|
||||
const result = await query(
|
||||
{
|
||||
tag: 'iq',
|
||||
@@ -707,7 +726,7 @@ export const makeChatsSocket = (config: SocketConfig) => {
|
||||
type: 'get',
|
||||
xmlns: 'w:profile:picture'
|
||||
},
|
||||
content: tcTokenContent
|
||||
content
|
||||
},
|
||||
timeoutMs
|
||||
)
|
||||
@@ -799,7 +818,11 @@ export const makeChatsSocket = (config: SocketConfig) => {
|
||||
* @param tcToken token for subscription, use if present
|
||||
*/
|
||||
const presenceSubscribe = async (toJid: string) => {
|
||||
const tcTokenContent = await buildTcTokenFromJid({ authState, jid: toJid })
|
||||
const tcTokenContent = await buildTcTokenFromJid({
|
||||
authState,
|
||||
jid: toJid,
|
||||
getLIDForPN: signalRepository.lidMapping.getLIDForPN.bind(signalRepository.lidMapping)
|
||||
})
|
||||
|
||||
return sendNode({
|
||||
tag: 'presence',
|
||||
|
||||
Reference in New Issue
Block a user