zapo-js 1.0.1 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/auth/pairing/WaPairingFlow.js +2 -0
- package/dist/client/WaClient.js +26 -20
- package/dist/client/coordinators/WaIncomingNodeCoordinator.js +1 -1
- package/dist/client/coordinators/WaMessageCoordinator.js +2 -18
- package/dist/client/coordinators/WaMessageDispatchCoordinator.js +2 -1
- package/dist/{types/client → client}/coordinators/WaRetryCoordinator.d.ts +0 -1
- package/dist/client/coordinators/WaRetryCoordinator.js +1 -21
- package/dist/client/events/incoming.js +3 -1
- package/dist/client/events/receipt.d.ts +30 -0
- package/dist/client/events/receipt.js +32 -0
- package/dist/{types/client → client}/media.d.ts +59 -2
- package/dist/client/media.js +60 -0
- package/dist/client/messaging/ignore-key.js +4 -2
- package/dist/{types/client → client}/types.d.ts +20 -10
- package/dist/esm/appstate-spec.js +2 -2
- package/dist/esm/auth/pairing/WaPairingFlow.js +2 -0
- package/dist/esm/client/WaClient.js +26 -20
- package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +1 -1
- package/dist/esm/client/coordinators/WaMessageCoordinator.js +2 -18
- package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +2 -1
- package/dist/esm/client/coordinators/WaRetryCoordinator.js +1 -21
- package/dist/esm/client/events/incoming.js +3 -1
- package/dist/esm/client/events/receipt.js +31 -0
- package/dist/esm/client/media.js +59 -0
- package/dist/esm/client/messaging/ignore-key.js +4 -2
- package/dist/esm/index.js +2 -0
- package/dist/esm/message/context-info.js +16 -3
- package/dist/esm/message/encode/media-payload.js +18 -0
- package/dist/esm/message/primitives/incoming.js +6 -2
- package/dist/esm/mex.js +1 -1
- package/dist/esm/protocol/message.js +2 -1
- package/dist/esm/transport/WaComms.js +4 -0
- package/dist/esm/transport/keepalive/WaKeepAlive.js +4 -0
- package/dist/esm/version-spec.js +1 -1
- package/dist/{types/index.d.ts → index.d.ts} +4 -1
- package/dist/index.js +6 -2
- package/dist/{types/message → message}/context-info.d.ts +9 -0
- package/dist/message/context-info.js +15 -2
- package/dist/message/encode/media-payload.d.ts +43 -0
- package/dist/message/encode/media-payload.js +18 -0
- package/dist/message/primitives/incoming.js +6 -2
- package/dist/{types/protocol → protocol}/message.d.ts +1 -0
- package/dist/protocol/message.js +2 -1
- package/dist/transport/WaComms.js +4 -0
- package/dist/transport/keepalive/WaKeepAlive.js +4 -0
- package/package.json +20 -16
- package/dist/types/client/events/receipt.d.ts +0 -14
- package/dist/types/message/encode/media-payload.d.ts +0 -12
- /package/dist/{types/appstate → appstate}/constants.d.ts +0 -0
- /package/dist/{types/appstate → appstate}/crypto/WaAppStateCrypto.d.ts +0 -0
- /package/dist/{types/appstate → appstate}/index.d.ts +0 -0
- /package/dist/{types/appstate → appstate}/parsers/encoding.d.ts +0 -0
- /package/dist/{types/appstate → appstate}/parsers/response-parser.d.ts +0 -0
- /package/dist/{types/appstate → appstate}/sync/WaAppStateSyncClient.d.ts +0 -0
- /package/dist/{types/appstate → appstate}/types.d.ts +0 -0
- /package/dist/{types/appstate → appstate}/utils.d.ts +0 -0
- /package/dist/{types/appstate-spec.d.ts → appstate-spec.d.ts} +0 -0
- /package/dist/{types/auth → auth}/WaAuthClient.d.ts +0 -0
- /package/dist/{types/auth → auth}/credentials-flow.d.ts +0 -0
- /package/dist/{types/auth → auth}/index.d.ts +0 -0
- /package/dist/{types/auth → auth}/pairing/WaPairingFlow.d.ts +0 -0
- /package/dist/{types/auth → auth}/pairing/WaQrFlow.d.ts +0 -0
- /package/dist/{types/auth → auth}/pairing/pairing-code-crypto.d.ts +0 -0
- /package/dist/{types/auth → auth}/types.d.ts +0 -0
- /package/dist/{types/client → client}/WaClient.d.ts +0 -0
- /package/dist/{types/client → client}/WaClientFactory.d.ts +0 -0
- /package/dist/{types/client → client}/connection/WaConnectionManager.d.ts +0 -0
- /package/dist/{types/client → client}/connection/WaReceiptQueue.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaAbPropsCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaAppStateMutationCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaBotCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaBroadcastListCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaBusinessCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaEmailCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaGroupCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaIncomingNodeCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaLowLevelCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaMessageCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaMessageDispatchCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaNewsletterCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaOfflineResumeCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaPassiveTasksCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaPresenceCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaPrivacyCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaProfileCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaStatusCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaStreamControlCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/coordinators/WaTrustedContactTokenCoordinator.d.ts +0 -0
- /package/dist/{types/client → client}/events/abprops.d.ts +0 -0
- /package/dist/{types/client → client}/events/appstate-mutation.d.ts +0 -0
- /package/dist/{types/client → client}/events/business.d.ts +0 -0
- /package/dist/{types/client → client}/events/call.d.ts +0 -0
- /package/dist/{types/client → client}/events/chatstate.d.ts +0 -0
- /package/dist/{types/client → client}/events/devices.d.ts +0 -0
- /package/dist/{types/client → client}/events/dirty.d.ts +0 -0
- /package/dist/{types/client → client}/events/group.d.ts +0 -0
- /package/dist/{types/client → client}/events/identity.d.ts +0 -0
- /package/dist/{types/client → client}/events/incoming.d.ts +0 -0
- /package/dist/{types/client → client}/events/mex-notification.d.ts +0 -0
- /package/dist/{types/client → client}/events/picture.d.ts +0 -0
- /package/dist/{types/client → client}/events/presence.d.ts +0 -0
- /package/dist/{types/client → client}/events/privacy-token.d.ts +0 -0
- /package/dist/{types/client → client}/events/registration.d.ts +0 -0
- /package/dist/{types/client → client}/index.d.ts +0 -0
- /package/dist/{types/client → client}/messaging/fanout.d.ts +0 -0
- /package/dist/{types/client → client}/messaging/group-metadata.d.ts +0 -0
- /package/dist/{types/client → client}/messaging/ignore-key.d.ts +0 -0
- /package/dist/{types/client → client}/messaging/key-protocol.d.ts +0 -0
- /package/dist/{types/client → client}/messaging/link-preview.d.ts +0 -0
- /package/dist/{types/client → client}/messaging/messages.d.ts +0 -0
- /package/dist/{types/client → client}/newsletter/admin.d.ts +0 -0
- /package/dist/{types/client → client}/newsletter/content.d.ts +0 -0
- /package/dist/{types/client → client}/newsletter/discovery.d.ts +0 -0
- /package/dist/{types/client → client}/newsletter/messaging.d.ts +0 -0
- /package/dist/{types/client → client}/newsletter/mex.d.ts +0 -0
- /package/dist/{types/client → client}/newsletter/parse.d.ts +0 -0
- /package/dist/{types/client → client}/newsletter/types.d.ts +0 -0
- /package/dist/{types/client → client}/persistence/WriteBehindPersistence.d.ts +0 -0
- /package/dist/{types/client → client}/persistence/history-sync.d.ts +0 -0
- /package/dist/{types/client → client}/persistence/mailbox.d.ts +0 -0
- /package/dist/{types/client → client}/tokens/cs-token.d.ts +0 -0
- /package/dist/{types/client → client}/tokens/tc-token.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/core/hkdf.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/core/index.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/core/keys.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/core/nonce.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/core/primitives.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/core/random.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/core/xeddsa.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/curves/Ed25519.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/curves/X25519.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/curves/constants.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/curves/types.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/index.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/math/constants.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/math/edwards.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/math/fe.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/math/le.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/math/mod.d.ts +0 -0
- /package/dist/{types/crypto → crypto}/math/types.d.ts +0 -0
- /package/dist/{types/infra → infra}/log/ConsoleLogger.d.ts +0 -0
- /package/dist/{types/infra → infra}/log/PinoLogger.d.ts +0 -0
- /package/dist/{types/infra → infra}/log/types.d.ts +0 -0
- /package/dist/{types/infra → infra}/perf/BackgroundQueue.d.ts +0 -0
- /package/dist/{types/infra → infra}/perf/BoundedTaskQueue.d.ts +0 -0
- /package/dist/{types/infra → infra}/perf/PromiseDedup.d.ts +0 -0
- /package/dist/{types/infra → infra}/perf/SharedExclusiveGate.d.ts +0 -0
- /package/dist/{types/infra → infra}/perf/StoreLock.d.ts +0 -0
- /package/dist/{types/media → media}/constants.d.ts +0 -0
- /package/dist/{types/media → media}/crypto/WaMediaCrypto.d.ts +0 -0
- /package/dist/{types/media → media}/index.d.ts +0 -0
- /package/dist/{types/media → media}/processor.d.ts +0 -0
- /package/dist/{types/media → media}/sticker/sticker-pack.d.ts +0 -0
- /package/dist/{types/media → media}/transfer/WaMediaTransferClient.d.ts +0 -0
- /package/dist/{types/media → media}/transfer/conn.d.ts +0 -0
- /package/dist/{types/media → media}/types.d.ts +0 -0
- /package/dist/{types/message → message}/WaMessageClient.d.ts +0 -0
- /package/dist/{types/message → message}/addons/link-preview/builder.d.ts +0 -0
- /package/dist/{types/message → message}/addons/link-preview/detect.d.ts +0 -0
- /package/dist/{types/message → message}/addons/link-preview/fetcher.d.ts +0 -0
- /package/dist/{types/message → message}/addons/link-preview/types.d.ts +0 -0
- /package/dist/{types/message → message}/crypto/addon-crypto.d.ts +0 -0
- /package/dist/{types/message → message}/crypto/icdc.d.ts +0 -0
- /package/dist/{types/message → message}/crypto/phash.d.ts +0 -0
- /package/dist/{types/message → message}/crypto/reporting-token.d.ts +0 -0
- /package/dist/{types/message → message}/crypto/use-case-secret.d.ts +0 -0
- /package/dist/{types/message → message}/encode/content.d.ts +0 -0
- /package/dist/{types/message → message}/encode/device-sent.d.ts +0 -0
- /package/dist/{types/message → message}/encode/padding.d.ts +0 -0
- /package/dist/{types/message → message}/index.d.ts +0 -0
- /package/dist/{types/message → message}/kinds/bot.d.ts +0 -0
- /package/dist/{types/message → message}/kinds/newsletter.d.ts +0 -0
- /package/dist/{types/message → message}/kinds/sticker-pack.d.ts +0 -0
- /package/dist/{types/message → message}/primitives/ack.d.ts +0 -0
- /package/dist/{types/message → message}/primitives/incoming.d.ts +0 -0
- /package/dist/{types/message → message}/primitives/peer-data-operation.d.ts +0 -0
- /package/dist/{types/message → message}/types.d.ts +0 -0
- /package/dist/{types/mex.d.ts → mex.d.ts} +0 -0
- /package/dist/{types/proto.d.ts → proto.d.ts} +0 -0
- /package/dist/{types/protocol → protocol}/abprops.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/appstate.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/auth.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/bot.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/browser.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/business.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/call.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/constants.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/defaults.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/dirty.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/email.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/group.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/index.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/jid.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/media.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/newsletter.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/nodes.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/notification.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/presence.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/privacy-token.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/privacy.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/status.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/stream.d.ts +0 -0
- /package/dist/{types/protocol → protocol}/usync.d.ts +0 -0
- /package/dist/{types/retry → retry}/codec.d.ts +0 -0
- /package/dist/{types/retry → retry}/constants.d.ts +0 -0
- /package/dist/{types/retry → retry}/index.d.ts +0 -0
- /package/dist/{types/retry → retry}/parse.d.ts +0 -0
- /package/dist/{types/retry → retry}/reason.d.ts +0 -0
- /package/dist/{types/retry → retry}/replay.d.ts +0 -0
- /package/dist/{types/retry → retry}/tracker.d.ts +0 -0
- /package/dist/{types/retry → retry}/types.d.ts +0 -0
- /package/dist/{types/signal → signal}/api/SignalDeviceSyncApi.d.ts +0 -0
- /package/dist/{types/signal → signal}/api/SignalDigestSyncApi.d.ts +0 -0
- /package/dist/{types/signal → signal}/api/SignalIdentitySyncApi.d.ts +0 -0
- /package/dist/{types/signal → signal}/api/SignalMissingPreKeysSyncApi.d.ts +0 -0
- /package/dist/{types/signal → signal}/api/SignalRotateKeyApi.d.ts +0 -0
- /package/dist/{types/signal → signal}/api/SignalSessionSyncApi.d.ts +0 -0
- /package/dist/{types/signal → signal}/api/codec.d.ts +0 -0
- /package/dist/{types/signal → signal}/api/constants.d.ts +0 -0
- /package/dist/{types/signal → signal}/api/prekeys.d.ts +0 -0
- /package/dist/{types/signal → signal}/api/result-map.d.ts +0 -0
- /package/dist/{types/signal → signal}/attestation/WaAdvSignature.d.ts +0 -0
- /package/dist/{types/signal → signal}/attestation/constants.d.ts +0 -0
- /package/dist/{types/signal → signal}/constants.d.ts +0 -0
- /package/dist/{types/signal → signal}/encoding.d.ts +0 -0
- /package/dist/{types/signal → signal}/group/SenderKeyChain.d.ts +0 -0
- /package/dist/{types/signal → signal}/group/SenderKeyCodec.d.ts +0 -0
- /package/dist/{types/signal → signal}/group/SenderKeyManager.d.ts +0 -0
- /package/dist/{types/signal → signal}/group/encoding.d.ts +0 -0
- /package/dist/{types/signal → signal}/index.d.ts +0 -0
- /package/dist/{types/signal → signal}/registration/encoding.d.ts +0 -0
- /package/dist/{types/signal → signal}/registration/keygen.d.ts +0 -0
- /package/dist/{types/signal → signal}/registration/utils.d.ts +0 -0
- /package/dist/{types/signal → signal}/session/SignalProtocol.d.ts +0 -0
- /package/dist/{types/signal → signal}/session/SignalRatchet.d.ts +0 -0
- /package/dist/{types/signal → signal}/session/SignalSerializer.d.ts +0 -0
- /package/dist/{types/signal → signal}/session/SignalSession.d.ts +0 -0
- /package/dist/{types/signal → signal}/session/encoding.d.ts +0 -0
- /package/dist/{types/signal → signal}/session/resolver.d.ts +0 -0
- /package/dist/{types/signal → signal}/types.d.ts +0 -0
- /package/dist/{types/store → store}/cache/identity.cache.d.ts +0 -0
- /package/dist/{types/store → store}/cache/privacy-token.cache.d.ts +0 -0
- /package/dist/{types/store → store}/cache/sender-key.cache.d.ts +0 -0
- /package/dist/{types/store → store}/cache/session.cache.d.ts +0 -0
- /package/dist/{types/store → store}/contracts/appstate.store.d.ts +0 -0
- /package/dist/{types/store → store}/contracts/auth.store.d.ts +0 -0
- /package/dist/{types/store → store}/contracts/contact.store.d.ts +0 -0
- /package/dist/{types/store → store}/contracts/device-list.store.d.ts +0 -0
- /package/dist/{types/store → store}/contracts/group-metadata.store.d.ts +0 -0
- /package/dist/{types/store → store}/contracts/identity.store.d.ts +0 -0
- /package/dist/{types/store → store}/contracts/message-secret.store.d.ts +0 -0
- /package/dist/{types/store → store}/contracts/message.store.d.ts +0 -0
- /package/dist/{types/store → store}/contracts/pre-key.store.d.ts +0 -0
- /package/dist/{types/store → store}/contracts/privacy-token.store.d.ts +0 -0
- /package/dist/{types/store → store}/contracts/retry.store.d.ts +0 -0
- /package/dist/{types/store → store}/contracts/sender-key.store.d.ts +0 -0
- /package/dist/{types/store → store}/contracts/session.store.d.ts +0 -0
- /package/dist/{types/store → store}/contracts/signal.store.d.ts +0 -0
- /package/dist/{types/store → store}/contracts/thread.store.d.ts +0 -0
- /package/dist/{types/store → store}/createStore.d.ts +0 -0
- /package/dist/{types/store → store}/index.d.ts +0 -0
- /package/dist/{types/store → store}/locks/appstate.lock.d.ts +0 -0
- /package/dist/{types/store → store}/locks/auth.lock.d.ts +0 -0
- /package/dist/{types/store → store}/locks/contact.lock.d.ts +0 -0
- /package/dist/{types/store → store}/locks/device-list.lock.d.ts +0 -0
- /package/dist/{types/store → store}/locks/group-metadata.lock.d.ts +0 -0
- /package/dist/{types/store → store}/locks/identity.lock.d.ts +0 -0
- /package/dist/{types/store → store}/locks/message-secret.lock.d.ts +0 -0
- /package/dist/{types/store → store}/locks/message.lock.d.ts +0 -0
- /package/dist/{types/store → store}/locks/pre-key.lock.d.ts +0 -0
- /package/dist/{types/store → store}/locks/privacy-token.lock.d.ts +0 -0
- /package/dist/{types/store → store}/locks/retry.lock.d.ts +0 -0
- /package/dist/{types/store → store}/locks/sender-key.lock.d.ts +0 -0
- /package/dist/{types/store → store}/locks/session.lock.d.ts +0 -0
- /package/dist/{types/store → store}/locks/signal.lock.d.ts +0 -0
- /package/dist/{types/store → store}/locks/thread.lock.d.ts +0 -0
- /package/dist/{types/store → store}/memory/appstate.store.d.ts +0 -0
- /package/dist/{types/store → store}/memory/auth.store.d.ts +0 -0
- /package/dist/{types/store → store}/memory/contact.store.d.ts +0 -0
- /package/dist/{types/store → store}/memory/device-list.store.d.ts +0 -0
- /package/dist/{types/store → store}/memory/group-metadata.store.d.ts +0 -0
- /package/dist/{types/store → store}/memory/identity.store.d.ts +0 -0
- /package/dist/{types/store → store}/memory/message-secret.store.d.ts +0 -0
- /package/dist/{types/store → store}/memory/message.store.d.ts +0 -0
- /package/dist/{types/store → store}/memory/pre-key.store.d.ts +0 -0
- /package/dist/{types/store → store}/memory/privacy-token.store.d.ts +0 -0
- /package/dist/{types/store → store}/memory/retry.store.d.ts +0 -0
- /package/dist/{types/store → store}/memory/sender-key.store.d.ts +0 -0
- /package/dist/{types/store → store}/memory/session.store.d.ts +0 -0
- /package/dist/{types/store → store}/memory/signal.store.d.ts +0 -0
- /package/dist/{types/store → store}/memory/thread.store.d.ts +0 -0
- /package/dist/{types/store → store}/noop.store.d.ts +0 -0
- /package/dist/{types/store → store}/types.d.ts +0 -0
- /package/dist/{types/transport → transport}/WaComms.d.ts +0 -0
- /package/dist/{types/transport → transport}/WaWebSocket.d.ts +0 -0
- /package/dist/{types/transport → transport}/binary/constants.d.ts +0 -0
- /package/dist/{types/transport → transport}/binary/decoder.d.ts +0 -0
- /package/dist/{types/transport → transport}/binary/encoder.d.ts +0 -0
- /package/dist/{types/transport → transport}/binary/index.d.ts +0 -0
- /package/dist/{types/transport → transport}/binary/tokens.d.ts +0 -0
- /package/dist/{types/transport → transport}/index.d.ts +0 -0
- /package/dist/{types/transport → transport}/keepalive/WaKeepAlive.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/WaMobileTcpSocket.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/WaNodeOrchestrator.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/WaNodeTransport.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/abprops.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/account-sync.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/bot.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/business.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/chatstate.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/community.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/device.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/email.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/global.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/group.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/media.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/message.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/newsletter.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/offline.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/pairing.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/passive.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/prekeys.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/presence.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/privacy-token.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/privacy.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/profile.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/retry.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/tos.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/builders/usync.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/helpers.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/mex/argo-decoder.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/mex/client.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/query.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/usync.d.ts +0 -0
- /package/dist/{types/transport → transport}/node/xml.d.ts +0 -0
- /package/dist/{types/transport → transport}/noise/WaClientPayload.d.ts +0 -0
- /package/dist/{types/transport → transport}/noise/WaFrameCodec.d.ts +0 -0
- /package/dist/{types/transport → transport}/noise/WaMobileClientPayload.d.ts +0 -0
- /package/dist/{types/transport → transport}/noise/WaNoiseCert.d.ts +0 -0
- /package/dist/{types/transport → transport}/noise/WaNoiseHandshake.d.ts +0 -0
- /package/dist/{types/transport → transport}/noise/WaNoiseSession.d.ts +0 -0
- /package/dist/{types/transport → transport}/noise/WaNoiseSocket.d.ts +0 -0
- /package/dist/{types/transport → transport}/noise/constants.d.ts +0 -0
- /package/dist/{types/transport → transport}/noise/types.d.ts +0 -0
- /package/dist/{types/transport → transport}/proxy.d.ts +0 -0
- /package/dist/{types/transport → transport}/stream/parse.d.ts +0 -0
- /package/dist/{types/transport → transport}/types.d.ts +0 -0
- /package/dist/{types/transport → transport}/wa-web-version-fetcher.d.ts +0 -0
- /package/dist/{types/util → util}/async.d.ts +0 -0
- /package/dist/{types/util → util}/bytes.d.ts +0 -0
- /package/dist/{types/util → util}/clock.d.ts +0 -0
- /package/dist/{types/util → util}/coercion.d.ts +0 -0
- /package/dist/{types/util → util}/collections.d.ts +0 -0
- /package/dist/{types/util → util}/index.d.ts +0 -0
- /package/dist/{types/util → util}/primitives.d.ts +0 -0
- /package/dist/{types/util → util}/runtime.d.ts +0 -0
- /package/dist/{types/version-spec.d.ts → version-spec.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/vinikjkkj/zapo/master/.github/assets/logo.png" />
|
|
4
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/vinikjkkj/zapo/master/.github/assets/logo-light.png" />
|
|
5
|
+
<img src="https://raw.githubusercontent.com/vinikjkkj/zapo/master/.github/assets/logo-light.png" alt="zapo" width="400" />
|
|
6
|
+
</picture>
|
|
3
7
|
</p>
|
|
4
8
|
|
|
5
9
|
<p align="center">
|
|
@@ -11,6 +11,7 @@ const WaAdvSignature_1 = require("../../signal/attestation/WaAdvSignature");
|
|
|
11
11
|
const global_1 = require("../../transport/node/builders/global");
|
|
12
12
|
const pairing_1 = require("../../transport/node/builders/pairing");
|
|
13
13
|
const helpers_1 = require("../../transport/node/helpers");
|
|
14
|
+
const query_1 = require("../../transport/node/query");
|
|
14
15
|
const bytes_1 = require("../../util/bytes");
|
|
15
16
|
class WaPairingFlow {
|
|
16
17
|
constructor(options) {
|
|
@@ -49,6 +50,7 @@ class WaPairingFlow {
|
|
|
49
50
|
responseTag: response.tag,
|
|
50
51
|
responseType: response.attrs.type
|
|
51
52
|
});
|
|
53
|
+
(0, query_1.assertIqResult)(response, 'companion hello');
|
|
52
54
|
const linkCodeNode = (0, helpers_1.findNodeChild)(response, constants_1.WA_NODE_TAGS.LINK_CODE_COMPANION_REG);
|
|
53
55
|
if (!linkCodeNode) {
|
|
54
56
|
throw new Error('companion hello response missing link_code_companion_reg');
|
package/dist/client/WaClient.js
CHANGED
|
@@ -258,10 +258,28 @@ class WaClient extends node_events_1.EventEmitter {
|
|
|
258
258
|
return;
|
|
259
259
|
}
|
|
260
260
|
if (protocolType === _proto_1.proto.Message.ProtocolMessage.Type.HISTORY_SYNC_NOTIFICATION) {
|
|
261
|
-
if (
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
261
|
+
if (!protocolMessage.historySyncNotification) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
const peerRemoteJid = event.key.remoteJid;
|
|
265
|
+
const peerStanzaId = event.key.id;
|
|
266
|
+
const sendHistSyncReceipt = peerRemoteJid && peerStanzaId
|
|
267
|
+
? async () => {
|
|
268
|
+
try {
|
|
269
|
+
await this.message.sendReceipt(peerRemoteJid, peerStanzaId, {
|
|
270
|
+
type: constants_1.WA_MESSAGE_TYPES.RECEIPT_TYPE_HISTORY_SYNC
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
catch (err) {
|
|
274
|
+
this.logger.warn('failed to send hist_sync receipt', {
|
|
275
|
+
id: peerStanzaId,
|
|
276
|
+
to: peerRemoteJid,
|
|
277
|
+
message: (0, primitives_1.toError)(err).message
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
: undefined;
|
|
282
|
+
if (this.options.history?.enabled !== false) {
|
|
265
283
|
await (0, history_sync_1.runHistorySyncNotification)({
|
|
266
284
|
logger: this.logger,
|
|
267
285
|
mediaTransfer: this.mediaTransfer,
|
|
@@ -269,24 +287,12 @@ class WaClient extends node_events_1.EventEmitter {
|
|
|
269
287
|
emitEvent: this.emit.bind(this),
|
|
270
288
|
onPrivacyTokens: (conversations) => this.deps.trustedContactToken.hydrateFromHistorySync(conversations),
|
|
271
289
|
onNctSalt: (salt) => this.deps.trustedContactToken.hydrateNctSaltFromHistorySync(salt),
|
|
272
|
-
onProcessed:
|
|
273
|
-
? async () => {
|
|
274
|
-
try {
|
|
275
|
-
await this.message.sendReceipt(peerRemoteJid, peerStanzaId, {
|
|
276
|
-
type: constants_1.WA_MESSAGE_TYPES.RECEIPT_TYPE_HISTORY_SYNC
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
catch (err) {
|
|
280
|
-
this.logger.warn('failed to send hist_sync receipt', {
|
|
281
|
-
id: peerStanzaId,
|
|
282
|
-
to: peerRemoteJid,
|
|
283
|
-
message: (0, primitives_1.toError)(err).message
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
: undefined
|
|
290
|
+
onProcessed: sendHistSyncReceipt
|
|
288
291
|
}, protocolMessage.historySyncNotification);
|
|
289
292
|
}
|
|
293
|
+
else if (sendHistSyncReceipt) {
|
|
294
|
+
await sendHistSyncReceipt();
|
|
295
|
+
}
|
|
290
296
|
return;
|
|
291
297
|
}
|
|
292
298
|
if (SYNC_RELATED_PROTOCOL_TYPES.has(protocolType)) {
|
|
@@ -391,7 +391,7 @@ class WaIncomingNodeCoordinator {
|
|
|
391
391
|
try {
|
|
392
392
|
const routingInfo = (0, helpers_1.decodeNodeContentBase64OrBytes)(routingInfoNode.content, `ib.${constants_1.WA_NODE_TAGS.EDGE_ROUTING}.${constants_1.WA_NODE_TAGS.ROUTING_INFO}`);
|
|
393
393
|
await this.runtime.persistRoutingInfo(routingInfo);
|
|
394
|
-
this.logger.
|
|
394
|
+
this.logger.debug('updated routing info from info bulletin', {
|
|
395
395
|
byteLength: routingInfo.byteLength
|
|
396
396
|
});
|
|
397
397
|
}
|
|
@@ -4,9 +4,9 @@ exports.WaMessageCoordinator = void 0;
|
|
|
4
4
|
const node_fs_1 = require("node:fs");
|
|
5
5
|
const promises_1 = require("node:stream/promises");
|
|
6
6
|
const receipt_1 = require("../events/receipt");
|
|
7
|
+
const media_1 = require("../media");
|
|
7
8
|
const addon_crypto_1 = require("../../message/crypto/addon-crypto");
|
|
8
9
|
const content_1 = require("../../message/encode/content");
|
|
9
|
-
const media_payload_1 = require("../../message/encode/media-payload");
|
|
10
10
|
const _proto_1 = require("../../proto");
|
|
11
11
|
const jid_1 = require("../../protocol/jid");
|
|
12
12
|
const client_1 = require("../../transport/node/mex/client");
|
|
@@ -235,23 +235,7 @@ class WaMessageCoordinator {
|
|
|
235
235
|
* for one-shot verified downloads.
|
|
236
236
|
*/
|
|
237
237
|
async download(source, options = {}) {
|
|
238
|
-
|
|
239
|
-
const payload = (0, media_payload_1.resolveMediaPayload)(message);
|
|
240
|
-
if (!payload) {
|
|
241
|
-
throw new Error('message has no downloadable media');
|
|
242
|
-
}
|
|
243
|
-
const { plaintext, metadata } = await this.mediaTransfer.downloadAndDecryptStream({
|
|
244
|
-
directPath: payload.directPath,
|
|
245
|
-
mediaType: payload.mediaType,
|
|
246
|
-
mediaKey: payload.mediaKey,
|
|
247
|
-
fileSha256: payload.fileSha256,
|
|
248
|
-
fileEncSha256: payload.fileEncSha256,
|
|
249
|
-
timeoutMs: options.timeoutMs,
|
|
250
|
-
signal: options.signal,
|
|
251
|
-
maxBytes: options.maxBytes
|
|
252
|
-
});
|
|
253
|
-
metadata.catch(() => undefined);
|
|
254
|
-
return plaintext;
|
|
238
|
+
return (0, media_1.downloadMediaMessage)(source, { ...options, transfer: this.mediaTransfer });
|
|
255
239
|
}
|
|
256
240
|
/**
|
|
257
241
|
* Convenience wrapper around {@link download} that streams the decrypted
|
|
@@ -164,7 +164,8 @@ class WaMessageDispatchCoordinator {
|
|
|
164
164
|
quote: options.quote,
|
|
165
165
|
forward: options.forward,
|
|
166
166
|
mentions: options.mentions,
|
|
167
|
-
meLid: this.deps.getCurrentCredentials()?.meLid
|
|
167
|
+
meLid: this.deps.getCurrentCredentials()?.meLid,
|
|
168
|
+
targetJid: recipientJid
|
|
168
169
|
});
|
|
169
170
|
const withCtx = ctx ? (0, context_info_1.applyContextInfo)(built.message, ctx) : built.message;
|
|
170
171
|
const withViewOnce = options.viewOnce ? (0, content_1.wrapAsViewOnce)(withCtx) : withCtx;
|
|
@@ -50,7 +50,6 @@ export declare class WaRetryCoordinator {
|
|
|
50
50
|
private isRetryReceiptNode;
|
|
51
51
|
private prepareDecryptFailureRetry;
|
|
52
52
|
private sendDecryptFailureRetryReceipt;
|
|
53
|
-
private resolvePeerRetryRecipient;
|
|
54
53
|
private handleParsedRetryRequest;
|
|
55
54
|
private processRetryRequest;
|
|
56
55
|
private prepareRetryResend;
|
|
@@ -169,7 +169,7 @@ class WaRetryCoordinator {
|
|
|
169
169
|
};
|
|
170
170
|
}
|
|
171
171
|
async sendDecryptFailureRetryReceipt(context, prepared) {
|
|
172
|
-
const recipient = context
|
|
172
|
+
const { recipient } = context;
|
|
173
173
|
const retryReceiptNode = (0, retry_1.buildRetryReceiptNode)({
|
|
174
174
|
stanzaId: context.stanzaId,
|
|
175
175
|
to: context.from,
|
|
@@ -194,26 +194,6 @@ class WaRetryCoordinator {
|
|
|
194
194
|
withKeys: prepared.retryKeys !== undefined
|
|
195
195
|
});
|
|
196
196
|
}
|
|
197
|
-
resolvePeerRetryRecipient(context) {
|
|
198
|
-
if (!context.participant) {
|
|
199
|
-
return undefined;
|
|
200
|
-
}
|
|
201
|
-
const meLid = this.deps.getCurrentCredentials()?.meLid;
|
|
202
|
-
if (!meLid) {
|
|
203
|
-
return undefined;
|
|
204
|
-
}
|
|
205
|
-
try {
|
|
206
|
-
const participantUser = (0, jid_1.toUserJid)(context.participant);
|
|
207
|
-
const meUserLid = (0, jid_1.toUserJid)(meLid);
|
|
208
|
-
if (participantUser !== meUserLid) {
|
|
209
|
-
return undefined;
|
|
210
|
-
}
|
|
211
|
-
return meUserLid;
|
|
212
|
-
}
|
|
213
|
-
catch {
|
|
214
|
-
return undefined;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
197
|
async handleParsedRetryRequest(receiptNode, request) {
|
|
218
198
|
if (request.type === constants_1.WA_MESSAGE_TYPES.RECEIPT_TYPE_ENC_REKEY_RETRY) {
|
|
219
199
|
this.deps.logger.debug('received enc_rekey_retry request (voip path deferred)', {
|
|
@@ -18,6 +18,7 @@ const call_1 = require("../events/call");
|
|
|
18
18
|
const group_1 = require("../events/group");
|
|
19
19
|
const mex_notification_1 = require("../events/mex-notification");
|
|
20
20
|
const picture_1 = require("../events/picture");
|
|
21
|
+
const receipt_1 = require("../events/receipt");
|
|
21
22
|
const registration_1 = require("../events/registration");
|
|
22
23
|
const constants_1 = require("../../protocol/constants");
|
|
23
24
|
const jid_1 = require("../../protocol/jid");
|
|
@@ -188,7 +189,8 @@ function createIncomingReceiptHandler(options) {
|
|
|
188
189
|
status: mapped.status,
|
|
189
190
|
fromSelfDevice: mapped.fromSelfDevice,
|
|
190
191
|
participantJid: node.attrs.participant,
|
|
191
|
-
recipientJid: node.attrs.recipient
|
|
192
|
+
recipientJid: node.attrs.recipient,
|
|
193
|
+
messageIds: (0, receipt_1.extractReceiptIds)(node)
|
|
192
194
|
});
|
|
193
195
|
}
|
|
194
196
|
else if (node.attrs.type && !INTERNAL_ONLY_RECEIPT_TYPES.has(node.attrs.type)) {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { BinaryNode } from '../../transport/types';
|
|
2
|
+
interface ReceiptTarget {
|
|
3
|
+
readonly chatJid: string;
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly senderJid?: string;
|
|
6
|
+
readonly isGroupChat?: boolean;
|
|
7
|
+
readonly isBroadcastChat?: boolean;
|
|
8
|
+
}
|
|
9
|
+
interface AggregatedReceiptGroup {
|
|
10
|
+
readonly jid: string;
|
|
11
|
+
readonly ids: readonly string[];
|
|
12
|
+
readonly participant?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function aggregateReceiptTargets(targets: readonly ReceiptTarget[]): readonly AggregatedReceiptGroup[];
|
|
15
|
+
/**
|
|
16
|
+
* Resolves every message id a `<receipt>` acknowledges, mirroring WhatsApp
|
|
17
|
+
* Web's `externalIds`. A batch receipt carries the extra ids in a
|
|
18
|
+
* `<list><item id=.../>` block; the top-level `attrs.id` is just one of them.
|
|
19
|
+
*
|
|
20
|
+
* - `<list><item>` ids come first. For `type="view"` receipts the item key is
|
|
21
|
+
* `server_id` (not `id`), and the top-level id is NOT appended.
|
|
22
|
+
* - Otherwise the top-level `attrs.id` is appended last.
|
|
23
|
+
* - Aggregated receipts (carrying a `<participants>` child) are out of scope:
|
|
24
|
+
* their ids live in `<user>` children, so this falls back to the single
|
|
25
|
+
* top-level id for them.
|
|
26
|
+
*
|
|
27
|
+
* No dedup: matches wa-web, which pushes the top id without checking the list.
|
|
28
|
+
*/
|
|
29
|
+
export declare function extractReceiptIds(node: BinaryNode): readonly string[];
|
|
30
|
+
export {};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.aggregateReceiptTargets = aggregateReceiptTargets;
|
|
4
|
+
exports.extractReceiptIds = extractReceiptIds;
|
|
5
|
+
const constants_1 = require("../../protocol/constants");
|
|
4
6
|
const jid_1 = require("../../protocol/jid");
|
|
7
|
+
const helpers_1 = require("../../transport/node/helpers");
|
|
5
8
|
function needsParticipant(target) {
|
|
6
9
|
if (target.isGroupChat !== undefined || target.isBroadcastChat !== undefined) {
|
|
7
10
|
return target.isGroupChat === true || target.isBroadcastChat === true;
|
|
@@ -24,3 +27,32 @@ function aggregateReceiptTargets(targets) {
|
|
|
24
27
|
}
|
|
25
28
|
return [...groups.values()];
|
|
26
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Resolves every message id a `<receipt>` acknowledges, mirroring WhatsApp
|
|
32
|
+
* Web's `externalIds`. A batch receipt carries the extra ids in a
|
|
33
|
+
* `<list><item id=.../>` block; the top-level `attrs.id` is just one of them.
|
|
34
|
+
*
|
|
35
|
+
* - `<list><item>` ids come first. For `type="view"` receipts the item key is
|
|
36
|
+
* `server_id` (not `id`), and the top-level id is NOT appended.
|
|
37
|
+
* - Otherwise the top-level `attrs.id` is appended last.
|
|
38
|
+
* - Aggregated receipts (carrying a `<participants>` child) are out of scope:
|
|
39
|
+
* their ids live in `<user>` children, so this falls back to the single
|
|
40
|
+
* top-level id for them.
|
|
41
|
+
*
|
|
42
|
+
* No dedup: matches wa-web, which pushes the top id without checking the list.
|
|
43
|
+
*/
|
|
44
|
+
function extractReceiptIds(node) {
|
|
45
|
+
const topId = node.attrs.id;
|
|
46
|
+
if ((0, helpers_1.hasNodeChild)(node, 'participants')) {
|
|
47
|
+
return topId ? [topId] : [];
|
|
48
|
+
}
|
|
49
|
+
const isView = node.attrs.type === constants_1.WA_MESSAGE_TYPES.RECEIPT_TYPE_VIEW;
|
|
50
|
+
const list = (0, helpers_1.findNodeChild)(node, 'list');
|
|
51
|
+
const ids = list
|
|
52
|
+
? [...(0, helpers_1.getNodeChildrenNonEmptyAttrValuesByTag)(list, 'item', isView ? 'server_id' : 'id')]
|
|
53
|
+
: [];
|
|
54
|
+
if (!isView && topId) {
|
|
55
|
+
ids.push(topId);
|
|
56
|
+
}
|
|
57
|
+
return ids;
|
|
58
|
+
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { type Readable } from 'node:stream';
|
|
2
|
-
import type { WaMediaOptions } from './types';
|
|
2
|
+
import type { WaDownloadMediaOptions, WaIncomingMessageEvent, WaMediaOptions } from './types';
|
|
3
3
|
import type { Logger } from '../infra/log/types';
|
|
4
|
-
import
|
|
4
|
+
import { WaMediaTransferClient } from '../media/transfer/WaMediaTransferClient';
|
|
5
5
|
import type { WaMediaConn } from '../media/types';
|
|
6
6
|
import type { WaSendMediaMessage } from '../message/types';
|
|
7
|
+
import type { Proto } from '../proto';
|
|
8
|
+
import type { WaProxyTransport } from '../transport/types';
|
|
7
9
|
export interface ProcessedMediaFields {
|
|
8
10
|
readonly jpegThumbnail?: Uint8Array;
|
|
9
11
|
readonly pngThumbnail?: Uint8Array;
|
|
@@ -62,4 +64,59 @@ export declare function shouldNormalizeVoiceNote(media: WaMediaOptions | undefin
|
|
|
62
64
|
export declare function hasMediaProcessingTasks(media: WaMediaOptions | undefined, content: WaSendMediaMessage): boolean;
|
|
63
65
|
export declare function getScopedMediaLogger(parent: Logger): Logger;
|
|
64
66
|
export declare function runMediaProcessor(media: WaMediaOptions | undefined, input: Uint8Array | string | undefined, content: WaSendMediaMessage, logger: Logger): Promise<ProcessedMediaFields>;
|
|
67
|
+
export interface WaDownloadMediaMessageOptions extends WaDownloadMediaOptions {
|
|
68
|
+
/**
|
|
69
|
+
* Reuse an existing transfer client instead of creating a fresh one. Lets
|
|
70
|
+
* the download inherit proxy agents, timeouts, and the MAC-verification
|
|
71
|
+
* toggle, and avoids spinning up a new HTTP client per call in a loop. A
|
|
72
|
+
* stateless {@link WaMediaTransferClient} is created when omitted - fine
|
|
73
|
+
* for one-off downloads.
|
|
74
|
+
*/
|
|
75
|
+
readonly transfer?: WaMediaTransferClient;
|
|
76
|
+
/**
|
|
77
|
+
* Proxy for the CDN download leg, mirroring `proxy.mediaDownload` on the
|
|
78
|
+
* client. The fetch runs over `node:http`/`node:https`, so only the Node
|
|
79
|
+
* `http.Agent` form is used; an undici dispatcher is ignored (same as the
|
|
80
|
+
* client treats `mediaDownload`). Takes precedence over the default agent
|
|
81
|
+
* of a `transfer` you pass.
|
|
82
|
+
*/
|
|
83
|
+
readonly proxy?: WaProxyTransport;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Streams and decrypts the media attached to a message without a connected
|
|
87
|
+
* `WaClient`. Resolves the encrypted payload (directPath, mediaKey, file
|
|
88
|
+
* hashes) from `source`, fetches the ciphertext from the WhatsApp media CDN,
|
|
89
|
+
* and decrypts it on the fly.
|
|
90
|
+
*
|
|
91
|
+
* The media keys come from the (already decrypted) message itself, so this is
|
|
92
|
+
* for re-downloading media you have persisted - not for fetching media you
|
|
93
|
+
* never received. The CDN download needs no session or auth token; only the
|
|
94
|
+
* upload path does.
|
|
95
|
+
*
|
|
96
|
+
* **The caller owns the returned stream** - pipe it somewhere or call
|
|
97
|
+
* `.destroy()` to release the socket; an unconsumed stream leaks the
|
|
98
|
+
* connection. MAC + SHA-256 verification runs as bytes are consumed, so
|
|
99
|
+
* aborting mid-read leaves you with unverified bytes. Pass `options.signal`
|
|
100
|
+
* to cancel cleanly.
|
|
101
|
+
*
|
|
102
|
+
* @throws when `source` carries no downloadable media.
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* import { downloadMediaMessage } from '..'
|
|
106
|
+
* import { createWriteStream } from 'node:fs'
|
|
107
|
+
*
|
|
108
|
+
* const stream = await downloadMediaMessage(event)
|
|
109
|
+
* stream.pipe(createWriteStream('photo.jpg'))
|
|
110
|
+
* ```
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* // Route the CDN download through an http.Agent-style proxy
|
|
114
|
+
* import { HttpsProxyAgent } from 'https-proxy-agent'
|
|
115
|
+
*
|
|
116
|
+
* const stream = await downloadMediaMessage(event, {
|
|
117
|
+
* proxy: new HttpsProxyAgent('http://127.0.0.1:8080')
|
|
118
|
+
* })
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
export declare function downloadMediaMessage(source: Proto.IMessage | WaIncomingMessageEvent, options?: WaDownloadMediaMessageOptions): Promise<Readable>;
|
|
65
122
|
export {};
|
package/dist/client/media.js
CHANGED
|
@@ -14,6 +14,7 @@ exports.shouldNormalizeVoiceNote = shouldNormalizeVoiceNote;
|
|
|
14
14
|
exports.hasMediaProcessingTasks = hasMediaProcessingTasks;
|
|
15
15
|
exports.getScopedMediaLogger = getScopedMediaLogger;
|
|
16
16
|
exports.runMediaProcessor = runMediaProcessor;
|
|
17
|
+
exports.downloadMediaMessage = downloadMediaMessage;
|
|
17
18
|
const node_crypto_1 = require("node:crypto");
|
|
18
19
|
const node_fs_1 = require("node:fs");
|
|
19
20
|
const promises_1 = require("node:fs/promises");
|
|
@@ -22,6 +23,9 @@ const node_path_1 = require("node:path");
|
|
|
22
23
|
const node_stream_1 = require("node:stream");
|
|
23
24
|
const promises_2 = require("node:stream/promises");
|
|
24
25
|
const core_1 = require("../crypto/core");
|
|
26
|
+
const WaMediaTransferClient_1 = require("../media/transfer/WaMediaTransferClient");
|
|
27
|
+
const media_payload_1 = require("../message/encode/media-payload");
|
|
28
|
+
const proxy_1 = require("../transport/proxy");
|
|
25
29
|
const bytes_1 = require("../util/bytes");
|
|
26
30
|
const primitives_1 = require("../util/primitives");
|
|
27
31
|
async function readFileHead(filePath, bytes) {
|
|
@@ -398,3 +402,59 @@ async function runMediaProcessor(media, input, content, logger) {
|
|
|
398
402
|
}
|
|
399
403
|
return result;
|
|
400
404
|
}
|
|
405
|
+
/**
|
|
406
|
+
* Streams and decrypts the media attached to a message without a connected
|
|
407
|
+
* `WaClient`. Resolves the encrypted payload (directPath, mediaKey, file
|
|
408
|
+
* hashes) from `source`, fetches the ciphertext from the WhatsApp media CDN,
|
|
409
|
+
* and decrypts it on the fly.
|
|
410
|
+
*
|
|
411
|
+
* The media keys come from the (already decrypted) message itself, so this is
|
|
412
|
+
* for re-downloading media you have persisted - not for fetching media you
|
|
413
|
+
* never received. The CDN download needs no session or auth token; only the
|
|
414
|
+
* upload path does.
|
|
415
|
+
*
|
|
416
|
+
* **The caller owns the returned stream** - pipe it somewhere or call
|
|
417
|
+
* `.destroy()` to release the socket; an unconsumed stream leaks the
|
|
418
|
+
* connection. MAC + SHA-256 verification runs as bytes are consumed, so
|
|
419
|
+
* aborting mid-read leaves you with unverified bytes. Pass `options.signal`
|
|
420
|
+
* to cancel cleanly.
|
|
421
|
+
*
|
|
422
|
+
* @throws when `source` carries no downloadable media.
|
|
423
|
+
* @example
|
|
424
|
+
* ```ts
|
|
425
|
+
* import { downloadMediaMessage } from '..'
|
|
426
|
+
* import { createWriteStream } from 'node:fs'
|
|
427
|
+
*
|
|
428
|
+
* const stream = await downloadMediaMessage(event)
|
|
429
|
+
* stream.pipe(createWriteStream('photo.jpg'))
|
|
430
|
+
* ```
|
|
431
|
+
* @example
|
|
432
|
+
* ```ts
|
|
433
|
+
* // Route the CDN download through an http.Agent-style proxy
|
|
434
|
+
* import { HttpsProxyAgent } from 'https-proxy-agent'
|
|
435
|
+
*
|
|
436
|
+
* const stream = await downloadMediaMessage(event, {
|
|
437
|
+
* proxy: new HttpsProxyAgent('http://127.0.0.1:8080')
|
|
438
|
+
* })
|
|
439
|
+
* ```
|
|
440
|
+
*/
|
|
441
|
+
async function downloadMediaMessage(source, options = {}) {
|
|
442
|
+
const message = 'rawNode' in source ? source.message : source;
|
|
443
|
+
const payload = (0, media_payload_1.resolveMediaPayload)(message);
|
|
444
|
+
if (!payload) {
|
|
445
|
+
throw new Error('message has no downloadable media');
|
|
446
|
+
}
|
|
447
|
+
const transfer = options.transfer ?? new WaMediaTransferClient_1.WaMediaTransferClient();
|
|
448
|
+
const { plaintext } = await transfer.downloadAndDecryptStream({
|
|
449
|
+
directPath: payload.directPath,
|
|
450
|
+
mediaType: payload.mediaType,
|
|
451
|
+
mediaKey: payload.mediaKey,
|
|
452
|
+
fileSha256: payload.fileSha256,
|
|
453
|
+
fileEncSha256: payload.fileEncSha256,
|
|
454
|
+
agent: (0, proxy_1.toProxyAgent)(options.proxy),
|
|
455
|
+
timeoutMs: options.timeoutMs,
|
|
456
|
+
signal: options.signal,
|
|
457
|
+
maxBytes: options.maxBytes
|
|
458
|
+
});
|
|
459
|
+
return plaintext;
|
|
460
|
+
}
|
|
@@ -88,12 +88,14 @@ function extractIgnoreKeyContext(node, meJid) {
|
|
|
88
88
|
const me = tryParseJid(meJid);
|
|
89
89
|
const fromCandidates = collectFromCandidates(kind, a);
|
|
90
90
|
const fromMe = me !== null && fromCandidates.some((f) => tryParseJid(f)?.address.user === me.address.user);
|
|
91
|
+
// Device-stripped to match the JID form used by events/keys; a userless
|
|
92
|
+
// server `from` like `s.whatsapp.net` is unparseable, so fall back to raw.
|
|
91
93
|
return {
|
|
92
94
|
kind,
|
|
93
|
-
remoteJid: a.from ?? null,
|
|
95
|
+
remoteJid: tryParseJid(a.from)?.userJid ?? a.from ?? null,
|
|
94
96
|
fromMe,
|
|
95
97
|
id: a.id,
|
|
96
|
-
participant: a.participant ?? null
|
|
98
|
+
participant: tryParseJid(a.participant)?.userJid ?? a.participant ?? null
|
|
97
99
|
};
|
|
98
100
|
}
|
|
99
101
|
/** Pure matcher. Exported for direct testing without a coordinator. */
|
|
@@ -423,27 +423,30 @@ export interface WaIgnoreKey {
|
|
|
423
423
|
* Lib derives `kind` from the stanza tag and resolves `fromMe` by comparing
|
|
424
424
|
* every from-candidate (`from`, `sender_pn`, `sender_lid`) against `meJid`.
|
|
425
425
|
*
|
|
426
|
-
* `remoteJid` and `participant`
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
426
|
+
* `remoteJid` and `participant` are the `from` / `participant` attrs with the
|
|
427
|
+
* `:device` segment stripped (bare `user@server`), matching the JID form used
|
|
428
|
+
* by message events and keys. A value that does not parse as a JID (e.g. a
|
|
429
|
+
* userless server `from` like `s.whatsapp.net`) is passed through unchanged.
|
|
430
|
+
* They do NOT include the descriptor-style
|
|
431
|
+
* alt-attr lookups (`sender_pn` / `sender_lid` / `participant_pn` /
|
|
432
|
+
* `participant_lid`) or PN↔LID normalization, so they stay in whichever
|
|
433
|
+
* addressing mode the stanza arrived in. To match by user identity regardless
|
|
434
|
+
* of addressing mode, use the descriptor form, which handles it.
|
|
432
435
|
*/
|
|
433
436
|
export interface WaIgnoreKeyContext {
|
|
434
437
|
readonly kind: WaIgnoreStanzaKind;
|
|
435
|
-
/**
|
|
438
|
+
/** `from` attr without `:device` (group JID for groups, PN or LID user JID for 1:1). */
|
|
436
439
|
readonly remoteJid: string | null;
|
|
437
440
|
readonly fromMe: boolean;
|
|
438
441
|
readonly id: string | undefined;
|
|
439
|
-
/**
|
|
442
|
+
/** `participant` attr without `:device`; `null` for non-group stanzas. */
|
|
440
443
|
readonly participant: string | null;
|
|
441
444
|
}
|
|
442
445
|
/**
|
|
443
446
|
* Predicate form of {@link WaClient.ignoreKey}. Return `true` to drop the
|
|
444
447
|
* stanza, `false` to let it through. Receives a {@link WaIgnoreKeyContext}
|
|
445
|
-
* with the
|
|
446
|
-
*
|
|
448
|
+
* with the device-stripped `from`/`participant` (see the context's JSDoc for
|
|
449
|
+
* the addressing-mode caveat) plus lib-resolved `kind` and `fromMe`.
|
|
447
450
|
*/
|
|
448
451
|
export type WaIgnoreKeyPredicate = (ctx: WaIgnoreKeyContext) => boolean;
|
|
449
452
|
export interface WaIncomingBaseEvent {
|
|
@@ -512,6 +515,13 @@ export interface WaIncomingReceiptEvent extends WaIncomingBaseEvent {
|
|
|
512
515
|
readonly fromSelfDevice: boolean;
|
|
513
516
|
readonly participantJid?: string;
|
|
514
517
|
readonly recipientJid?: string;
|
|
518
|
+
/**
|
|
519
|
+
* All message ids this receipt acknowledges. For batch read/delivery
|
|
520
|
+
* receipts this is the `<list><item>` ids plus the top-level `stanzaId`;
|
|
521
|
+
* for single receipts it is just `[stanzaId]`. Mirrors WhatsApp Web's
|
|
522
|
+
* `externalIds`.
|
|
523
|
+
*/
|
|
524
|
+
readonly messageIds: readonly string[];
|
|
515
525
|
}
|
|
516
526
|
export interface WaIncomingPresenceEvent extends WaIncomingBaseEvent {
|
|
517
527
|
readonly type: IncomingPresenceType;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { proto } from './proto.js';
|
|
2
|
-
import { WA_APPSTATE_SCHEMAS as RAW_WA_APPSTATE_SCHEMAS } from '
|
|
3
|
-
export { WA_APPSTATE_COLLECTIONS, WA_APPSTATE_SCHEMAS } from '
|
|
2
|
+
import { WA_APPSTATE_SCHEMAS as RAW_WA_APPSTATE_SCHEMAS } from '../../spec/appstate/index.js';
|
|
3
|
+
export { WA_APPSTATE_COLLECTIONS, WA_APPSTATE_SCHEMAS } from '../../spec/appstate/index.js';
|
|
4
4
|
const SCHEMA_BY_ACTION_NAME_BUILDER = {};
|
|
5
5
|
for (const key of Object.keys(RAW_WA_APPSTATE_SCHEMAS)) {
|
|
6
6
|
SCHEMA_BY_ACTION_NAME_BUILDER[RAW_WA_APPSTATE_SCHEMAS[key].name] = key;
|
|
@@ -8,6 +8,7 @@ import { ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE, computeAdvIdentityHmac, generateDe
|
|
|
8
8
|
import { buildAckNode, buildIqResultNode } from '../../transport/node/builders/global.js';
|
|
9
9
|
import { buildCompanionFinishRequestNode, buildCompanionHelloRequestNode, buildGetCountryCodeRequestNode } from '../../transport/node/builders/pairing.js';
|
|
10
10
|
import { decodeNodeContentUtf8OrBytes, findNodeChild, findNodeChildrenByTags, getFirstNodeChild, getNodeChildrenNonEmptyUtf8ByTag, hasNodeChild } from '../../transport/node/helpers.js';
|
|
11
|
+
import { assertIqResult } from '../../transport/node/query.js';
|
|
11
12
|
import { concatBytes, decodeProtoBytes, uint8Equal, uint8TimingSafeEqual } from '../../util/bytes.js';
|
|
12
13
|
export class WaPairingFlow {
|
|
13
14
|
constructor(options) {
|
|
@@ -46,6 +47,7 @@ export class WaPairingFlow {
|
|
|
46
47
|
responseTag: response.tag,
|
|
47
48
|
responseType: response.attrs.type
|
|
48
49
|
});
|
|
50
|
+
assertIqResult(response, 'companion hello');
|
|
49
51
|
const linkCodeNode = findNodeChild(response, WA_NODE_TAGS.LINK_CODE_COMPANION_REG);
|
|
50
52
|
if (!linkCodeNode) {
|
|
51
53
|
throw new Error('companion hello response missing link_code_companion_reg');
|
|
@@ -255,10 +255,28 @@ export class WaClient extends EventEmitter {
|
|
|
255
255
|
return;
|
|
256
256
|
}
|
|
257
257
|
if (protocolType === proto.Message.ProtocolMessage.Type.HISTORY_SYNC_NOTIFICATION) {
|
|
258
|
-
if (
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
258
|
+
if (!protocolMessage.historySyncNotification) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const peerRemoteJid = event.key.remoteJid;
|
|
262
|
+
const peerStanzaId = event.key.id;
|
|
263
|
+
const sendHistSyncReceipt = peerRemoteJid && peerStanzaId
|
|
264
|
+
? async () => {
|
|
265
|
+
try {
|
|
266
|
+
await this.message.sendReceipt(peerRemoteJid, peerStanzaId, {
|
|
267
|
+
type: WA_MESSAGE_TYPES.RECEIPT_TYPE_HISTORY_SYNC
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
catch (err) {
|
|
271
|
+
this.logger.warn('failed to send hist_sync receipt', {
|
|
272
|
+
id: peerStanzaId,
|
|
273
|
+
to: peerRemoteJid,
|
|
274
|
+
message: toError(err).message
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
: undefined;
|
|
279
|
+
if (this.options.history?.enabled !== false) {
|
|
262
280
|
await runHistorySyncNotification({
|
|
263
281
|
logger: this.logger,
|
|
264
282
|
mediaTransfer: this.mediaTransfer,
|
|
@@ -266,24 +284,12 @@ export class WaClient extends EventEmitter {
|
|
|
266
284
|
emitEvent: this.emit.bind(this),
|
|
267
285
|
onPrivacyTokens: (conversations) => this.deps.trustedContactToken.hydrateFromHistorySync(conversations),
|
|
268
286
|
onNctSalt: (salt) => this.deps.trustedContactToken.hydrateNctSaltFromHistorySync(salt),
|
|
269
|
-
onProcessed:
|
|
270
|
-
? async () => {
|
|
271
|
-
try {
|
|
272
|
-
await this.message.sendReceipt(peerRemoteJid, peerStanzaId, {
|
|
273
|
-
type: WA_MESSAGE_TYPES.RECEIPT_TYPE_HISTORY_SYNC
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
catch (err) {
|
|
277
|
-
this.logger.warn('failed to send hist_sync receipt', {
|
|
278
|
-
id: peerStanzaId,
|
|
279
|
-
to: peerRemoteJid,
|
|
280
|
-
message: toError(err).message
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
: undefined
|
|
287
|
+
onProcessed: sendHistSyncReceipt
|
|
285
288
|
}, protocolMessage.historySyncNotification);
|
|
286
289
|
}
|
|
290
|
+
else if (sendHistSyncReceipt) {
|
|
291
|
+
await sendHistSyncReceipt();
|
|
292
|
+
}
|
|
287
293
|
return;
|
|
288
294
|
}
|
|
289
295
|
if (SYNC_RELATED_PROTOCOL_TYPES.has(protocolType)) {
|
|
@@ -388,7 +388,7 @@ export class WaIncomingNodeCoordinator {
|
|
|
388
388
|
try {
|
|
389
389
|
const routingInfo = decodeNodeContentBase64OrBytes(routingInfoNode.content, `ib.${WA_NODE_TAGS.EDGE_ROUTING}.${WA_NODE_TAGS.ROUTING_INFO}`);
|
|
390
390
|
await this.runtime.persistRoutingInfo(routingInfo);
|
|
391
|
-
this.logger.
|
|
391
|
+
this.logger.debug('updated routing info from info bulletin', {
|
|
392
392
|
byteLength: routingInfo.byteLength
|
|
393
393
|
});
|
|
394
394
|
}
|