project: Move to ESM Modules
This commit is contained in:
+10
-9
@@ -12,7 +12,7 @@ import type {
|
||||
} from '../Types'
|
||||
import { Curve, signedKeyPair } from './crypto'
|
||||
import { delay, generateRegistrationId } from './generics'
|
||||
import { ILogger } from './logger'
|
||||
import type { ILogger } from './logger'
|
||||
|
||||
/**
|
||||
* Adds caching capability to a SignalKeyStore
|
||||
@@ -67,8 +67,8 @@ export function makeCacheableSignalKeyStore(
|
||||
async set(data) {
|
||||
let keys = 0
|
||||
for (const type in data) {
|
||||
for (const id in data[type]) {
|
||||
cache.set(getUniqueId(type, id), data[type][id])
|
||||
for (const id in data[type as keyof SignalDataTypeMap]) {
|
||||
cache.set(getUniqueId(type, id), data[type as keyof SignalDataTypeMap]![id])
|
||||
keys += 1
|
||||
}
|
||||
}
|
||||
@@ -118,7 +118,7 @@ export const addTransactionCapability = (
|
||||
Object.assign(transactionCache[type]!, result)
|
||||
}
|
||||
|
||||
return ids.reduce((dict, id) => {
|
||||
return ids.reduce((dict: { [T in string]: any }, id) => {
|
||||
const value = transactionCache[type]?.[id]
|
||||
if (value) {
|
||||
dict[id] = value
|
||||
@@ -133,12 +133,13 @@ export const addTransactionCapability = (
|
||||
set: data => {
|
||||
if (isInTransaction()) {
|
||||
logger.trace({ types: Object.keys(data) }, 'caching in transaction')
|
||||
for (const key in data) {
|
||||
transactionCache[key] = transactionCache[key] || {}
|
||||
Object.assign(transactionCache[key], data[key])
|
||||
for (const key_ in data) {
|
||||
const key = key_ as keyof SignalDataTypeMap
|
||||
transactionCache[key] = transactionCache[key] || ({} as any)
|
||||
Object.assign(transactionCache[key]!, data[key])
|
||||
|
||||
mutations[key] = mutations[key] || {}
|
||||
Object.assign(mutations[key], data[key])
|
||||
mutations[key] = mutations[key] || ({} as any)
|
||||
Object.assign(mutations[key]!, data[key])
|
||||
}
|
||||
} else {
|
||||
return state.set(data)
|
||||
|
||||
@@ -18,7 +18,7 @@ export const captureEventStream = (ev: BaileysEventEmitter, filename: string) =>
|
||||
// monkey patch eventemitter to capture all events
|
||||
ev.emit = function (...args: any[]) {
|
||||
const content = JSON.stringify({ timestamp: Date.now(), event: args[0], data: args[1] }) + '\n'
|
||||
const result = oldEmit.apply(ev, args)
|
||||
const result = oldEmit.apply(ev, args as any)
|
||||
|
||||
writeMutex.mutex(async () => {
|
||||
await writeFile(filename, content, { flag: 'a' })
|
||||
|
||||
@@ -3,7 +3,7 @@ import { createHash } from 'crypto'
|
||||
import { createWriteStream, promises as fs } from 'fs'
|
||||
import { tmpdir } from 'os'
|
||||
import { join } from 'path'
|
||||
import {
|
||||
import type {
|
||||
CatalogCollection,
|
||||
CatalogStatus,
|
||||
OrderDetails,
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
WAMediaUpload,
|
||||
WAMediaUploadFunction
|
||||
} from '../Types'
|
||||
import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, getBinaryNodeChildString } from '../WABinary'
|
||||
import { type BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, getBinaryNodeChildString } from '../WABinary'
|
||||
import { generateMessageIDV2 } from './generics'
|
||||
import { getStream, getUrlFromDirectPath } from './messages-media'
|
||||
|
||||
|
||||
+18
-14
@@ -1,7 +1,7 @@
|
||||
import { Boom } from '@hapi/boom'
|
||||
import { AxiosRequestConfig } from 'axios'
|
||||
import type { AxiosRequestConfig } from 'axios'
|
||||
import { proto } from '../../WAProto'
|
||||
import {
|
||||
import type {
|
||||
BaileysEventEmitter,
|
||||
Chat,
|
||||
ChatModification,
|
||||
@@ -14,9 +14,13 @@ import {
|
||||
WAPatchCreate,
|
||||
WAPatchName
|
||||
} from '../Types'
|
||||
import { ChatLabelAssociation, LabelAssociationType, MessageLabelAssociation } from '../Types/LabelAssociation'
|
||||
import {
|
||||
BinaryNode,
|
||||
type ChatLabelAssociation,
|
||||
LabelAssociationType,
|
||||
type MessageLabelAssociation
|
||||
} from '../Types/LabelAssociation'
|
||||
import {
|
||||
type BinaryNode,
|
||||
getBinaryNodeChild,
|
||||
getBinaryNodeChildren,
|
||||
isJidGroup,
|
||||
@@ -25,7 +29,7 @@ import {
|
||||
} from '../WABinary'
|
||||
import { aesDecrypt, aesEncrypt, hkdf, hmacSign } from './crypto'
|
||||
import { toNumber } from './generics'
|
||||
import { ILogger } from './logger'
|
||||
import type { ILogger } from './logger'
|
||||
import { LT_HASH_ANTI_TAMPERING } from './lt-hash'
|
||||
import { downloadContentFromMessage } from './messages-media'
|
||||
|
||||
@@ -343,7 +347,7 @@ export const extractSyncdPatches = async (result: BinaryNode, options: AxiosRequ
|
||||
|
||||
const syncd = proto.SyncdPatch.decode(content as Uint8Array)
|
||||
if (!syncd.version) {
|
||||
syncd.version = { version: +collectionNode.attrs.version + 1 }
|
||||
syncd.version = { version: +collectionNode.attrs.version! + 1 }
|
||||
}
|
||||
|
||||
syncds.push(syncd)
|
||||
@@ -616,7 +620,7 @@ export const chatModificationToAppPatch = (mod: ChatModification, jid: string) =
|
||||
operation: mod.contact ? OP.SET : OP.REMOVE
|
||||
}
|
||||
} else if ('star' in mod) {
|
||||
const key = mod.star.messages[0]
|
||||
const key = mod.star.messages[0]!
|
||||
patch = {
|
||||
syncAction: {
|
||||
starAction: {
|
||||
@@ -753,7 +757,7 @@ export const processSyncAction = (
|
||||
{
|
||||
id,
|
||||
muteEndTime: action.muteAction?.muted ? toNumber(action.muteAction.muteEndTimestamp) : null,
|
||||
conditional: getChatUpdateConditional(id, undefined)
|
||||
conditional: getChatUpdateConditional(id!, undefined)
|
||||
}
|
||||
])
|
||||
} else if (action?.archiveChatAction || type === 'archive' || type === 'unarchive') {
|
||||
@@ -782,7 +786,7 @@ export const processSyncAction = (
|
||||
{
|
||||
id,
|
||||
archived: isArchived,
|
||||
conditional: getChatUpdateConditional(id, msgRange)
|
||||
conditional: getChatUpdateConditional(id!, msgRange)
|
||||
}
|
||||
])
|
||||
} else if (action?.markChatAsReadAction) {
|
||||
@@ -796,7 +800,7 @@ export const processSyncAction = (
|
||||
{
|
||||
id,
|
||||
unreadCount: isNullUpdate ? null : !!markReadAction?.read ? 0 : -1,
|
||||
conditional: getChatUpdateConditional(id, markReadAction?.messageRange)
|
||||
conditional: getChatUpdateConditional(id!, markReadAction?.messageRange)
|
||||
}
|
||||
])
|
||||
} else if (action?.deleteMessageForMeAction || type === 'deleteMessageForMe') {
|
||||
@@ -812,7 +816,7 @@ export const processSyncAction = (
|
||||
} else if (action?.contactAction) {
|
||||
ev.emit('contacts.upsert', [
|
||||
{
|
||||
id: id,
|
||||
id: id!,
|
||||
name: action.contactAction.fullName!,
|
||||
lid: action.contactAction.lidJid || undefined,
|
||||
jid: isJidUser(id) ? id : undefined
|
||||
@@ -828,7 +832,7 @@ export const processSyncAction = (
|
||||
{
|
||||
id,
|
||||
pinned: action.pinAction?.pinned ? toNumber(action.timestamp) : null,
|
||||
conditional: getChatUpdateConditional(id, undefined)
|
||||
conditional: getChatUpdateConditional(id!, undefined)
|
||||
}
|
||||
])
|
||||
} else if (action?.unarchiveChatsSetting) {
|
||||
@@ -853,13 +857,13 @@ export const processSyncAction = (
|
||||
])
|
||||
} else if (action?.deleteChatAction || type === 'deleteChat') {
|
||||
if (!isInitialSync) {
|
||||
ev.emit('chats.delete', [id])
|
||||
ev.emit('chats.delete', [id!])
|
||||
}
|
||||
} else if (action?.labelEditAction) {
|
||||
const { name, color, deleted, predefinedId } = action.labelEditAction
|
||||
|
||||
ev.emit('labels.edit', {
|
||||
id,
|
||||
id: id!,
|
||||
name: name!,
|
||||
color: color!,
|
||||
deleted: deleted!,
|
||||
|
||||
+2
-1
@@ -1,7 +1,8 @@
|
||||
import { createCipheriv, createDecipheriv, createHash, createHmac, randomBytes } from 'crypto'
|
||||
/* @ts-ignore */
|
||||
import * as libsignal from 'libsignal'
|
||||
import { KEY_BUNDLE_TYPE } from '../Defaults'
|
||||
import { KeyPair } from '../Types'
|
||||
import type { KeyPair } from '../Types'
|
||||
|
||||
// insure browser & node compatibility
|
||||
const { subtle } = globalThis.crypto
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Boom } from '@hapi/boom'
|
||||
import { proto } from '../../WAProto'
|
||||
import { SignalRepository, WAMessage, WAMessageKey } from '../Types'
|
||||
import type { SignalRepository, WAMessage, WAMessageKey } from '../Types'
|
||||
import {
|
||||
areJidsSameUser,
|
||||
BinaryNode,
|
||||
type BinaryNode,
|
||||
isJidBroadcast,
|
||||
isJidGroup,
|
||||
isJidMetaIa,
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
isLidUser
|
||||
} from '../WABinary'
|
||||
import { unpadRandomMax16 } from './generics'
|
||||
import { ILogger } from './logger'
|
||||
import type { ILogger } from './logger'
|
||||
|
||||
export const NO_MESSAGE_FOUND_ERROR_TEXT = 'Message absent from node'
|
||||
export const MISSING_KEYS_ERROR_TEXT = 'Key used already or never filled'
|
||||
@@ -62,17 +62,17 @@ export function decodeMessageNode(stanza: BinaryNode, meId: string, meLid: strin
|
||||
|
||||
if (isJidUser(from) || isLidUser(from)) {
|
||||
if (recipient && !isJidMetaIa(recipient)) {
|
||||
if (!isMe(from) && !isMeLid(from)) {
|
||||
if (!isMe(from!) && !isMeLid(from!)) {
|
||||
throw new Boom('receipient present, but msg not from me', { data: stanza })
|
||||
}
|
||||
|
||||
chatId = recipient
|
||||
} else {
|
||||
chatId = from
|
||||
chatId = from!
|
||||
}
|
||||
|
||||
msgType = 'chat'
|
||||
author = from
|
||||
author = from!
|
||||
} else if (isJidGroup(from)) {
|
||||
if (!participant) {
|
||||
throw new Boom('No participant in group message')
|
||||
@@ -80,30 +80,30 @@ export function decodeMessageNode(stanza: BinaryNode, meId: string, meLid: strin
|
||||
|
||||
msgType = 'group'
|
||||
author = participant
|
||||
chatId = from
|
||||
chatId = from!
|
||||
} else if (isJidBroadcast(from)) {
|
||||
if (!participant) {
|
||||
throw new Boom('No participant in group message')
|
||||
}
|
||||
|
||||
const isParticipantMe = isMe(participant)
|
||||
if (isJidStatusBroadcast(from)) {
|
||||
if (isJidStatusBroadcast(from!)) {
|
||||
msgType = isParticipantMe ? 'direct_peer_status' : 'other_status'
|
||||
} else {
|
||||
msgType = isParticipantMe ? 'peer_broadcast' : 'other_broadcast'
|
||||
}
|
||||
|
||||
chatId = from
|
||||
chatId = from!
|
||||
author = participant
|
||||
} else if (isJidNewsletter(from)) {
|
||||
msgType = 'newsletter'
|
||||
chatId = from
|
||||
author = from
|
||||
chatId = from!
|
||||
author = from!
|
||||
} else {
|
||||
throw new Boom('Unknown message type', { data: stanza })
|
||||
}
|
||||
|
||||
const fromMe = (isLidUser(from) ? isMeLid : isMe)(stanza.attrs.participant || stanza.attrs.from)
|
||||
const fromMe = (isLidUser(from) ? isMeLid : isMe)((stanza.attrs.participant || stanza.attrs.from)!)
|
||||
const pushname = stanza?.attrs?.notify
|
||||
|
||||
const key: WAMessageKey = {
|
||||
@@ -120,7 +120,7 @@ export function decodeMessageNode(stanza: BinaryNode, meId: string, meLid: strin
|
||||
|
||||
const fullMessage: WAMessage = {
|
||||
key,
|
||||
messageTimestamp: +stanza.attrs.t,
|
||||
messageTimestamp: +stanza.attrs.t!,
|
||||
pushName: pushname,
|
||||
broadcast: isJidBroadcast(from)
|
||||
}
|
||||
@@ -221,7 +221,7 @@ export const decryptMessageNode = (
|
||||
} else {
|
||||
fullMessage.message = msg
|
||||
}
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
logger.error({ key: fullMessage.key, err }, 'failed to decrypt message')
|
||||
fullMessage.messageStubType = proto.WebMessageInfo.StubType.CIPHERTEXT
|
||||
fullMessage.messageStubParameters = [err.message]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import EventEmitter from 'events'
|
||||
import { proto } from '../../WAProto'
|
||||
import {
|
||||
import type {
|
||||
BaileysEvent,
|
||||
BaileysEventEmitter,
|
||||
BaileysEventMap,
|
||||
@@ -8,11 +8,11 @@ import {
|
||||
Chat,
|
||||
ChatUpdate,
|
||||
Contact,
|
||||
WAMessage,
|
||||
WAMessageStatus
|
||||
WAMessage
|
||||
} from '../Types'
|
||||
import { WAMessageStatus } from '../Types'
|
||||
import { trimUndefined } from './generics'
|
||||
import { ILogger } from './logger'
|
||||
import type { ILogger } from './logger'
|
||||
import { updateMessageWithReaction, updateMessageWithReceipt } from './messages'
|
||||
import { isRealMessage, shouldIncrementChatUnread } from './process-message'
|
||||
|
||||
@@ -79,7 +79,7 @@ export const makeEventBuffer = (logger: ILogger): BaileysBufferableEventEmitter
|
||||
// take the generic event and fire it as a baileys event
|
||||
ev.on('event', (map: BaileysEventData) => {
|
||||
for (const event in map) {
|
||||
ev.emit(event, map[event])
|
||||
ev.emit(event, map[event as keyof BaileysEventMap])
|
||||
}
|
||||
})
|
||||
|
||||
@@ -249,7 +249,7 @@ function append<E extends BufferableEvent>(
|
||||
for (const chat of eventData as Chat[]) {
|
||||
let upsert = data.chatUpserts[chat.id]
|
||||
if (!upsert) {
|
||||
upsert = data.historySets[chat.id]
|
||||
upsert = data.historySets.chats[chat.id]
|
||||
if (upsert) {
|
||||
logger.debug({ chatId: chat.id }, 'absorbed chat upsert in chat set')
|
||||
}
|
||||
@@ -339,7 +339,7 @@ function append<E extends BufferableEvent>(
|
||||
}
|
||||
|
||||
if (data.contactUpdates[contact.id]) {
|
||||
upsert = Object.assign(data.contactUpdates[contact.id], trimUndefined(contact)) as Contact
|
||||
upsert = Object.assign(data.contactUpdates[contact.id]!, trimUndefined(contact)) as Contact
|
||||
delete data.contactUpdates[contact.id]
|
||||
}
|
||||
}
|
||||
@@ -550,7 +550,7 @@ function consolidateEvents(data: BufferedEventData) {
|
||||
|
||||
const messageUpsertList = Object.values(data.messageUpserts)
|
||||
if (messageUpsertList.length) {
|
||||
const type = messageUpsertList[0].type
|
||||
const type = messageUpsertList[0]!.type
|
||||
map['messages.upsert'] = {
|
||||
messages: messageUpsertList.map(m => m.message),
|
||||
type
|
||||
|
||||
+20
-14
@@ -1,19 +1,19 @@
|
||||
import { Boom } from '@hapi/boom'
|
||||
import axios, { AxiosRequestConfig } from 'axios'
|
||||
import axios, { type AxiosRequestConfig } from 'axios'
|
||||
import { createHash, randomBytes } from 'crypto'
|
||||
import { platform, release } from 'os'
|
||||
import { proto } from '../../WAProto'
|
||||
import { version as baileysVersion } from '../Defaults/baileys-version.json'
|
||||
import {
|
||||
import type {
|
||||
BaileysEventEmitter,
|
||||
BaileysEventMap,
|
||||
BrowsersMap,
|
||||
ConnectionState,
|
||||
DisconnectReason,
|
||||
WACallUpdateType,
|
||||
WAVersion
|
||||
} from '../Types'
|
||||
import { BinaryNode, getAllBinaryNodeChildren, jidDecode } from '../WABinary'
|
||||
import { DisconnectReason } from '../Types'
|
||||
import { type BinaryNode, getAllBinaryNodeChildren, jidDecode } from '../WABinary'
|
||||
|
||||
const PLATFORM_MAP = {
|
||||
aix: 'AIX',
|
||||
@@ -22,7 +22,11 @@ const PLATFORM_MAP = {
|
||||
android: 'Android',
|
||||
freebsd: 'FreeBSD',
|
||||
openbsd: 'OpenBSD',
|
||||
sunos: 'Solaris'
|
||||
sunos: 'Solaris',
|
||||
linux: undefined,
|
||||
haiku: undefined,
|
||||
cygwin: undefined,
|
||||
netbsd: undefined
|
||||
}
|
||||
|
||||
export const Browsers: BrowsersMap = {
|
||||
@@ -35,13 +39,13 @@ export const Browsers: BrowsersMap = {
|
||||
}
|
||||
|
||||
export const getPlatformId = (browser: string) => {
|
||||
const platformType = proto.DeviceProps.PlatformType[browser.toUpperCase()]
|
||||
const platformType = proto.DeviceProps.PlatformType[browser.toUpperCase() as any]
|
||||
return platformType ? platformType.toString() : '1' //chrome
|
||||
}
|
||||
|
||||
export const BufferJSON = {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
replacer: (k, value: any) => {
|
||||
replacer: (k: any, value: any) => {
|
||||
if (Buffer.isBuffer(value) || value instanceof Uint8Array || value?.type === 'Buffer') {
|
||||
return { type: 'Buffer', data: Buffer.from(value?.data || value).toString('base64') }
|
||||
}
|
||||
@@ -50,7 +54,7 @@ export const BufferJSON = {
|
||||
},
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
reviver: (_, value: any) => {
|
||||
reviver: (_: any, value: any) => {
|
||||
if (typeof value === 'object' && !!value && (value.buffer === true || value.type === 'Buffer')) {
|
||||
const val = value.data || value.value
|
||||
return typeof val === 'string' ? Buffer.from(val, 'base64') : Buffer.from(val || [])
|
||||
@@ -65,8 +69,10 @@ export const getKeyAuthor = (key: proto.IMessageKey | undefined | null, meId = '
|
||||
|
||||
export const writeRandomPadMax16 = (msg: Uint8Array) => {
|
||||
const pad = randomBytes(1)
|
||||
pad[0] &= 0xf
|
||||
if (!pad[0]) {
|
||||
|
||||
if (pad[0]) {
|
||||
pad[0] &= 0xf
|
||||
} else {
|
||||
pad[0] = 0xf
|
||||
}
|
||||
|
||||
@@ -79,7 +85,7 @@ export const unpadRandomMax16 = (e: Uint8Array | Buffer) => {
|
||||
throw new Error('unpadPkcs7 given empty bytes')
|
||||
}
|
||||
|
||||
var r = t[t.length - 1]
|
||||
var r = t[t.length - 1]!
|
||||
if (r > t.length) {
|
||||
throw new Error(`unpad given ${t.length} bytes, but pad is ${r}`)
|
||||
}
|
||||
@@ -90,7 +96,7 @@ export const unpadRandomMax16 = (e: Uint8Array | Buffer) => {
|
||||
export const encodeWAMessage = (message: proto.IMessage) => writeRandomPadMax16(proto.Message.encode(message).finish())
|
||||
|
||||
export const generateRegistrationId = (): number => {
|
||||
return Uint16Array.from(randomBytes(2))[0] & 16383
|
||||
return Uint16Array.from(randomBytes(2))[0]! & 16383
|
||||
}
|
||||
|
||||
export const encodeBigEndian = (e: number, t = 4) => {
|
||||
@@ -135,7 +141,7 @@ export const delay = (ms: number) => delayCancellable(ms).delay
|
||||
export const delayCancellable = (ms: number) => {
|
||||
const stack = new Error().stack
|
||||
let timeout: NodeJS.Timeout
|
||||
let reject: (error) => void
|
||||
let reject: (error: any) => void
|
||||
const delay: Promise<void> = new Promise((resolve, _reject) => {
|
||||
timeout = setTimeout(resolve, ms)
|
||||
reject = _reject
|
||||
@@ -157,7 +163,7 @@ export const delayCancellable = (ms: number) => {
|
||||
|
||||
export async function promiseTimeout<T>(
|
||||
ms: number | undefined,
|
||||
promise: (resolve: (v: T) => void, reject: (error) => void) => void
|
||||
promise: (resolve: (v: T) => void, reject: (error: any) => void) => void
|
||||
) {
|
||||
if (!ms) {
|
||||
return new Promise(promise)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { AxiosRequestConfig } from 'axios'
|
||||
import type { AxiosRequestConfig } from 'axios'
|
||||
import { promisify } from 'util'
|
||||
import { inflate } from 'zlib'
|
||||
import { proto } from '../../WAProto'
|
||||
import { Chat, Contact, WAMessageStubType } from '../Types'
|
||||
import type { Chat, Contact } from '../Types'
|
||||
import { WAMessageStubType } from '../Types'
|
||||
import { isJidUser } from '../WABinary'
|
||||
import { toNumber } from './generics'
|
||||
import { normalizeMessageContent } from './messages'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AxiosRequestConfig } from 'axios'
|
||||
import { WAMediaUploadFunction, WAUrlInfo } from '../Types'
|
||||
import { ILogger } from './logger'
|
||||
import type { AxiosRequestConfig } from 'axios'
|
||||
import type { WAMediaUploadFunction, WAUrlInfo } from '../Types'
|
||||
import type { ILogger } from './logger'
|
||||
import { prepareWAMessageMedia } from './messages'
|
||||
import { extractImageThumb, getHttpStream } from './messages-media'
|
||||
|
||||
@@ -85,7 +85,7 @@ export const getUrlInfo = async (
|
||||
|
||||
if (opts.uploadImage) {
|
||||
const { imageMessage } = await prepareWAMessageMedia(
|
||||
{ image: { url: image } },
|
||||
{ image: { url: image! } },
|
||||
{
|
||||
upload: opts.uploadImage,
|
||||
mediaTypeOverride: 'thumbnail-link',
|
||||
@@ -97,14 +97,14 @@ export const getUrlInfo = async (
|
||||
} else {
|
||||
try {
|
||||
urlInfo.jpegThumbnail = image ? (await getCompressedJpegThumbnail(image, opts)).buffer : undefined
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
opts.logger?.debug({ err: error.stack, url: previewLink }, 'error in generating thumbnail')
|
||||
}
|
||||
}
|
||||
|
||||
return urlInfo
|
||||
}
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
if (!error.message.includes('receive a valid')) {
|
||||
throw error
|
||||
}
|
||||
|
||||
+5
-5
@@ -3,11 +3,11 @@ import P from 'pino'
|
||||
export interface ILogger {
|
||||
level: string
|
||||
child(obj: Record<string, unknown>): ILogger
|
||||
trace(obj: unknown, msg?: string)
|
||||
debug(obj: unknown, msg?: string)
|
||||
info(obj: unknown, msg?: string)
|
||||
warn(obj: unknown, msg?: string)
|
||||
error(obj: unknown, msg?: string)
|
||||
trace(obj: unknown, msg?: string): void
|
||||
debug(obj: unknown, msg?: string): void
|
||||
info(obj: unknown, msg?: string): void
|
||||
warn(obj: unknown, msg?: string): void
|
||||
error(obj: unknown, msg?: string): void
|
||||
}
|
||||
|
||||
export default P({ timestamp: () => `,"time":"${new Date().toJSON()}"` })
|
||||
|
||||
+35
-30
@@ -5,56 +5,61 @@ import { hkdf } from './crypto'
|
||||
* over a series of mutations. You can add/remove mutations and it'll return a hash equal to
|
||||
* if the same series of mutations was made sequentially.
|
||||
*/
|
||||
|
||||
const o = 128
|
||||
|
||||
class d {
|
||||
class LTHash {
|
||||
salt: string
|
||||
|
||||
constructor(e: string) {
|
||||
this.salt = e
|
||||
}
|
||||
add(e, t) {
|
||||
var r = this
|
||||
|
||||
async add(e: ArrayBuffer, t: ArrayBuffer[]): Promise<ArrayBuffer> {
|
||||
for (const item of t) {
|
||||
e = r._addSingle(e, item)
|
||||
e = await this._addSingle(e, item)
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
subtract(e, t) {
|
||||
var r = this
|
||||
|
||||
async subtract(e: ArrayBuffer, t: ArrayBuffer[]): Promise<ArrayBuffer> {
|
||||
for (const item of t) {
|
||||
e = r._subtractSingle(e, item)
|
||||
e = await this._subtractSingle(e, item)
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
subtractThenAdd(e, t, r) {
|
||||
var n = this
|
||||
return n.add(n.subtract(e, r), t)
|
||||
}
|
||||
async _addSingle(e, t) {
|
||||
var r = this
|
||||
const n = new Uint8Array(await hkdf(Buffer.from(t), o, { info: r.salt })).buffer
|
||||
return r.performPointwiseWithOverflow(await e, n, (e, t) => e + t)
|
||||
}
|
||||
async _subtractSingle(e, t) {
|
||||
var r = this
|
||||
|
||||
const n = new Uint8Array(await hkdf(Buffer.from(t), o, { info: r.salt })).buffer
|
||||
return r.performPointwiseWithOverflow(await e, n, (e, t) => e - t)
|
||||
async subtractThenAdd(e: ArrayBuffer, addList: ArrayBuffer[], subtractList: ArrayBuffer[]): Promise<ArrayBuffer> {
|
||||
const subtracted = await this.subtract(e, subtractList)
|
||||
return this.add(subtracted, addList)
|
||||
}
|
||||
performPointwiseWithOverflow(e, t, r) {
|
||||
const n = new DataView(e),
|
||||
i = new DataView(t),
|
||||
a = new ArrayBuffer(n.byteLength),
|
||||
s = new DataView(a)
|
||||
for (let e = 0; e < n.byteLength; e += 2) {
|
||||
s.setUint16(e, r(n.getUint16(e, !0), i.getUint16(e, !0)), !0)
|
||||
|
||||
private async _addSingle(e: ArrayBuffer, t: ArrayBuffer): Promise<ArrayBuffer> {
|
||||
const derived = new Uint8Array(await hkdf(Buffer.from(t), o, { info: this.salt })).buffer
|
||||
return this.performPointwiseWithOverflow(e, derived, (a, b) => a + b)
|
||||
}
|
||||
|
||||
private async _subtractSingle(e: ArrayBuffer, t: ArrayBuffer): Promise<ArrayBuffer> {
|
||||
const derived = new Uint8Array(await hkdf(Buffer.from(t), o, { info: this.salt })).buffer
|
||||
return this.performPointwiseWithOverflow(e, derived, (a, b) => a - b)
|
||||
}
|
||||
|
||||
private performPointwiseWithOverflow(
|
||||
e: ArrayBuffer,
|
||||
t: ArrayBuffer,
|
||||
op: (a: number, b: number) => number
|
||||
): ArrayBuffer {
|
||||
const n = new DataView(e)
|
||||
const i = new DataView(t)
|
||||
const out = new ArrayBuffer(n.byteLength)
|
||||
const s = new DataView(out)
|
||||
|
||||
for (let offset = 0; offset < n.byteLength; offset += 2) {
|
||||
s.setUint16(offset, op(n.getUint16(offset, true), i.getUint16(offset, true)), true)
|
||||
}
|
||||
|
||||
return a
|
||||
return out
|
||||
}
|
||||
}
|
||||
export const LT_HASH_ANTI_TAMPERING = new d('WhatsApp Patch Integrity')
|
||||
export const LT_HASH_ANTI_TAMPERING = new LTHash('WhatsApp Patch Integrity')
|
||||
|
||||
+15
-12
@@ -1,5 +1,5 @@
|
||||
import { Boom } from '@hapi/boom'
|
||||
import axios, { AxiosRequestConfig } from 'axios'
|
||||
import axios, { type AxiosRequestConfig } from 'axios'
|
||||
import { exec } from 'child_process'
|
||||
import * as Crypto from 'crypto'
|
||||
import { once } from 'events'
|
||||
@@ -11,7 +11,7 @@ import { Readable, Transform } from 'stream'
|
||||
import { URL } from 'url'
|
||||
import { proto } from '../../WAProto'
|
||||
import { DEFAULT_ORIGIN, MEDIA_HKDF_KEY_MAPPING, MEDIA_PATH_MAP } from '../Defaults'
|
||||
import {
|
||||
import type {
|
||||
BaileysEventMap,
|
||||
DownloadableMessage,
|
||||
MediaConnInfo,
|
||||
@@ -24,10 +24,10 @@ import {
|
||||
WAMediaUploadFunction,
|
||||
WAMessageContent
|
||||
} from '../Types'
|
||||
import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildBuffer, jidNormalizedUser } from '../WABinary'
|
||||
import { type BinaryNode, getBinaryNodeChild, getBinaryNodeChildBuffer, jidNormalizedUser } from '../WABinary'
|
||||
import { aesDecryptGCM, aesEncryptGCM, hkdf } from './crypto'
|
||||
import { generateMessageIDV2 } from './generics'
|
||||
import { ILogger } from './logger'
|
||||
import type { ILogger } from './logger'
|
||||
|
||||
const getTmpFilesDirectory = () => tmpdir()
|
||||
|
||||
@@ -132,6 +132,8 @@ const extractVideoThumb = async (
|
||||
})
|
||||
|
||||
export const extractImageThumb = async (bufferOrFilePath: Readable | Buffer | string, width = 32) => {
|
||||
// TODO: Move entirely to sharp, removing jimp as it supports readable streams
|
||||
// This will have positive speed and performance impacts as well as minimizing RAM usage.
|
||||
if (bufferOrFilePath instanceof Readable) {
|
||||
bufferOrFilePath = await toBuffer(bufferOrFilePath)
|
||||
}
|
||||
@@ -590,7 +592,7 @@ export const downloadEncryptedContent = async (
|
||||
try {
|
||||
pushBytes(aes.update(data), b => this.push(b))
|
||||
callback()
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
callback(error)
|
||||
}
|
||||
},
|
||||
@@ -598,7 +600,7 @@ export const downloadEncryptedContent = async (
|
||||
try {
|
||||
pushBytes(aes.final(), b => this.push(b))
|
||||
callback()
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
callback(error)
|
||||
}
|
||||
}
|
||||
@@ -607,14 +609,14 @@ export const downloadEncryptedContent = async (
|
||||
}
|
||||
|
||||
export function extensionForMediaMessage(message: WAMessageContent) {
|
||||
const getExtension = (mimetype: string) => mimetype.split(';')[0].split('/')[1]
|
||||
const type = Object.keys(message)[0] as MessageType
|
||||
const getExtension = (mimetype: string) => mimetype.split(';')[0]?.split('/')[1]
|
||||
const type = Object.keys(message)[0] as Exclude<MessageType, 'toJSON'>
|
||||
let extension: string
|
||||
if (type === 'locationMessage' || type === 'liveLocationMessage' || type === 'productMessage') {
|
||||
extension = '.jpeg'
|
||||
} else {
|
||||
const messageContent = message[type] as WAGenericMediaMessage
|
||||
extension = getExtension(messageContent.mimetype!)
|
||||
extension = getExtension(messageContent.mimetype!)!
|
||||
}
|
||||
|
||||
return extension
|
||||
@@ -667,7 +669,7 @@ export const getWAUploadToServer = (
|
||||
uploadInfo = await refreshMediaConn(true)
|
||||
throw new Error(`upload failed, reason: ${JSON.stringify(result)}`)
|
||||
}
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
if (axios.isAxiosError(error)) {
|
||||
result = error.response?.data
|
||||
}
|
||||
@@ -751,7 +753,7 @@ export const decodeMediaRetryNode = (node: BinaryNode) => {
|
||||
|
||||
const errorNode = getBinaryNodeChild(node, 'error')
|
||||
if (errorNode) {
|
||||
const errorCode = +errorNode.attrs.code
|
||||
const errorCode = +errorNode.attrs.code!
|
||||
event.error = new Boom(`Failed to re-upload media (${errorCode})`, {
|
||||
data: errorNode.attrs,
|
||||
statusCode: getStatusCodeForMediaRetry(errorCode)
|
||||
@@ -780,7 +782,8 @@ export const decryptMediaRetryData = async (
|
||||
return proto.MediaRetryNotification.decode(plaintext)
|
||||
}
|
||||
|
||||
export const getStatusCodeForMediaRetry = (code: number) => MEDIA_RETRY_STATUS_MAP[code]
|
||||
export const getStatusCodeForMediaRetry = (code: number) =>
|
||||
MEDIA_RETRY_STATUS_MAP[code as proto.MediaRetryNotification.ResultType]
|
||||
|
||||
const MEDIA_RETRY_STATUS_MAP = {
|
||||
[proto.MediaRetryNotification.ResultType.SUCCESS]: 200,
|
||||
|
||||
+41
-32
@@ -5,7 +5,7 @@ import { promises as fs } from 'fs'
|
||||
import { type Transform } from 'stream'
|
||||
import { proto } from '../../WAProto'
|
||||
import { MEDIA_KEYS, URL_REGEX, WA_DEFAULT_EPHEMERAL } from '../Defaults'
|
||||
import {
|
||||
import type {
|
||||
AnyMediaMessageContent,
|
||||
AnyMessageContent,
|
||||
DownloadableMessage,
|
||||
@@ -13,27 +13,25 @@ import {
|
||||
MessageContentGenerationOptions,
|
||||
MessageGenerationOptions,
|
||||
MessageGenerationOptionsFromContent,
|
||||
MessageType,
|
||||
MessageUserReceipt,
|
||||
WAMediaUpload,
|
||||
WAMessage,
|
||||
WAMessageContent,
|
||||
WAMessageStatus,
|
||||
WAProto,
|
||||
WATextMessage
|
||||
} from '../Types'
|
||||
import { WAMessageStatus, WAProto } from '../Types'
|
||||
import { isJidGroup, isJidNewsletter, isJidStatusBroadcast, jidNormalizedUser } from '../WABinary'
|
||||
import { sha256 } from './crypto'
|
||||
import { generateMessageIDV2, getKeyAuthor, unixTimestampSeconds } from './generics'
|
||||
import { ILogger } from './logger'
|
||||
import type { ILogger } from './logger'
|
||||
import {
|
||||
downloadContentFromMessage,
|
||||
encryptedStream,
|
||||
generateThumbnail,
|
||||
getAudioDuration,
|
||||
getAudioWaveform,
|
||||
getRawMediaUploadData,
|
||||
MediaDownloadOptions
|
||||
getRawMediaUploadData,
|
||||
type MediaDownloadOptions
|
||||
} from './messages-media'
|
||||
|
||||
type MediaUploadData = {
|
||||
@@ -86,14 +84,14 @@ export const generateLinkPreviewIfRequired = async (
|
||||
try {
|
||||
const urlInfo = await getUrlInfo(url)
|
||||
return urlInfo
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
// ignore if fails
|
||||
logger?.warn({ trace: error.stack }, 'url generation failed')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const assertColor = async color => {
|
||||
const assertColor = async (color: any) => {
|
||||
let assertedColor
|
||||
if (typeof color === 'number') {
|
||||
assertedColor = color > 0 ? color : 0xffffffff + Number(color) + 1
|
||||
@@ -127,10 +125,10 @@ export const prepareWAMessageMedia = async (
|
||||
|
||||
const uploadData: MediaUploadData = {
|
||||
...message,
|
||||
media: message[mediaType]
|
||||
media: (message as any)[mediaType]
|
||||
}
|
||||
delete uploadData[mediaType]
|
||||
|
||||
delete (uploadData as any)[mediaType]
|
||||
// check if cacheable + generate cache key
|
||||
const cacheableKey =
|
||||
typeof uploadData.media === 'object' &&
|
||||
'url' in uploadData.media &&
|
||||
@@ -154,7 +152,7 @@ export const prepareWAMessageMedia = async (
|
||||
const obj = WAProto.Message.decode(mediaBuff)
|
||||
const key = `${mediaType}Message`
|
||||
|
||||
Object.assign(obj[key], { ...uploadData, media: undefined })
|
||||
Object.assign(obj[key as keyof proto.Message]!, { ...uploadData, media: undefined })
|
||||
|
||||
return obj
|
||||
}
|
||||
@@ -262,7 +260,7 @@ export const prepareWAMessageMedia = async (
|
||||
logger?.debug('computed backgroundColor audio status')
|
||||
}
|
||||
} catch (error) {
|
||||
logger?.warn({ trace: error.stack }, 'failed to obtain extra info')
|
||||
logger?.warn({ trace: (error as any).stack }, 'failed to obtain extra info')
|
||||
}
|
||||
})()
|
||||
]).finally(async () => {
|
||||
@@ -279,7 +277,7 @@ export const prepareWAMessageMedia = async (
|
||||
})
|
||||
|
||||
const obj = WAProto.Message.fromObject({
|
||||
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
|
||||
[`${mediaType}Message`]: MessageTypeProto[mediaType as keyof typeof MessageTypeProto].fromObject({
|
||||
url: mediaUrl,
|
||||
directPath,
|
||||
mediaKey,
|
||||
@@ -335,9 +333,9 @@ export const generateForwardMessageContent = (message: WAMessage, forceForward?:
|
||||
content = normalizeMessageContent(content)
|
||||
content = proto.Message.decode(proto.Message.encode(content!).finish())
|
||||
|
||||
let key = Object.keys(content)[0] as MessageType
|
||||
let key = Object.keys(content)[0] as keyof proto.IMessage
|
||||
|
||||
let score = content[key].contextInfo?.forwardingScore || 0
|
||||
let score = (content?.[key] as { contextInfo: proto.IContextInfo })?.contextInfo?.forwardingScore || 0
|
||||
score += message.key.fromMe && !forceForward ? 0 : 1
|
||||
if (key === 'conversation') {
|
||||
content.extendedTextMessage = { text: content[key] }
|
||||
@@ -346,10 +344,11 @@ export const generateForwardMessageContent = (message: WAMessage, forceForward?:
|
||||
key = 'extendedTextMessage'
|
||||
}
|
||||
|
||||
const key_ = content?.[key] as { contextInfo: proto.IContextInfo }
|
||||
if (score > 0) {
|
||||
content[key].contextInfo = { forwardingScore: score, isForwarded: true }
|
||||
key_.contextInfo = { forwardingScore: score, isForwarded: true }
|
||||
} else {
|
||||
content[key].contextInfo = {}
|
||||
key_.contextInfo = {}
|
||||
}
|
||||
|
||||
return content
|
||||
@@ -403,7 +402,7 @@ export const generateWAMessageContent = async (
|
||||
}
|
||||
|
||||
if (contactLen === 1) {
|
||||
m.contactMessage = WAProto.Message.ContactMessage.fromObject(message.contacts.contacts[0])
|
||||
m.contactMessage = WAProto.Message.ContactMessage.fromObject(message.contacts.contacts[0]!)
|
||||
} else {
|
||||
m.contactsArrayMessage = WAProto.Message.ContactsArrayMessage.fromObject(message.contacts)
|
||||
}
|
||||
@@ -541,9 +540,12 @@ export const generateWAMessageContent = async (
|
||||
}
|
||||
|
||||
if ('mentions' in message && message.mentions?.length) {
|
||||
const [messageType] = Object.keys(m)
|
||||
m[messageType].contextInfo = m[messageType] || {}
|
||||
m[messageType].contextInfo.mentionedJid = message.mentions
|
||||
const messageType = Object.keys(m)[0]! as Exclude<keyof proto.IMessage, 'conversation'>
|
||||
const key = m[messageType]
|
||||
if ('contextInfo' in key!) {
|
||||
key.contextInfo = key.contextInfo || {}
|
||||
key.contextInfo.mentionedJid = message.mentions
|
||||
}
|
||||
}
|
||||
|
||||
if ('edit' in message) {
|
||||
@@ -558,9 +560,11 @@ export const generateWAMessageContent = async (
|
||||
}
|
||||
|
||||
if ('contextInfo' in message && !!message.contextInfo) {
|
||||
const [messageType] = Object.keys(m)
|
||||
m[messageType] = m[messageType] || {}
|
||||
m[messageType].contextInfo = message.contextInfo
|
||||
const messageType = Object.keys(m)[0]! as Exclude<keyof proto.IMessage, 'conversation'>
|
||||
const key = m[messageType]
|
||||
if ('contextInfo' in key!) {
|
||||
key.contextInfo = { ...key.contextInfo, ...message.contextInfo }
|
||||
}
|
||||
}
|
||||
|
||||
return WAProto.Message.fromObject(m)
|
||||
@@ -578,7 +582,7 @@ export const generateWAMessageFromContent = (
|
||||
}
|
||||
|
||||
const innerMessage = normalizeMessageContent(message)!
|
||||
const key: string = getContentType(innerMessage)!
|
||||
const key = getContentType(innerMessage)! as Exclude<keyof proto.IMessage, 'conversation'>
|
||||
const timestamp = unixTimestampSeconds(options.timestamp)
|
||||
const { quoted, userJid } = options
|
||||
|
||||
@@ -597,7 +601,8 @@ export const generateWAMessageFromContent = (
|
||||
delete quotedContent.contextInfo
|
||||
}
|
||||
|
||||
const contextInfo: proto.IContextInfo = innerMessage[key].contextInfo || {}
|
||||
const contextInfo: proto.IContextInfo =
|
||||
('contextInfo' in innerMessage[key]! && innerMessage[key]?.contextInfo) || {}
|
||||
contextInfo.participant = jidNormalizedUser(participant!)
|
||||
contextInfo.stanzaId = quoted.key.id
|
||||
contextInfo.quotedMessage = quotedMsg
|
||||
@@ -608,7 +613,10 @@ export const generateWAMessageFromContent = (
|
||||
contextInfo.remoteJid = quoted.key.remoteJid
|
||||
}
|
||||
|
||||
innerMessage[key].contextInfo = contextInfo
|
||||
if (contextInfo && innerMessage[key]) {
|
||||
/* @ts-ignore */
|
||||
innerMessage[key].contextInfo = contextInfo
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -621,8 +629,9 @@ export const generateWAMessageFromContent = (
|
||||
// newsletters don't support ephemeral messages
|
||||
!isJidNewsletter(jid)
|
||||
) {
|
||||
/* @ts-ignore */
|
||||
innerMessage[key].contextInfo = {
|
||||
...(innerMessage[key].contextInfo || {}),
|
||||
...((innerMessage[key] as any).contextInfo || {}),
|
||||
expiration: options.ephemeralExpiration || WA_DEFAULT_EPHEMERAL
|
||||
//ephemeralSettingTimestamp: options.ephemeralOptions.eph_setting_ts?.toString()
|
||||
}
|
||||
@@ -653,7 +662,7 @@ export const generateWAMessage = async (jid: string, content: AnyMessageContent,
|
||||
}
|
||||
|
||||
/** Get the key to access the true type of content */
|
||||
export const getContentType = (content: WAProto.IMessage | undefined) => {
|
||||
export const getContentType = (content: proto.IMessage | undefined) => {
|
||||
if (content) {
|
||||
const keys = Object.keys(content)
|
||||
const key = keys.find(k => (k === 'conversation' || k.includes('Message')) && k !== 'senderKeyDistributionMessage')
|
||||
@@ -837,7 +846,7 @@ export function getAggregateVotesInPollMessage(
|
||||
data = voteHashMap[hash]
|
||||
}
|
||||
|
||||
voteHashMap[hash].voters.push(getKeyAuthor(update.pollUpdateMessageKey, meId))
|
||||
voteHashMap[hash]!.voters.push(getKeyAuthor(update.pollUpdateMessageKey, meId))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Boom } from '@hapi/boom'
|
||||
import { proto } from '../../WAProto'
|
||||
import { NOISE_MODE, WA_CERT_DETAILS } from '../Defaults'
|
||||
import { KeyPair } from '../Types'
|
||||
import { BinaryNode, decodeBinaryNode } from '../WABinary'
|
||||
import type { KeyPair } from '../Types'
|
||||
import type { BinaryNode } from '../WABinary'
|
||||
import { decodeBinaryNode } from '../WABinary'
|
||||
import { aesDecryptGCM, aesEncryptGCM, Curve, hkdf, sha256 } from './crypto'
|
||||
import { ILogger } from './logger'
|
||||
import type { ILogger } from './logger'
|
||||
|
||||
const generateIV = (counter: number) => {
|
||||
const iv = new ArrayBuffer(12)
|
||||
@@ -64,17 +65,17 @@ export const makeNoiseHandler = ({
|
||||
|
||||
const mixIntoKey = async (data: Uint8Array) => {
|
||||
const [write, read] = await localHKDF(data)
|
||||
salt = write
|
||||
encKey = read
|
||||
decKey = read
|
||||
salt = write!
|
||||
encKey = read!
|
||||
decKey = read!
|
||||
readCounter = 0
|
||||
writeCounter = 0
|
||||
}
|
||||
|
||||
const finishInit = async () => {
|
||||
const [write, read] = await localHKDF(new Uint8Array(0))
|
||||
encKey = write
|
||||
decKey = read
|
||||
encKey = write!
|
||||
decKey = read!
|
||||
hash = Buffer.from([])
|
||||
readCounter = 0
|
||||
writeCounter = 0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AxiosRequestConfig } from 'axios'
|
||||
import type { AxiosRequestConfig } from 'axios'
|
||||
import { proto } from '../../WAProto'
|
||||
import {
|
||||
import type {
|
||||
AuthenticationCreds,
|
||||
BaileysEventEmitter,
|
||||
CacheStore,
|
||||
@@ -9,15 +9,15 @@ import {
|
||||
ParticipantAction,
|
||||
RequestJoinAction,
|
||||
RequestJoinMethod,
|
||||
SignalKeyStoreWithTransaction,
|
||||
WAMessageStubType
|
||||
SignalKeyStoreWithTransaction
|
||||
} from '../Types'
|
||||
import { WAMessageStubType } from '../Types'
|
||||
import { getContentType, normalizeMessageContent } from '../Utils/messages'
|
||||
import { areJidsSameUser, isJidBroadcast, isJidStatusBroadcast, jidNormalizedUser } from '../WABinary'
|
||||
import { aesDecryptGCM, hmacSign } from './crypto'
|
||||
import { toNumber } from './generics'
|
||||
import { downloadAndProcessHistorySyncNotification } from './history'
|
||||
import { ILogger } from './logger'
|
||||
import type { ILogger } from './logger'
|
||||
|
||||
type ProcessMessageContext = {
|
||||
shouldProcessHistoryMsg: boolean
|
||||
@@ -273,6 +273,7 @@ const processMessage = async (
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
case proto.Message.ProtocolMessage.Type.MESSAGE_EDIT:
|
||||
ev.emit('messages.update', [
|
||||
{
|
||||
|
||||
+17
-9
@@ -1,7 +1,6 @@
|
||||
import { chunk } from 'lodash'
|
||||
import { KEY_BUNDLE_TYPE } from '../Defaults'
|
||||
import { SignalRepository } from '../Types'
|
||||
import {
|
||||
import type { SignalRepository } from '../Types'
|
||||
import type {
|
||||
AuthenticationCreds,
|
||||
AuthenticationState,
|
||||
KeyPair,
|
||||
@@ -11,19 +10,28 @@ import {
|
||||
} from '../Types/Auth'
|
||||
import {
|
||||
assertNodeErrorFree,
|
||||
BinaryNode,
|
||||
type BinaryNode,
|
||||
getBinaryNodeChild,
|
||||
getBinaryNodeChildBuffer,
|
||||
getBinaryNodeChildren,
|
||||
getBinaryNodeChildUInt,
|
||||
jidDecode,
|
||||
JidWithDevice,
|
||||
type JidWithDevice,
|
||||
S_WHATSAPP_NET
|
||||
} from '../WABinary'
|
||||
import { DeviceListData, ParsedDeviceInfo, USyncQueryResultList } from '../WAUSync'
|
||||
import type { DeviceListData, ParsedDeviceInfo, USyncQueryResultList } from '../WAUSync'
|
||||
import { Curve, generateSignalPubKey } from './crypto'
|
||||
import { encodeBigEndian } from './generics'
|
||||
|
||||
function chunk<T>(array: T[], size: number): T[][] {
|
||||
const chunks: T[][] = []
|
||||
for (let i = 0; i < array.length; i += size) {
|
||||
chunks.push(array.slice(i, i + size))
|
||||
}
|
||||
|
||||
return chunks
|
||||
}
|
||||
|
||||
export const createSignalIdentity = (wid: string, accountSignatureKey: Uint8Array): SignalIdentity => {
|
||||
return {
|
||||
identifier: { name: wid, deviceId: 0 },
|
||||
@@ -100,11 +108,11 @@ export const parseAndInjectE2ESessions = async (node: BinaryNode, repository: Si
|
||||
const chunks = chunk(nodes, chunkSize)
|
||||
for (const nodesChunk of chunks) {
|
||||
await Promise.all(
|
||||
nodesChunk.map(async node => {
|
||||
nodesChunk.map(async (node: BinaryNode) => {
|
||||
const signedKey = getBinaryNodeChild(node, 'skey')!
|
||||
const key = getBinaryNodeChild(node, 'key')!
|
||||
const identity = getBinaryNodeChildBuffer(node, 'identity')!
|
||||
const jid = node.attrs.jid
|
||||
const jid = node.attrs.jid!
|
||||
const registrationId = getBinaryNodeChildUInt(node, 'registration', 4)
|
||||
|
||||
await repository.injectE2ESession({
|
||||
@@ -180,7 +188,7 @@ export const getNextPreKeysNode = async (state: AuthenticationState, count: numb
|
||||
{ tag: 'registration', attrs: {}, content: encodeBigEndian(creds.registrationId) },
|
||||
{ tag: 'type', attrs: {}, content: KEY_BUNDLE_TYPE },
|
||||
{ tag: 'identity', attrs: {}, content: creds.signedIdentityKey.public },
|
||||
{ tag: 'list', attrs: {}, content: Object.keys(preKeys).map(k => xmppPreKey(preKeys[+k], +k)) },
|
||||
{ tag: 'list', attrs: {}, content: Object.keys(preKeys).map(k => xmppPreKey(preKeys[+k]!, +k)) },
|
||||
xmppSignedPreKey(creds.signedPreKey)
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Mutex } from 'async-mutex'
|
||||
import { mkdir, readFile, stat, unlink, writeFile } from 'fs/promises'
|
||||
import { join } from 'path'
|
||||
import { proto } from '../../WAProto'
|
||||
import { AuthenticationCreds, AuthenticationState, SignalDataTypeMap } from '../Types'
|
||||
import type { AuthenticationCreds, AuthenticationState, SignalDataTypeMap } from '../Types'
|
||||
import { initAuthCreds } from './auth-utils'
|
||||
import { BufferJSON } from './generics'
|
||||
|
||||
@@ -118,8 +118,8 @@ export const useMultiFileAuthState = async (
|
||||
set: async data => {
|
||||
const tasks: Promise<void>[] = []
|
||||
for (const category in data) {
|
||||
for (const id in data[category]) {
|
||||
const value = data[category][id]
|
||||
for (const id in data[category as keyof SignalDataTypeMap]) {
|
||||
const value = data[category as keyof SignalDataTypeMap]![id]
|
||||
const file = `${category}-${id}.json`
|
||||
tasks.push(value ? writeData(value, file) : removeData(file))
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { createHash } from 'crypto'
|
||||
import { proto } from '../../WAProto'
|
||||
import { KEY_BUNDLE_TYPE } from '../Defaults'
|
||||
import type { AuthenticationCreds, SignalCreds, SocketConfig } from '../Types'
|
||||
import { BinaryNode, getBinaryNodeChild, jidDecode, S_WHATSAPP_NET } from '../WABinary'
|
||||
import { type BinaryNode, getBinaryNodeChild, jidDecode, S_WHATSAPP_NET } from '../WABinary'
|
||||
import { Curve, hmacSign } from './crypto'
|
||||
import { encodeBigEndian } from './generics'
|
||||
import { createSignalIdentity } from './signal'
|
||||
@@ -34,8 +34,8 @@ const PLATFORM_MAP = {
|
||||
|
||||
const getWebInfo = (config: SocketConfig): proto.ClientPayload.IWebInfo => {
|
||||
let webSubPlatform = proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER
|
||||
if (config.syncFullHistory && PLATFORM_MAP[config.browser[0]]) {
|
||||
webSubPlatform = PLATFORM_MAP[config.browser[0]]
|
||||
if (config.syncFullHistory && PLATFORM_MAP[config.browser[0] as keyof typeof PLATFORM_MAP]) {
|
||||
webSubPlatform = PLATFORM_MAP[config.browser[0] as keyof typeof PLATFORM_MAP]
|
||||
}
|
||||
|
||||
return { webSubPlatform }
|
||||
@@ -67,7 +67,10 @@ export const generateLoginNode = (userJid: string, config: SocketConfig): proto.
|
||||
|
||||
const getPlatformType = (platform: string): proto.DeviceProps.PlatformType => {
|
||||
const platformType = platform.toUpperCase()
|
||||
return proto.DeviceProps.PlatformType[platformType] || proto.DeviceProps.PlatformType.DESKTOP
|
||||
return (
|
||||
proto.DeviceProps.PlatformType[platformType as keyof typeof proto.DeviceProps.PlatformType] ||
|
||||
proto.DeviceProps.PlatformType.DESKTOP
|
||||
)
|
||||
}
|
||||
|
||||
export const generateRegistrationNode = (
|
||||
@@ -151,7 +154,7 @@ export const configureSuccessfulPairing = (
|
||||
const deviceMsg = Buffer.concat([devicePrefix, deviceDetails!, signedIdentityKey.public, accountSignatureKey!])
|
||||
account.deviceSignature = Curve.sign(signedIdentityKey.private, deviceMsg)
|
||||
|
||||
const identity = createSignalIdentity(jid, accountSignatureKey!)
|
||||
const identity = createSignalIdentity(jid!, accountSignatureKey!)
|
||||
const accountEnc = encodeSignedDeviceIdentity(account, false)
|
||||
|
||||
const deviceIdentity = proto.ADVDeviceIdentity.decode(account.details!)
|
||||
@@ -161,7 +164,7 @@ export const configureSuccessfulPairing = (
|
||||
attrs: {
|
||||
to: S_WHATSAPP_NET,
|
||||
type: 'result',
|
||||
id: msgId
|
||||
id: msgId!
|
||||
},
|
||||
content: [
|
||||
{
|
||||
@@ -180,7 +183,7 @@ export const configureSuccessfulPairing = (
|
||||
|
||||
const authUpdate: Partial<AuthenticationCreds> = {
|
||||
account,
|
||||
me: { id: jid, name: bizName },
|
||||
me: { id: jid!, name: bizName },
|
||||
signalIdentities: [...(signalIdentities || []), identity],
|
||||
platform: platformNode?.attrs.name
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user