zapo-js 0.2.0 → 1.0.0
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/LICENSE +21 -0
- package/README.md +103 -179
- package/dist/appstate/{WaAppStateCrypto.js → crypto/WaAppStateCrypto.js} +79 -62
- package/dist/appstate/index.js +8 -7
- package/dist/appstate/{encoding.js → parsers/encoding.js} +11 -4
- package/dist/appstate/{WaAppStateSyncResponseParser.js → parsers/response-parser.js} +20 -8
- package/dist/appstate/{WaAppStateSyncClient.js → sync/WaAppStateSyncClient.js} +246 -88
- package/dist/appstate/utils.js +16 -0
- package/dist/appstate-spec.js +89 -0
- package/dist/auth/WaAuthClient.js +117 -13
- package/dist/auth/credentials-flow.js +207 -0
- package/dist/auth/pairing/WaPairingFlow.js +53 -47
- package/dist/auth/pairing/pairing-code-crypto.js +91 -0
- package/dist/client/WaClient.js +369 -460
- package/dist/client/WaClientFactory.js +377 -93
- package/dist/client/connection/WaConnectionManager.js +31 -11
- package/dist/client/coordinators/WaAbPropsCoordinator.js +140 -0
- package/dist/client/coordinators/WaAppStateMutationCoordinator.js +663 -143
- package/dist/client/coordinators/WaBotCoordinator.js +345 -0
- package/dist/client/coordinators/WaBroadcastListCoordinator.js +20 -0
- package/dist/client/coordinators/WaBusinessCoordinator.js +81 -180
- package/dist/client/coordinators/WaEmailCoordinator.js +64 -0
- package/dist/client/coordinators/WaGroupCoordinator.js +529 -52
- package/dist/client/coordinators/WaIncomingNodeCoordinator.js +130 -20
- package/dist/client/coordinators/WaLowLevelCoordinator.js +41 -0
- package/dist/client/coordinators/WaMessageCoordinator.js +365 -0
- package/dist/client/coordinators/WaMessageDispatchCoordinator.js +724 -216
- package/dist/client/coordinators/WaNewsletterCoordinator.js +18 -0
- package/dist/client/coordinators/WaOfflineResumeCoordinator.js +114 -0
- package/dist/client/coordinators/WaPassiveTasksCoordinator.js +53 -22
- package/dist/client/coordinators/WaPresenceCoordinator.js +21 -0
- package/dist/client/coordinators/WaPrivacyCoordinator.js +7 -5
- package/dist/client/coordinators/WaProfileCoordinator.js +223 -50
- package/dist/client/coordinators/WaRetryCoordinator.js +256 -123
- package/dist/client/coordinators/WaStatusCoordinator.js +49 -0
- package/dist/client/coordinators/WaStreamControlCoordinator.js +6 -6
- package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +29 -10
- package/dist/client/events/abprops.js +43 -0
- package/dist/client/events/appstate-mutation.js +133 -0
- package/dist/client/events/business.js +375 -0
- package/dist/client/events/call.js +58 -0
- package/dist/client/events/chatstate.js +23 -0
- package/dist/client/events/devices.js +15 -16
- package/dist/client/{dirty.js → events/dirty.js} +34 -20
- package/dist/client/events/group.js +13 -24
- package/dist/client/events/identity.js +2 -1
- package/dist/client/events/incoming.js +502 -0
- package/dist/client/events/mex-notification.js +181 -0
- package/dist/client/events/picture.js +33 -0
- package/dist/client/events/presence.js +44 -0
- package/dist/client/events/privacy-token.js +1 -2
- package/dist/client/events/receipt.js +26 -0
- package/dist/client/events/registration.js +42 -0
- package/dist/client/media.js +400 -0
- package/dist/client/messaging/fanout.js +9 -10
- package/dist/client/messaging/{participants.js → group-metadata.js} +73 -35
- package/dist/client/messaging/ignore-key.js +132 -0
- package/dist/client/messaging/key-protocol.js +3 -17
- package/dist/client/messaging/link-preview.js +159 -0
- package/dist/client/messaging/messages.js +671 -0
- package/dist/client/newsletter/admin.js +165 -0
- package/dist/client/newsletter/content.js +253 -0
- package/dist/client/newsletter/discovery.js +115 -0
- package/dist/client/newsletter/messaging.js +197 -0
- package/dist/client/newsletter/mex.js +41 -0
- package/dist/client/newsletter/parse.js +217 -0
- package/dist/client/persistence/WriteBehindPersistence.js +31 -4
- package/dist/client/{history-sync.js → persistence/history-sync.js} +125 -18
- package/dist/client/persistence/mailbox.js +104 -0
- package/dist/client/tokens/cs-token.js +11 -17
- package/dist/crypto/core/hkdf.js +12 -12
- package/dist/crypto/core/index.js +9 -8
- package/dist/crypto/core/keys.js +1 -8
- package/dist/crypto/core/nonce.js +12 -12
- package/dist/crypto/core/primitives.js +123 -93
- package/dist/crypto/core/random.js +9 -9
- package/dist/crypto/core/xeddsa.js +59 -0
- package/dist/crypto/curves/Ed25519.js +32 -21
- package/dist/crypto/curves/X25519.js +71 -17
- package/dist/crypto/curves/constants.js +3 -1
- package/dist/crypto/math/constants.js +1 -2
- package/dist/crypto/math/mod.js +0 -33
- package/dist/esm/appstate/{WaAppStateCrypto.js → crypto/WaAppStateCrypto.js} +72 -55
- package/dist/esm/appstate/index.js +5 -5
- package/dist/esm/appstate/{encoding.js → parsers/encoding.js} +11 -4
- package/dist/esm/appstate/{WaAppStateSyncResponseParser.js → parsers/response-parser.js} +20 -8
- package/dist/esm/appstate/{WaAppStateSyncClient.js → sync/WaAppStateSyncClient.js} +235 -76
- package/dist/esm/appstate/utils.js +16 -0
- package/dist/esm/appstate-spec.js +79 -0
- package/dist/esm/auth/WaAuthClient.js +114 -10
- package/dist/esm/auth/credentials-flow.js +202 -0
- package/dist/esm/auth/pairing/WaPairingFlow.js +52 -46
- package/dist/esm/auth/pairing/pairing-code-crypto.js +85 -0
- package/dist/esm/client/WaClient.js +372 -463
- package/dist/esm/client/WaClientFactory.js +380 -96
- package/dist/esm/client/connection/WaConnectionManager.js +31 -11
- package/dist/esm/client/coordinators/WaAbPropsCoordinator.js +136 -0
- package/dist/esm/client/coordinators/WaAppStateMutationCoordinator.js +665 -145
- package/dist/esm/client/coordinators/WaBotCoordinator.js +342 -0
- package/dist/esm/client/coordinators/WaBroadcastListCoordinator.js +17 -0
- package/dist/esm/client/coordinators/WaBusinessCoordinator.js +78 -177
- package/dist/esm/client/coordinators/WaEmailCoordinator.js +61 -0
- package/dist/esm/client/coordinators/WaGroupCoordinator.js +532 -55
- package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +132 -22
- package/dist/esm/client/coordinators/WaLowLevelCoordinator.js +38 -0
- package/dist/esm/client/coordinators/WaMessageCoordinator.js +361 -0
- package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +719 -211
- package/dist/esm/client/coordinators/WaNewsletterCoordinator.js +13 -0
- package/dist/esm/client/coordinators/WaOfflineResumeCoordinator.js +110 -0
- package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +54 -23
- package/dist/esm/client/coordinators/WaPresenceCoordinator.js +18 -0
- package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +7 -5
- package/dist/esm/client/coordinators/WaProfileCoordinator.js +226 -53
- package/dist/esm/client/coordinators/WaRetryCoordinator.js +258 -125
- package/dist/esm/client/coordinators/WaStatusCoordinator.js +46 -0
- package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +6 -6
- package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +31 -12
- package/dist/esm/client/events/abprops.js +40 -0
- package/dist/esm/client/events/appstate-mutation.js +130 -0
- package/dist/esm/client/events/business.js +370 -0
- package/dist/esm/client/events/call.js +55 -0
- package/dist/esm/client/events/chatstate.js +20 -0
- package/dist/esm/client/events/devices.js +15 -16
- package/dist/esm/client/{dirty.js → events/dirty.js} +34 -20
- package/dist/esm/client/events/group.js +14 -25
- package/dist/esm/client/events/identity.js +2 -1
- package/dist/esm/client/events/incoming.js +487 -0
- package/dist/esm/client/events/mex-notification.js +178 -0
- package/dist/esm/client/events/picture.js +30 -0
- package/dist/esm/client/events/presence.js +41 -0
- package/dist/esm/client/events/privacy-token.js +1 -2
- package/dist/esm/client/events/receipt.js +23 -0
- package/dist/esm/client/events/registration.js +39 -0
- package/dist/esm/client/media.js +384 -0
- package/dist/esm/client/messaging/fanout.js +10 -11
- package/dist/esm/client/messaging/{participants.js → group-metadata.js} +72 -34
- package/dist/esm/client/messaging/ignore-key.js +126 -0
- package/dist/esm/client/messaging/key-protocol.js +3 -17
- package/dist/esm/client/messaging/link-preview.js +156 -0
- package/dist/esm/client/messaging/messages.js +667 -0
- package/dist/esm/client/newsletter/admin.js +162 -0
- package/dist/esm/client/newsletter/content.js +249 -0
- package/dist/esm/client/newsletter/discovery.js +112 -0
- package/dist/esm/client/newsletter/messaging.js +194 -0
- package/dist/esm/client/newsletter/mex.js +37 -0
- package/dist/esm/client/newsletter/parse.js +200 -0
- package/dist/esm/client/persistence/WriteBehindPersistence.js +31 -4
- package/dist/esm/client/{history-sync.js → persistence/history-sync.js} +124 -18
- package/dist/esm/client/persistence/mailbox.js +101 -0
- package/dist/esm/client/tokens/cs-token.js +12 -18
- package/dist/esm/crypto/core/hkdf.js +14 -14
- package/dist/esm/crypto/core/index.js +3 -2
- package/dist/esm/crypto/core/keys.js +1 -7
- package/dist/esm/crypto/core/nonce.js +11 -11
- package/dist/esm/crypto/core/primitives.js +121 -88
- package/dist/esm/crypto/core/random.js +8 -7
- package/dist/esm/crypto/core/xeddsa.js +55 -0
- package/dist/esm/crypto/curves/Ed25519.js +35 -24
- package/dist/esm/crypto/curves/X25519.js +74 -20
- package/dist/esm/crypto/curves/constants.js +2 -0
- package/dist/esm/crypto/math/constants.js +1 -2
- package/dist/esm/crypto/math/mod.js +0 -32
- package/dist/esm/index.js +7 -2
- package/dist/esm/infra/log/ConsoleLogger.js +30 -6
- package/dist/esm/infra/log/PinoLogger.js +64 -0
- package/dist/esm/infra/log/types.js +4 -2
- package/dist/esm/infra/perf/BackgroundQueue.js +55 -13
- package/dist/esm/infra/perf/StoreLock.js +7 -4
- package/dist/esm/media/constants.js +35 -2
- package/dist/esm/media/crypto/WaMediaCrypto.js +374 -0
- package/dist/esm/media/index.js +4 -3
- package/dist/esm/media/processor.js +1 -0
- package/dist/esm/media/sticker/sticker-pack.js +133 -0
- package/dist/esm/media/{WaMediaTransferClient.js → transfer/WaMediaTransferClient.js} +84 -196
- package/dist/esm/media/{conn.js → transfer/conn.js} +10 -5
- package/dist/esm/message/WaMessageClient.js +46 -15
- package/dist/esm/message/addons/link-preview/builder.js +36 -0
- package/dist/esm/message/addons/link-preview/detect.js +55 -0
- package/dist/esm/message/addons/link-preview/fetcher.js +391 -0
- package/dist/esm/message/addons/link-preview/types.js +1 -0
- package/dist/esm/message/context-info.js +123 -0
- package/dist/esm/message/crypto/addon-crypto.js +244 -0
- package/dist/esm/message/{icdc.js → crypto/icdc.js} +11 -13
- package/dist/esm/message/crypto/phash.js +133 -0
- package/dist/esm/message/{reporting-token.js → crypto/reporting-token.js} +7 -7
- package/dist/esm/message/{use-case-secret.js → crypto/use-case-secret.js} +21 -4
- package/dist/esm/message/{content.js → encode/content.js} +183 -8
- package/dist/esm/message/encode/media-payload.js +42 -0
- package/dist/esm/message/{padding.js → encode/padding.js} +9 -3
- package/dist/esm/message/index.js +2 -2
- package/dist/esm/message/kinds/bot.js +111 -0
- package/dist/esm/message/kinds/newsletter.js +244 -0
- package/dist/esm/message/kinds/sticker-pack.js +29 -0
- package/dist/esm/message/{ack.js → primitives/ack.js} +8 -1
- package/dist/esm/message/primitives/incoming.js +511 -0
- package/dist/esm/message/primitives/peer-data-operation.js +93 -0
- package/dist/esm/mex.js +1 -0
- package/dist/esm/protocol/abprops.js +169 -0
- package/dist/esm/protocol/appstate.js +6 -30
- package/dist/esm/protocol/auth.js +3 -2
- package/dist/esm/protocol/bot.js +77 -0
- package/dist/esm/protocol/browser.js +22 -0
- package/dist/esm/protocol/business.js +19 -0
- package/dist/esm/protocol/call.js +48 -0
- package/dist/esm/protocol/constants.js +10 -2
- package/dist/esm/protocol/defaults.js +3 -0
- package/dist/esm/protocol/email.js +30 -0
- package/dist/esm/protocol/index.js +1 -1
- package/dist/esm/protocol/jid.js +142 -11
- package/dist/esm/protocol/media.js +25 -12
- package/dist/esm/protocol/message.js +4 -1
- package/dist/esm/protocol/newsletter.js +61 -0
- package/dist/esm/protocol/nodes.js +26 -2
- package/dist/esm/protocol/notification.js +24 -2
- package/dist/esm/protocol/presence.js +13 -0
- package/dist/esm/protocol/status.js +6 -0
- package/dist/esm/retry/codec.js +5 -0
- package/dist/esm/retry/parse.js +20 -38
- package/dist/esm/retry/reason.js +6 -1
- package/dist/esm/retry/replay.js +131 -37
- package/dist/esm/retry/tracker.js +4 -8
- package/dist/esm/signal/api/SignalDeviceSyncApi.js +71 -21
- package/dist/esm/signal/api/SignalDigestSyncApi.js +15 -8
- package/dist/esm/signal/api/SignalIdentitySyncApi.js +13 -4
- package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +24 -63
- package/dist/esm/signal/api/SignalRotateKeyApi.js +10 -0
- package/dist/esm/signal/api/SignalSessionSyncApi.js +23 -51
- package/dist/esm/signal/api/codec.js +52 -1
- package/dist/esm/signal/api/prekeys.js +4 -0
- package/dist/esm/signal/attestation/WaAdvSignature.js +17 -0
- package/dist/esm/signal/{crypto → attestation}/constants.js +0 -4
- package/dist/esm/signal/constants.js +3 -0
- package/dist/esm/signal/encoding.js +6 -332
- package/dist/esm/signal/group/SenderKeyChain.js +20 -35
- package/dist/esm/signal/group/SenderKeyCodec.js +5 -6
- package/dist/esm/signal/group/SenderKeyManager.js +37 -17
- package/dist/esm/signal/group/encoding.js +96 -0
- package/dist/esm/signal/index.js +4 -1
- package/dist/esm/signal/registration/encoding.js +34 -0
- package/dist/esm/signal/registration/keygen.js +12 -3
- package/dist/esm/signal/registration/utils.js +8 -2
- package/dist/esm/signal/session/SignalProtocol.js +129 -26
- package/dist/esm/signal/session/SignalRatchet.js +46 -64
- package/dist/esm/signal/session/SignalSerializer.js +5 -6
- package/dist/esm/signal/session/SignalSession.js +14 -19
- package/dist/esm/signal/session/encoding.js +173 -0
- package/dist/esm/signal/session/resolver.js +144 -35
- package/dist/esm/store/cache/identity.cache.js +75 -0
- package/dist/esm/store/cache/privacy-token.cache.js +57 -0
- package/dist/esm/store/cache/sender-key.cache.js +101 -0
- package/dist/esm/store/cache/session.cache.js +92 -0
- package/dist/esm/store/contracts/group-metadata.store.js +1 -0
- package/dist/esm/store/contracts/identity.store.js +1 -0
- package/dist/esm/store/contracts/message-secret.store.js +1 -0
- package/dist/esm/store/contracts/pre-key.store.js +1 -0
- package/dist/esm/store/contracts/session.store.js +1 -0
- package/dist/esm/store/createStore.js +129 -39
- package/dist/esm/store/index.js +15 -10
- package/dist/esm/store/locks/contact.lock.js +1 -0
- package/dist/esm/store/locks/device-list.lock.js +1 -0
- package/dist/esm/store/locks/group-metadata.lock.js +20 -0
- package/dist/esm/store/locks/identity.lock.js +16 -0
- package/dist/esm/store/locks/message-secret.lock.js +17 -0
- package/dist/esm/store/locks/pre-key.lock.js +27 -0
- package/dist/esm/store/locks/session.lock.js +19 -0
- package/dist/esm/store/locks/signal.lock.js +0 -24
- package/dist/esm/store/{providers/memory → memory}/appstate.store.js +5 -5
- package/dist/esm/store/memory/auth.store.js +24 -0
- package/dist/esm/store/memory/contact.store.js +79 -0
- package/dist/esm/store/memory/device-list.store.js +103 -0
- package/dist/esm/store/{providers/memory/participants.store.js → memory/group-metadata.store.js} +24 -12
- package/dist/esm/store/memory/identity.store.js +31 -0
- package/dist/esm/store/memory/message-secret.store.js +90 -0
- package/dist/esm/store/{providers/memory → memory}/message.store.js +2 -2
- package/dist/esm/store/memory/pre-key.store.js +97 -0
- package/dist/esm/store/{providers/memory → memory}/privacy-token.store.js +1 -1
- package/dist/esm/store/{providers/memory → memory}/retry.store.js +49 -14
- package/dist/esm/store/{providers/memory → memory}/sender-key.store.js +3 -3
- package/dist/esm/store/memory/session.store.js +45 -0
- package/dist/esm/store/memory/signal.store.js +36 -0
- package/dist/esm/store/{providers/memory → memory}/thread.store.js +2 -2
- package/dist/esm/store/noop.store.js +26 -4
- package/dist/esm/transport/WaComms.js +18 -8
- package/dist/esm/transport/WaWebSocket.js +41 -9
- package/dist/esm/transport/binary/constants.js +10 -4
- package/dist/esm/transport/binary/decoder.js +21 -15
- package/dist/esm/transport/binary/encoder.js +96 -21
- package/dist/esm/transport/binary/tokens.js +12 -12
- package/dist/esm/transport/index.js +7 -0
- package/dist/esm/transport/keepalive/WaKeepAlive.js +35 -12
- package/dist/esm/transport/node/WaMobileTcpSocket.js +120 -0
- package/dist/esm/transport/node/WaNodeOrchestrator.js +26 -13
- package/dist/esm/transport/node/WaNodeTransport.js +13 -0
- package/dist/esm/transport/node/builders/abprops.js +20 -0
- package/dist/esm/transport/node/builders/account-sync.js +7 -15
- package/dist/esm/transport/node/builders/bot.js +38 -0
- package/dist/esm/transport/node/builders/business.js +30 -30
- package/dist/esm/transport/node/builders/chatstate.js +28 -0
- package/dist/esm/transport/node/builders/community.js +53 -0
- package/dist/esm/transport/node/builders/device.js +11 -0
- package/dist/esm/transport/node/builders/email.js +66 -0
- package/dist/esm/transport/node/builders/global.js +1 -1
- package/dist/esm/transport/node/builders/group.js +114 -4
- package/dist/esm/transport/node/builders/media.js +2 -2
- package/dist/esm/transport/node/builders/message.js +83 -49
- package/dist/esm/transport/node/builders/newsletter.js +176 -0
- package/dist/esm/transport/node/builders/offline.js +14 -0
- package/dist/esm/transport/node/builders/passive.js +7 -0
- package/dist/esm/transport/node/builders/prekeys.js +40 -43
- package/dist/esm/transport/node/builders/presence.js +39 -0
- package/dist/esm/transport/node/builders/privacy-token.js +19 -23
- package/dist/esm/transport/node/builders/privacy.js +6 -6
- package/dist/esm/transport/node/builders/profile.js +28 -8
- package/dist/esm/transport/node/builders/retry.js +1 -1
- package/dist/esm/transport/node/builders/tos.js +58 -0
- package/dist/esm/transport/node/builders/usync.js +51 -2
- package/dist/esm/transport/node/helpers.js +27 -1
- package/dist/esm/transport/node/mex/argo-decoder.js +152 -0
- package/dist/esm/transport/node/mex/client.js +105 -0
- package/dist/esm/transport/node/query.js +17 -0
- package/dist/esm/transport/node/usync.js +12 -0
- package/dist/esm/transport/noise/WaClientPayload.js +23 -18
- package/dist/esm/transport/noise/WaFrameCodec.js +2 -2
- package/dist/esm/transport/noise/WaMobileClientPayload.js +58 -0
- package/dist/esm/transport/noise/WaNoiseCert.js +14 -27
- package/dist/esm/transport/noise/WaNoiseHandshake.js +27 -25
- package/dist/esm/transport/noise/WaNoiseSession.js +48 -67
- package/dist/esm/transport/noise/WaNoiseSocket.js +19 -13
- package/dist/esm/transport/noise/constants.js +0 -1
- package/dist/esm/transport/proxy.js +5 -0
- package/dist/esm/transport/stream/parse.js +3 -7
- package/dist/esm/transport/wa-web-version-fetcher.js +91 -0
- package/dist/esm/util/async.js +4 -0
- package/dist/esm/util/bytes.js +37 -2
- package/dist/esm/util/clock.js +15 -0
- package/dist/esm/util/coercion.js +45 -3
- package/dist/esm/util/collections.js +11 -0
- package/dist/esm/util/index.js +2 -2
- package/dist/esm/util/primitives.js +19 -0
- package/dist/esm/util/runtime.js +5 -0
- package/dist/esm/version-spec.js +1 -0
- package/dist/index.js +31 -1
- package/dist/infra/log/ConsoleLogger.js +30 -6
- package/dist/infra/log/PinoLogger.js +64 -0
- package/dist/infra/log/types.js +4 -2
- package/dist/infra/perf/BackgroundQueue.js +55 -13
- package/dist/infra/perf/StoreLock.js +7 -4
- package/dist/media/constants.js +36 -3
- package/dist/media/crypto/WaMediaCrypto.js +378 -0
- package/dist/media/index.js +9 -4
- package/dist/media/processor.js +2 -0
- package/dist/media/sticker/sticker-pack.js +136 -0
- package/dist/media/{WaMediaTransferClient.js → transfer/WaMediaTransferClient.js} +87 -229
- package/dist/media/{conn.js → transfer/conn.js} +10 -5
- package/dist/message/WaMessageClient.js +46 -15
- package/dist/message/addons/link-preview/builder.js +39 -0
- package/dist/message/addons/link-preview/detect.js +58 -0
- package/dist/message/addons/link-preview/fetcher.js +394 -0
- package/dist/message/addons/link-preview/types.js +2 -0
- package/dist/message/context-info.js +129 -0
- package/dist/message/crypto/addon-crypto.js +254 -0
- package/dist/message/{icdc.js → crypto/icdc.js} +11 -13
- package/dist/message/crypto/phash.js +136 -0
- package/dist/message/{reporting-token.js → crypto/reporting-token.js} +7 -7
- package/dist/message/{use-case-secret.js → crypto/use-case-secret.js} +21 -4
- package/dist/message/{content.js → encode/content.js} +200 -7
- package/dist/message/encode/media-payload.js +45 -0
- package/dist/message/{padding.js → encode/padding.js} +9 -3
- package/dist/message/index.js +2 -2
- package/dist/message/kinds/bot.js +120 -0
- package/dist/message/kinds/newsletter.js +248 -0
- package/dist/message/kinds/sticker-pack.js +34 -0
- package/dist/message/{ack.js → primitives/ack.js} +8 -1
- package/dist/message/{incoming.js → primitives/incoming.js} +225 -38
- package/dist/message/primitives/peer-data-operation.js +96 -0
- package/dist/mex.js +6 -0
- package/dist/proto.js +1 -1
- package/dist/protocol/abprops.js +173 -0
- package/dist/protocol/appstate.js +7 -31
- package/dist/protocol/auth.js +3 -2
- package/dist/protocol/bot.js +81 -0
- package/dist/protocol/browser.js +23 -0
- package/dist/protocol/business.js +22 -0
- package/dist/protocol/call.js +51 -0
- package/dist/protocol/constants.js +51 -3
- package/dist/protocol/defaults.js +3 -0
- package/dist/protocol/email.js +33 -0
- package/dist/protocol/index.js +12 -3
- package/dist/protocol/jid.js +148 -11
- package/dist/protocol/media.js +25 -12
- package/dist/protocol/message.js +4 -1
- package/dist/protocol/newsletter.js +64 -0
- package/dist/protocol/nodes.js +26 -2
- package/dist/protocol/notification.js +25 -3
- package/dist/protocol/presence.js +16 -0
- package/dist/protocol/status.js +9 -0
- package/dist/retry/codec.js +5 -0
- package/dist/retry/parse.js +16 -34
- package/dist/retry/reason.js +6 -1
- package/dist/retry/replay.js +129 -35
- package/dist/retry/tracker.js +3 -7
- package/dist/signal/api/SignalDeviceSyncApi.js +69 -19
- package/dist/signal/api/SignalDigestSyncApi.js +14 -7
- package/dist/signal/api/SignalIdentitySyncApi.js +13 -4
- package/dist/signal/api/SignalMissingPreKeysSyncApi.js +21 -60
- package/dist/signal/api/SignalRotateKeyApi.js +10 -0
- package/dist/signal/api/SignalSessionSyncApi.js +20 -48
- package/dist/signal/api/codec.js +52 -0
- package/dist/signal/api/prekeys.js +4 -0
- package/dist/signal/attestation/WaAdvSignature.js +26 -0
- package/dist/signal/{crypto → attestation}/constants.js +1 -5
- package/dist/signal/constants.js +4 -1
- package/dist/signal/encoding.js +5 -341
- package/dist/signal/group/SenderKeyChain.js +19 -34
- package/dist/signal/group/SenderKeyCodec.js +4 -5
- package/dist/signal/group/SenderKeyManager.js +36 -16
- package/dist/signal/group/encoding.js +101 -0
- package/dist/signal/index.js +13 -10
- package/dist/signal/registration/encoding.js +39 -0
- package/dist/signal/registration/keygen.js +11 -2
- package/dist/signal/registration/utils.js +8 -2
- package/dist/signal/session/SignalProtocol.js +128 -25
- package/dist/signal/session/SignalRatchet.js +41 -60
- package/dist/signal/session/SignalSerializer.js +5 -6
- package/dist/signal/session/SignalSession.js +13 -19
- package/dist/signal/session/encoding.js +183 -0
- package/dist/signal/session/resolver.js +144 -35
- package/dist/store/cache/identity.cache.js +78 -0
- package/dist/store/cache/privacy-token.cache.js +60 -0
- package/dist/store/cache/sender-key.cache.js +104 -0
- package/dist/store/cache/session.cache.js +95 -0
- package/dist/store/contracts/group-metadata.store.js +2 -0
- package/dist/store/contracts/identity.store.js +2 -0
- package/dist/store/contracts/message-secret.store.js +2 -0
- package/dist/store/contracts/pre-key.store.js +2 -0
- package/dist/store/contracts/session.store.js +2 -0
- package/dist/store/createStore.js +128 -38
- package/dist/store/index.js +22 -12
- package/dist/store/locks/contact.lock.js +1 -0
- package/dist/store/locks/device-list.lock.js +1 -0
- package/dist/store/locks/group-metadata.lock.js +23 -0
- package/dist/store/locks/identity.lock.js +19 -0
- package/dist/store/locks/message-secret.lock.js +20 -0
- package/dist/store/locks/pre-key.lock.js +30 -0
- package/dist/store/locks/session.lock.js +22 -0
- package/dist/store/locks/signal.lock.js +0 -24
- package/dist/store/{providers/memory → memory}/appstate.store.js +5 -5
- package/dist/store/memory/auth.store.js +28 -0
- package/dist/store/memory/contact.store.js +83 -0
- package/dist/store/memory/device-list.store.js +107 -0
- package/dist/store/{providers/memory/participants.store.js → memory/group-metadata.store.js} +26 -14
- package/dist/store/memory/identity.store.js +35 -0
- package/dist/store/memory/message-secret.store.js +94 -0
- package/dist/store/{providers/memory → memory}/message.store.js +2 -2
- package/dist/store/memory/pre-key.store.js +101 -0
- package/dist/store/{providers/memory → memory}/privacy-token.store.js +1 -1
- package/dist/store/{providers/memory → memory}/retry.store.js +49 -14
- package/dist/store/{providers/memory → memory}/sender-key.store.js +3 -3
- package/dist/store/memory/session.store.js +49 -0
- package/dist/store/memory/signal.store.js +40 -0
- package/dist/store/{providers/memory → memory}/thread.store.js +2 -2
- package/dist/store/noop.store.js +27 -5
- package/dist/transport/WaComms.js +18 -8
- package/dist/transport/WaWebSocket.js +41 -9
- package/dist/transport/binary/constants.js +11 -5
- package/dist/transport/binary/decoder.js +24 -18
- package/dist/transport/binary/encoder.js +109 -34
- package/dist/transport/binary/tokens.js +12 -12
- package/dist/transport/index.js +19 -1
- package/dist/transport/keepalive/WaKeepAlive.js +35 -12
- package/dist/transport/node/WaMobileTcpSocket.js +124 -0
- package/dist/transport/node/WaNodeOrchestrator.js +25 -12
- package/dist/transport/node/WaNodeTransport.js +13 -0
- package/dist/transport/node/builders/abprops.js +23 -0
- package/dist/transport/node/builders/account-sync.js +7 -16
- package/dist/transport/node/builders/bot.js +43 -0
- package/dist/transport/node/builders/business.js +31 -31
- package/dist/transport/node/builders/chatstate.js +31 -0
- package/dist/transport/node/builders/community.js +59 -0
- package/dist/transport/node/builders/device.js +14 -0
- package/dist/transport/node/builders/email.js +73 -0
- package/dist/transport/node/builders/global.js +1 -1
- package/dist/transport/node/builders/group.js +121 -3
- package/dist/transport/node/builders/media.js +1 -1
- package/dist/transport/node/builders/message.js +84 -49
- package/dist/transport/node/builders/newsletter.js +183 -0
- package/dist/transport/node/builders/offline.js +17 -0
- package/dist/transport/node/builders/passive.js +10 -0
- package/dist/transport/node/builders/prekeys.js +38 -41
- package/dist/transport/node/builders/presence.js +43 -0
- package/dist/transport/node/builders/privacy-token.js +18 -22
- package/dist/transport/node/builders/privacy.js +5 -5
- package/dist/transport/node/builders/profile.js +30 -7
- package/dist/transport/node/builders/retry.js +1 -1
- package/dist/transport/node/builders/tos.js +63 -0
- package/dist/transport/node/builders/usync.js +52 -1
- package/dist/transport/node/helpers.js +28 -1
- package/dist/transport/node/mex/argo-decoder.js +189 -0
- package/dist/transport/node/mex/client.js +109 -0
- package/dist/transport/node/query.js +17 -0
- package/dist/transport/node/usync.js +13 -0
- package/dist/transport/noise/WaClientPayload.js +22 -17
- package/dist/transport/noise/WaFrameCodec.js +1 -1
- package/dist/transport/noise/WaMobileClientPayload.js +61 -0
- package/dist/transport/noise/WaNoiseCert.js +13 -26
- package/dist/transport/noise/WaNoiseHandshake.js +25 -23
- package/dist/transport/noise/WaNoiseSession.js +47 -66
- package/dist/transport/noise/WaNoiseSocket.js +18 -12
- package/dist/transport/noise/constants.js +1 -2
- package/dist/transport/proxy.js +5 -0
- package/dist/transport/stream/parse.js +3 -7
- package/dist/transport/wa-web-version-fetcher.js +94 -0
- package/dist/types/appstate/constants.d.ts +1 -1
- package/dist/types/appstate/{WaAppStateCrypto.d.ts → crypto/WaAppStateCrypto.d.ts} +29 -9
- package/dist/types/appstate/index.d.ts +5 -5
- package/dist/types/appstate/{encoding.d.ts → parsers/encoding.d.ts} +8 -1
- package/dist/types/appstate/{WaAppStateSyncResponseParser.d.ts → parsers/response-parser.d.ts} +13 -3
- package/dist/types/appstate/sync/WaAppStateSyncClient.d.ts +105 -0
- package/dist/types/appstate/types.d.ts +1 -1
- package/dist/types/appstate/utils.d.ts +17 -1
- package/dist/types/appstate-spec.d.ts +24 -0
- package/dist/types/auth/WaAuthClient.d.ts +95 -3
- package/dist/types/auth/credentials-flow.d.ts +21 -0
- package/dist/types/auth/pairing/WaPairingFlow.d.ts +3 -2
- package/dist/types/auth/pairing/{WaPairingCodeCrypto.d.ts → pairing-code-crypto.d.ts} +5 -1
- package/dist/types/auth/types.d.ts +88 -1
- package/dist/types/client/WaClient.d.ts +183 -65
- package/dist/types/client/WaClientFactory.d.ts +40 -9
- package/dist/types/client/connection/WaConnectionManager.d.ts +4 -2
- package/dist/types/client/connection/WaReceiptQueue.d.ts +1 -1
- package/dist/types/client/coordinators/WaAbPropsCoordinator.d.ts +26 -0
- package/dist/types/client/coordinators/WaAppStateMutationCoordinator.d.ts +215 -5
- package/dist/types/client/coordinators/WaBotCoordinator.d.ts +117 -0
- package/dist/types/client/coordinators/WaBroadcastListCoordinator.d.ts +39 -0
- package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +45 -44
- package/dist/types/client/coordinators/WaEmailCoordinator.d.ts +40 -0
- package/dist/types/client/coordinators/WaGroupCoordinator.d.ts +311 -9
- package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +16 -4
- package/dist/types/client/coordinators/WaLowLevelCoordinator.d.ts +47 -0
- package/dist/types/client/coordinators/WaMessageCoordinator.d.ts +232 -0
- package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +65 -29
- package/dist/types/client/coordinators/WaNewsletterCoordinator.d.ts +13 -0
- package/dist/types/client/coordinators/WaOfflineResumeCoordinator.d.ts +31 -0
- package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +15 -3
- package/dist/types/client/coordinators/WaPresenceCoordinator.d.ts +27 -0
- package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +28 -1
- package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +117 -2
- package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +23 -15
- package/dist/types/client/coordinators/WaStatusCoordinator.d.ts +42 -0
- package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +16 -2
- package/dist/types/client/events/abprops.d.ts +15 -0
- package/dist/types/client/events/appstate-mutation.d.ts +3 -0
- package/dist/types/client/events/business.d.ts +10 -0
- package/dist/types/client/events/call.d.ts +31 -0
- package/dist/types/client/events/chatstate.d.ts +9 -0
- package/dist/types/client/events/devices.d.ts +5 -4
- package/dist/types/client/{dirty.d.ts → events/dirty.d.ts} +7 -4
- package/dist/types/client/events/group.d.ts +2 -1
- package/dist/types/client/events/identity.d.ts +2 -1
- package/dist/types/client/events/incoming.d.ts +65 -0
- package/dist/types/client/events/mex-notification.d.ts +6 -0
- package/dist/types/client/events/picture.d.ts +8 -0
- package/dist/types/client/events/presence.d.ts +28 -0
- package/dist/types/client/events/receipt.d.ts +14 -0
- package/dist/types/client/events/registration.d.ts +18 -0
- package/dist/types/client/index.d.ts +1 -1
- package/dist/types/client/media.d.ts +65 -0
- package/dist/types/client/messaging/fanout.d.ts +2 -2
- package/dist/types/client/messaging/group-metadata.d.ts +19 -0
- package/dist/types/client/messaging/ignore-key.d.ts +11 -0
- package/dist/types/client/messaging/key-protocol.d.ts +9 -7
- package/dist/types/client/messaging/link-preview.d.ts +19 -0
- package/dist/types/client/messaging/messages.d.ts +28 -0
- package/dist/types/client/newsletter/admin.d.ts +71 -0
- package/dist/types/client/newsletter/content.d.ts +42 -0
- package/dist/types/client/newsletter/discovery.d.ts +33 -0
- package/dist/types/client/newsletter/messaging.d.ts +66 -0
- package/dist/types/client/newsletter/mex.d.ts +14 -0
- package/dist/types/client/newsletter/parse.d.ts +19 -0
- package/dist/types/client/newsletter/types.d.ts +190 -0
- package/dist/types/client/persistence/WriteBehindPersistence.d.ts +13 -2
- package/dist/types/client/persistence/history-sync.d.ts +29 -0
- package/dist/types/client/persistence/mailbox.d.ts +12 -0
- package/dist/types/client/tokens/cs-token.d.ts +1 -3
- package/dist/types/client/types.d.ts +926 -55
- package/dist/types/crypto/core/hkdf.d.ts +10 -2
- package/dist/types/crypto/core/index.d.ts +3 -2
- package/dist/types/crypto/core/keys.d.ts +0 -4
- package/dist/types/crypto/core/nonce.d.ts +4 -5
- package/dist/types/crypto/core/primitives.d.ts +31 -20
- package/dist/types/crypto/core/random.d.ts +7 -1
- package/dist/types/crypto/core/xeddsa.d.ts +11 -0
- package/dist/types/crypto/curves/Ed25519.d.ts +7 -1
- package/dist/types/crypto/curves/X25519.d.ts +20 -1
- package/dist/types/crypto/curves/constants.d.ts +4 -2
- package/dist/types/crypto/curves/types.d.ts +0 -5
- package/dist/types/crypto/index.d.ts +1 -0
- package/dist/types/crypto/math/constants.d.ts +0 -1
- package/dist/types/crypto/math/mod.d.ts +0 -1
- package/dist/types/index.d.ts +32 -5
- package/dist/types/infra/log/ConsoleLogger.d.ts +19 -2
- package/dist/types/infra/log/PinoLogger.d.ts +56 -2
- package/dist/types/infra/log/types.d.ts +6 -0
- package/dist/types/infra/perf/BackgroundQueue.d.ts +19 -0
- package/dist/types/infra/perf/StoreLock.d.ts +1 -0
- package/dist/types/media/constants.d.ts +9 -2
- package/dist/types/media/crypto/WaMediaCrypto.d.ts +59 -0
- package/dist/types/media/index.d.ts +7 -4
- package/dist/types/media/processor.d.ts +50 -0
- package/dist/types/media/sticker/sticker-pack.d.ts +6 -0
- package/dist/types/media/{WaMediaTransferClient.d.ts → transfer/WaMediaTransferClient.d.ts} +33 -12
- package/dist/types/media/transfer/conn.d.ts +7 -0
- package/dist/types/media/types.d.ts +10 -5
- package/dist/types/message/WaMessageClient.d.ts +14 -0
- package/dist/types/message/addons/link-preview/builder.d.ts +13 -0
- package/dist/types/message/addons/link-preview/detect.d.ts +5 -0
- package/dist/types/message/addons/link-preview/fetcher.d.ts +13 -0
- package/dist/types/message/addons/link-preview/types.d.ts +51 -0
- package/dist/types/message/context-info.d.ts +66 -0
- package/dist/types/message/crypto/addon-crypto.d.ts +78 -0
- package/dist/types/message/{icdc.d.ts → crypto/icdc.d.ts} +6 -6
- package/dist/types/message/{phash.d.ts → crypto/phash.d.ts} +1 -1
- package/dist/types/message/{reporting-token.d.ts → crypto/reporting-token.d.ts} +2 -2
- package/dist/types/message/{use-case-secret.d.ts → crypto/use-case-secret.d.ts} +17 -1
- package/dist/types/message/encode/content.d.ts +43 -0
- package/dist/types/message/{device-sent.d.ts → encode/device-sent.d.ts} +1 -1
- package/dist/types/message/encode/media-payload.d.ts +12 -0
- package/dist/types/message/index.d.ts +2 -2
- package/dist/types/message/kinds/bot.d.ts +31 -0
- package/dist/types/message/kinds/newsletter.d.ts +12 -0
- package/dist/types/message/kinds/sticker-pack.d.ts +6 -0
- package/dist/types/message/{ack.d.ts → primitives/ack.d.ts} +1 -1
- package/dist/types/message/primitives/incoming.d.ts +21 -0
- package/dist/types/message/primitives/peer-data-operation.d.ts +23 -0
- package/dist/types/message/types.d.ts +218 -28
- package/dist/types/mex.d.ts +2 -0
- package/dist/types/proto.d.ts +2 -2
- package/dist/types/protocol/abprops.d.ts +151 -0
- package/dist/types/protocol/appstate.d.ts +4 -49
- package/dist/types/protocol/auth.d.ts +2 -2
- package/dist/types/protocol/bot.d.ts +45 -0
- package/dist/types/protocol/browser.d.ts +9 -0
- package/dist/types/protocol/business.d.ts +21 -0
- package/dist/types/protocol/call.d.ts +44 -0
- package/dist/types/protocol/constants.d.ts +20 -3
- package/dist/types/protocol/defaults.d.ts +3 -0
- package/dist/types/protocol/email.d.ts +32 -0
- package/dist/types/protocol/group.d.ts +1 -1
- package/dist/types/protocol/index.d.ts +2 -1
- package/dist/types/protocol/jid.d.ts +79 -0
- package/dist/types/protocol/media.d.ts +21 -13
- package/dist/types/protocol/message.d.ts +4 -0
- package/dist/types/protocol/newsletter.d.ts +65 -0
- package/dist/types/protocol/nodes.d.ts +24 -0
- package/dist/types/protocol/notification.d.ts +22 -0
- package/dist/types/protocol/presence.d.ts +16 -0
- package/dist/types/protocol/status.d.ts +7 -0
- package/dist/types/protocol/stream.d.ts +1 -0
- package/dist/types/retry/codec.d.ts +5 -0
- package/dist/types/retry/index.d.ts +1 -1
- package/dist/types/retry/parse.d.ts +9 -0
- package/dist/types/retry/reason.d.ts +6 -1
- package/dist/types/retry/replay.d.ts +19 -5
- package/dist/types/retry/tracker.d.ts +10 -3
- package/dist/types/retry/types.d.ts +3 -8
- package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +20 -0
- package/dist/types/signal/api/SignalDigestSyncApi.d.ts +13 -0
- package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +12 -3
- package/dist/types/signal/api/SignalMissingPreKeysSyncApi.d.ts +8 -0
- package/dist/types/signal/api/SignalRotateKeyApi.d.ts +10 -0
- package/dist/types/signal/api/SignalSessionSyncApi.d.ts +13 -0
- package/dist/types/signal/api/codec.d.ts +20 -0
- package/dist/types/signal/api/constants.d.ts +1 -1
- package/dist/types/signal/api/prekeys.d.ts +4 -0
- package/dist/types/signal/{crypto → attestation}/WaAdvSignature.d.ts +2 -4
- package/dist/types/signal/attestation/constants.d.ts +4 -0
- package/dist/types/signal/constants.d.ts +7 -4
- package/dist/types/signal/encoding.d.ts +6 -62
- package/dist/types/signal/group/SenderKeyChain.d.ts +2 -2
- package/dist/types/signal/group/SenderKeyManager.d.ts +24 -2
- package/dist/types/signal/group/encoding.d.ts +25 -0
- package/dist/types/signal/index.d.ts +4 -1
- package/dist/types/signal/registration/encoding.d.ts +30 -0
- package/dist/types/signal/registration/keygen.d.ts +10 -0
- package/dist/types/signal/registration/utils.d.ts +7 -1
- package/dist/types/signal/session/SignalProtocol.d.ts +66 -2
- package/dist/types/signal/session/SignalRatchet.d.ts +2 -3
- package/dist/types/signal/session/SignalSerializer.d.ts +2 -1
- package/dist/types/signal/session/SignalSession.d.ts +0 -1
- package/dist/types/signal/session/encoding.d.ts +28 -0
- package/dist/types/signal/session/resolver.d.ts +18 -2
- package/dist/types/signal/types.d.ts +16 -4
- package/dist/types/store/cache/identity.cache.d.ts +15 -0
- package/dist/types/store/cache/privacy-token.cache.d.ts +15 -0
- package/dist/types/store/cache/sender-key.cache.d.ts +18 -0
- package/dist/types/store/cache/session.cache.d.ts +23 -0
- package/dist/types/store/contracts/contact.store.d.ts +14 -0
- package/dist/types/store/contracts/device-list.store.d.ts +13 -0
- package/dist/types/store/contracts/group-metadata.store.d.ts +14 -0
- package/dist/types/store/contracts/identity.store.d.ts +11 -0
- package/dist/types/store/contracts/message-secret.store.d.ts +16 -0
- package/dist/types/store/contracts/message.store.d.ts +0 -2
- package/dist/types/store/contracts/pre-key.store.d.ts +13 -0
- package/dist/types/store/contracts/session.store.d.ts +14 -0
- package/dist/types/store/contracts/signal.store.d.ts +1 -34
- package/dist/types/store/createStore.d.ts +54 -2
- package/dist/types/store/index.d.ts +22 -13
- package/dist/types/store/locks/group-metadata.lock.d.ts +2 -0
- package/dist/types/store/locks/identity.lock.d.ts +3 -0
- package/dist/types/store/locks/message-secret.lock.d.ts +3 -0
- package/dist/types/store/locks/pre-key.lock.d.ts +3 -0
- package/dist/types/store/locks/session.lock.d.ts +3 -0
- package/dist/types/store/{providers/memory → memory}/appstate.store.d.ts +2 -2
- package/dist/types/store/memory/auth.store.d.ts +18 -0
- package/dist/types/store/{providers/memory → memory}/contact.store.d.ts +6 -1
- package/dist/types/store/{providers/memory → memory}/device-list.store.d.ts +15 -2
- package/dist/types/store/memory/group-metadata.store.d.ts +27 -0
- package/dist/types/store/memory/identity.store.d.ts +18 -0
- package/dist/types/store/memory/message-secret.store.d.ts +31 -0
- package/dist/types/store/{providers/memory → memory}/message.store.d.ts +1 -1
- package/dist/types/store/memory/pre-key.store.d.ts +23 -0
- package/dist/types/store/{providers/memory → memory}/privacy-token.store.d.ts +1 -1
- package/dist/types/store/{providers/memory → memory}/retry.store.d.ts +23 -4
- package/dist/types/store/{providers/memory → memory}/sender-key.store.d.ts +2 -2
- package/dist/types/store/memory/session.store.d.ts +21 -0
- package/dist/types/store/memory/signal.store.d.ts +16 -0
- package/dist/types/store/{providers/memory → memory}/thread.store.d.ts +1 -1
- package/dist/types/store/noop.store.d.ts +6 -2
- package/dist/types/store/types.d.ts +271 -7
- package/dist/types/transport/WaComms.d.ts +5 -0
- package/dist/types/transport/WaWebSocket.d.ts +6 -0
- package/dist/types/transport/binary/constants.d.ts +8 -2
- package/dist/types/transport/binary/decoder.d.ts +5 -0
- package/dist/types/transport/binary/encoder.d.ts +5 -0
- package/dist/types/transport/binary/tokens.d.ts +6 -6
- package/dist/types/transport/index.d.ts +9 -0
- package/dist/types/transport/keepalive/WaKeepAlive.d.ts +11 -1
- package/dist/types/transport/node/WaMobileTcpSocket.d.ts +24 -0
- package/dist/types/transport/node/WaNodeOrchestrator.d.ts +11 -2
- package/dist/types/transport/node/WaNodeTransport.d.ts +13 -0
- package/dist/types/transport/node/builders/abprops.d.ts +5 -0
- package/dist/types/transport/node/builders/account-sync.d.ts +1 -2
- package/dist/types/transport/node/builders/bot.d.ts +4 -0
- package/dist/types/transport/node/builders/business.d.ts +21 -4
- package/dist/types/transport/node/builders/chatstate.d.ts +11 -0
- package/dist/types/transport/node/builders/community.d.ts +17 -0
- package/dist/types/transport/node/builders/device.d.ts +2 -0
- package/dist/types/transport/node/builders/email.d.ts +11 -0
- package/dist/types/transport/node/builders/group.d.ts +44 -2
- package/dist/types/transport/node/builders/message.d.ts +11 -6
- package/dist/types/transport/node/builders/newsletter.d.ts +73 -0
- package/dist/types/transport/node/builders/offline.d.ts +2 -0
- package/dist/types/transport/node/builders/passive.d.ts +3 -0
- package/dist/types/transport/node/builders/prekeys.d.ts +4 -3
- package/dist/types/transport/node/builders/presence.d.ts +13 -0
- package/dist/types/transport/node/builders/profile.d.ts +3 -0
- package/dist/types/transport/node/builders/tos.d.ts +12 -0
- package/dist/types/transport/node/builders/usync.d.ts +16 -0
- package/dist/types/transport/node/helpers.d.ts +3 -1
- package/dist/types/transport/node/mex/argo-decoder.d.ts +11 -0
- package/dist/types/transport/node/mex/client.d.ts +29 -0
- package/dist/types/transport/node/query.d.ts +19 -1
- package/dist/types/transport/node/usync.d.ts +3 -0
- package/dist/types/transport/noise/WaMobileClientPayload.d.ts +34 -0
- package/dist/types/transport/noise/WaNoiseCert.d.ts +12 -1
- package/dist/types/transport/noise/WaNoiseHandshake.d.ts +12 -6
- package/dist/types/transport/noise/WaNoiseSession.d.ts +1 -1
- package/dist/types/transport/noise/WaNoiseSocket.d.ts +12 -6
- package/dist/types/transport/noise/constants.d.ts +4 -5
- package/dist/types/transport/proxy.d.ts +5 -0
- package/dist/types/transport/types.d.ts +15 -0
- package/dist/types/transport/wa-web-version-fetcher.d.ts +44 -0
- package/dist/types/util/async.d.ts +4 -0
- package/dist/types/util/bytes.d.ts +36 -1
- package/dist/types/util/clock.d.ts +6 -0
- package/dist/types/util/coercion.d.ts +25 -0
- package/dist/types/util/collections.d.ts +8 -0
- package/dist/types/util/index.d.ts +2 -2
- package/dist/types/util/primitives.d.ts +11 -0
- package/dist/types/util/runtime.d.ts +5 -0
- package/dist/types/version-spec.d.ts +1 -0
- package/dist/util/async.js +4 -0
- package/dist/util/bytes.js +37 -2
- package/dist/util/clock.js +18 -0
- package/dist/util/coercion.js +48 -3
- package/dist/util/collections.js +12 -0
- package/dist/util/index.js +7 -1
- package/dist/util/primitives.js +20 -0
- package/dist/util/runtime.js +5 -0
- package/dist/version-spec.js +5 -0
- package/package.json +37 -11
- package/spec/appstate/index.d.ts +188 -0
- package/spec/appstate/index.js +850 -0
- package/spec/mex/index.d.ts +4172 -0
- package/spec/mex/index.js +261 -0
- package/spec/proto/index.d.ts +16305 -0
- package/spec/proto/index.js +1 -0
- package/spec/version/index.d.ts +4 -0
- package/spec/version/index.js +9 -0
- package/spec/version/version.json +3 -0
- package/dist/auth/flow/WaAuthCredentialsFlow.js +0 -130
- package/dist/auth/pairing/WaPairingCodeCrypto.js +0 -77
- package/dist/auth/pairing/constants.js +0 -5
- package/dist/client/connection/WaKeyShareCoordinator.js +0 -63
- package/dist/client/events/chat.js +0 -227
- package/dist/client/incoming.js +0 -269
- package/dist/client/mailbox.js +0 -50
- package/dist/client/messages.js +0 -228
- package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +0 -125
- package/dist/esm/auth/pairing/WaPairingCodeCrypto.js +0 -73
- package/dist/esm/auth/pairing/constants.js +0 -2
- package/dist/esm/client/connection/WaKeyShareCoordinator.js +0 -59
- package/dist/esm/client/events/chat.js +0 -224
- package/dist/esm/client/incoming.js +0 -260
- package/dist/esm/client/mailbox.js +0 -47
- package/dist/esm/client/messages.js +0 -224
- package/dist/esm/media/WaMediaCrypto.js +0 -304
- package/dist/esm/message/addon-crypto.js +0 -59
- package/dist/esm/message/incoming.js +0 -325
- package/dist/esm/message/phash.js +0 -27
- package/dist/esm/signal/crypto/WaAdvSignature.js +0 -64
- package/dist/esm/store/locks/participants.lock.js +0 -20
- package/dist/esm/store/providers/memory/contact.store.js +0 -28
- package/dist/esm/store/providers/memory/device-list.store.js +0 -64
- package/dist/esm/store/providers/memory/signal.store.js +0 -199
- package/dist/esm/transport/node/builders/index.js +0 -11
- package/dist/media/WaMediaCrypto.js +0 -308
- package/dist/message/addon-crypto.js +0 -65
- package/dist/message/phash.js +0 -30
- package/dist/signal/crypto/WaAdvSignature.js +0 -76
- package/dist/store/locks/participants.lock.js +0 -23
- package/dist/store/providers/memory/contact.store.js +0 -32
- package/dist/store/providers/memory/device-list.store.js +0 -68
- package/dist/store/providers/memory/signal.store.js +0 -203
- package/dist/transport/node/builders/index.js +0 -51
- package/dist/types/appstate/WaAppStateSyncClient.d.ts +0 -66
- package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +0 -14
- package/dist/types/auth/pairing/constants.d.ts +0 -2
- package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +0 -14
- package/dist/types/client/events/chat.d.ts +0 -3
- package/dist/types/client/history-sync.d.ts +0 -20
- package/dist/types/client/incoming.d.ts +0 -37
- package/dist/types/client/mailbox.d.ts +0 -10
- package/dist/types/client/messages.d.ts +0 -16
- package/dist/types/client/messaging/participants.d.ts +0 -13
- package/dist/types/media/WaMediaCrypto.d.ts +0 -13
- package/dist/types/media/conn.d.ts +0 -3
- package/dist/types/message/addon-crypto.d.ts +0 -25
- package/dist/types/message/content.d.ts +0 -12
- package/dist/types/message/incoming.d.ts +0 -18
- package/dist/types/signal/crypto/constants.d.ts +0 -5
- package/dist/types/store/contracts/participants.store.d.ts +0 -13
- package/dist/types/store/locks/participants.lock.d.ts +0 -2
- package/dist/types/store/providers/memory/participants.store.d.ts +0 -17
- package/dist/types/store/providers/memory/signal.store.d.ts +0 -58
- package/dist/types/transport/node/builders/index.d.ts +0 -11
- package/proto/index.d.ts +0 -10903
- package/proto/index.js +0 -1
- /package/dist/{store/contracts/participants.store.js → client/newsletter/types.js} +0 -0
- /package/dist/esm/{store/contracts/participants.store.js → client/newsletter/types.js} +0 -0
- /package/dist/esm/message/{device-sent.js → encode/device-sent.js} +0 -0
- /package/dist/message/{device-sent.js → encode/device-sent.js} +0 -0
- /package/dist/types/message/{padding.d.ts → encode/padding.d.ts} +0 -0
|
@@ -1,65 +1,49 @@
|
|
|
1
1
|
import { randomBytesAsync, sha256 } from '../../crypto/index.js';
|
|
2
|
+
import { md5Bytes } from '../../crypto/core/primitives.js';
|
|
2
3
|
import { PromiseDedup } from '../../infra/perf/PromiseDedup.js';
|
|
3
|
-
import { ensureMessageSecret } from '../../message/index.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
4
|
+
import { assertMessageSecret, ensureMessageSecret } from '../../message/index.js';
|
|
5
|
+
import { applyContextInfo, resolveSendContextInfo } from '../../message/context-info.js';
|
|
6
|
+
import { injectDeviceListMetadata, resolveIcdcMeta } from '../../message/crypto/icdc.js';
|
|
7
|
+
import { computePhashV2 } from '../../message/crypto/phash.js';
|
|
8
|
+
import { buildReportingTokenArtifacts } from '../../message/crypto/reporting-token.js';
|
|
9
|
+
import { isSendAddonCryptoMessage, isSendMediaMessage, isSendTextMessage, needsSecretPersistence, resolveButtonAddonKind, resolveDecryptFailAttr, resolveEditAttr, resolveEncMediaType, resolveMessageTypeAttr, resolveMetaAttrs, wrapAsViewOnce } from '../../message/encode/content.js';
|
|
10
|
+
import { wrapDeviceSentMessage } from '../../message/encode/device-sent.js';
|
|
11
|
+
import { writeRandomPadMax16 } from '../../message/encode/padding.js';
|
|
12
|
+
import { buildBotInvokeProtoCopy, extractInvokedBotJid, genBotMsgSecret } from '../../message/kinds/bot.js';
|
|
10
13
|
import { proto } from '../../proto.js';
|
|
11
14
|
import { WA_DEFAULTS } from '../../protocol/constants.js';
|
|
12
|
-
import { isGroupJid, normalizeDeviceJid, normalizeRecipientJid, parseJidFull, parseSignalAddressFromJid,
|
|
13
|
-
import { signalAddressKey } from '../../protocol/jid.js';
|
|
15
|
+
import { isBotJid, isGroupJid, isHostedDeviceJid, isLidJid, isNewsletterJid, normalizeDeviceJid, normalizeRecipientJid, parseJidFull, parseSignalAddressFromJid, signalAddressKey, toUserJid } from '../../protocol/jid.js';
|
|
14
16
|
import { encodeBinaryNode } from '../../transport/binary/index.js';
|
|
15
|
-
import { buildDirectMessageFanoutNode, buildGroupSenderKeyMessageNode, buildMetaNode } from '../../transport/node/builders/message.js';
|
|
16
|
-
import { bytesToHex,
|
|
17
|
+
import { buildButtonAddonNode, buildDirectMessageFanoutNode, buildGroupSenderKeyMessageNode, buildMetaNode } from '../../transport/node/builders/message.js';
|
|
18
|
+
import { bytesToHex, TEXT_ENCODER } from '../../util/bytes.js';
|
|
17
19
|
import { toError } from '../../util/primitives.js';
|
|
18
20
|
export class WaMessageDispatchCoordinator {
|
|
19
21
|
constructor(options) {
|
|
20
22
|
this.icdcDedup = new PromiseDedup();
|
|
21
23
|
this.privacyTokenDedup = new PromiseDedup();
|
|
22
24
|
this.distributionDedup = new PromiseDedup();
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
25
|
-
this.
|
|
26
|
-
this.sessionResolver = options.sessionResolver;
|
|
27
|
-
this.fanoutResolver = options.fanoutResolver;
|
|
28
|
-
this.participantsCache = options.participantsCache;
|
|
29
|
-
this.appStateSyncKeyProtocol = options.appStateSyncKeyProtocol;
|
|
30
|
-
this.buildMessageContent = options.buildMessageContent;
|
|
31
|
-
this.senderKeyManager = options.senderKeyManager;
|
|
32
|
-
this.signalProtocol = options.signalProtocol;
|
|
33
|
-
this.signalStore = options.signalStore;
|
|
34
|
-
this.deviceListStore = options.deviceListStore;
|
|
35
|
-
this.getCurrentMeJid = options.getCurrentMeJid;
|
|
36
|
-
this.getCurrentMeLid = options.getCurrentMeLid;
|
|
37
|
-
this.getCurrentSignedIdentity = options.getCurrentSignedIdentity;
|
|
38
|
-
this.resolvePrivacyTokenNode = options.resolvePrivacyTokenNode;
|
|
39
|
-
this.onDirectMessageSent = options.onDirectMessageSent;
|
|
25
|
+
this.deps = options;
|
|
26
|
+
this.mobileMessageIdFormat = options.mobileMessageIdFormat ?? false;
|
|
27
|
+
this.serverClock = options.serverClock;
|
|
40
28
|
}
|
|
41
29
|
async publishMessageNode(node, options = {}) {
|
|
42
|
-
this.logger.
|
|
30
|
+
this.deps.logger.trace('wa client publish message node', {
|
|
43
31
|
tag: node.tag,
|
|
44
32
|
type: node.attrs.type,
|
|
45
33
|
to: node.attrs.to
|
|
46
34
|
});
|
|
47
|
-
const messageType = node.attrs.type ?? 'text';
|
|
48
35
|
const replayPayload = {
|
|
49
36
|
mode: 'opaque_node',
|
|
50
37
|
node: encodeBinaryNode(node)
|
|
51
38
|
};
|
|
52
|
-
return this.retryTracker.track({
|
|
39
|
+
return this.deps.retryTracker.track({
|
|
53
40
|
messageIdHint: node.attrs.id,
|
|
54
41
|
toJid: node.attrs.to,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
participantJid: node.attrs.participant,
|
|
58
|
-
recipientJid: node.attrs.recipient
|
|
59
|
-
}, async () => this.messageClient.publishNode(node, options));
|
|
42
|
+
replayPayload
|
|
43
|
+
}, async () => this.deps.messageClient.publishNode(node, options));
|
|
60
44
|
}
|
|
61
45
|
async publishEncryptedMessage(input, options = {}) {
|
|
62
|
-
this.logger.
|
|
46
|
+
this.deps.logger.trace('wa client publish encrypted message', {
|
|
63
47
|
to: input.to,
|
|
64
48
|
type: input.type,
|
|
65
49
|
encType: input.encType
|
|
@@ -72,14 +56,12 @@ export class WaMessageDispatchCoordinator {
|
|
|
72
56
|
ciphertext: input.ciphertext,
|
|
73
57
|
participant: input.participant
|
|
74
58
|
};
|
|
75
|
-
return this.retryTracker.track({
|
|
59
|
+
return this.deps.retryTracker.track({
|
|
76
60
|
messageIdHint: input.id,
|
|
77
61
|
toJid: input.to,
|
|
78
|
-
type: input.type ?? 'text',
|
|
79
62
|
replayPayload,
|
|
80
|
-
participantJid: input.participant,
|
|
81
63
|
eligibleRequesterDeviceJids: [input.to]
|
|
82
|
-
}, async () => this.messageClient.publishEncrypted(input, options));
|
|
64
|
+
}, async () => this.deps.messageClient.publishEncrypted(input, options));
|
|
83
65
|
}
|
|
84
66
|
async publishSignalMessage(input, options = {}) {
|
|
85
67
|
this.requireCurrentMeJid('publishSignalMessage');
|
|
@@ -87,30 +69,29 @@ export class WaMessageDispatchCoordinator {
|
|
|
87
69
|
if (address.server === WA_DEFAULTS.GROUP_SERVER) {
|
|
88
70
|
throw new Error('publishSignalMessage currently supports only direct chats; use sender-key flow for groups');
|
|
89
71
|
}
|
|
90
|
-
this.logger.
|
|
72
|
+
this.deps.logger.trace('wa client publish signal message', {
|
|
91
73
|
to: input.to,
|
|
92
74
|
type: input.type
|
|
93
75
|
});
|
|
94
76
|
const [paddedPlaintext] = await Promise.all([
|
|
95
77
|
writeRandomPadMax16(input.plaintext),
|
|
96
|
-
this.sessionResolver.ensureSession(address, input.to, input.expectedIdentity)
|
|
78
|
+
this.deps.sessionResolver.ensureSession(address, input.to, input.expectedIdentity)
|
|
97
79
|
]);
|
|
98
|
-
const encrypted = await this.signalProtocol.encryptMessage(address, paddedPlaintext, input.expectedIdentity);
|
|
80
|
+
const encrypted = await this.deps.signalProtocol.encryptMessage(address, paddedPlaintext, input.expectedIdentity);
|
|
99
81
|
const messageType = input.type ?? 'text';
|
|
82
|
+
const deviceIdentity = encrypted.type === 'pkmsg' ? this.getEncodedSignedDeviceIdentity() : undefined;
|
|
100
83
|
const replayPayload = {
|
|
101
84
|
mode: 'plaintext',
|
|
102
85
|
to: input.to,
|
|
103
86
|
type: messageType,
|
|
104
87
|
plaintext: paddedPlaintext
|
|
105
88
|
};
|
|
106
|
-
return this.retryTracker.track({
|
|
89
|
+
return this.deps.retryTracker.track({
|
|
107
90
|
messageIdHint: input.id,
|
|
108
91
|
toJid: input.to,
|
|
109
|
-
type: messageType,
|
|
110
92
|
replayPayload,
|
|
111
|
-
participantJid: input.participant,
|
|
112
93
|
eligibleRequesterDeviceJids: [input.to]
|
|
113
|
-
}, async () => this.messageClient.publishEncrypted({
|
|
94
|
+
}, async () => this.deps.messageClient.publishEncrypted({
|
|
114
95
|
to: input.to,
|
|
115
96
|
encType: encrypted.type,
|
|
116
97
|
ciphertext: encrypted.ciphertext,
|
|
@@ -119,18 +100,130 @@ export class WaMessageDispatchCoordinator {
|
|
|
119
100
|
category: input.category,
|
|
120
101
|
pushPriority: input.pushPriority,
|
|
121
102
|
participant: input.participant,
|
|
122
|
-
deviceFanout: input.deviceFanout
|
|
103
|
+
deviceFanout: input.deviceFanout,
|
|
104
|
+
deviceIdentity,
|
|
105
|
+
metaNode: input.metaNode
|
|
123
106
|
}, options));
|
|
124
107
|
}
|
|
125
108
|
async sendMessage(to, content, options = {}) {
|
|
126
109
|
const recipientJid = normalizeRecipientJid(to);
|
|
127
|
-
|
|
128
|
-
this.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
110
|
+
if (isNewsletterJid(recipientJid)) {
|
|
111
|
+
if (!this.deps.sendNewsletterMessage) {
|
|
112
|
+
throw new Error('newsletter sendMessage requires sendNewsletterMessage dependency');
|
|
113
|
+
}
|
|
114
|
+
const newsletterCtx = resolveSendContextInfo({
|
|
115
|
+
contentLevel: pickContentContextInfo(content),
|
|
116
|
+
optionsLevel: options.contextInfo,
|
|
117
|
+
quote: options.quote,
|
|
118
|
+
forward: options.forward,
|
|
119
|
+
mentions: options.mentions
|
|
120
|
+
});
|
|
121
|
+
assertNewsletterContextInfoCompatible(newsletterCtx);
|
|
122
|
+
const sendOptions = await this.withResolvedMessageId(options);
|
|
123
|
+
return this.deps.sendNewsletterMessage(recipientJid, content, sendOptions, newsletterCtx);
|
|
124
|
+
}
|
|
125
|
+
let built;
|
|
126
|
+
let sendOptions;
|
|
127
|
+
if (isSendAddonCryptoMessage(content)) {
|
|
128
|
+
sendOptions = await this.withResolvedMessageId(options);
|
|
129
|
+
const meJid = this.deps.getCurrentCredentials()?.meJid;
|
|
130
|
+
if (!meJid) {
|
|
131
|
+
throw new Error(`${content.type} sendMessage requires registered meJid`);
|
|
132
|
+
}
|
|
133
|
+
built = await this.deps.buildMessageContent(content, {
|
|
134
|
+
to: recipientJid,
|
|
135
|
+
outgoingStanzaId: sendOptions.id,
|
|
136
|
+
meJid: toUserJid(meJid)
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
;
|
|
141
|
+
[built, sendOptions] = await Promise.all([
|
|
142
|
+
this.deps.buildMessageContent(content, { to: recipientJid }),
|
|
143
|
+
this.withResolvedMessageId(options)
|
|
144
|
+
]);
|
|
145
|
+
}
|
|
146
|
+
let optionsCtx = options.contextInfo;
|
|
147
|
+
if (options.expirationSeconds !== undefined) {
|
|
148
|
+
optionsCtx = { ...optionsCtx, expirationSeconds: options.expirationSeconds };
|
|
149
|
+
}
|
|
150
|
+
if (isGroupJid(recipientJid) &&
|
|
151
|
+
optionsCtx?.expirationSeconds === undefined &&
|
|
152
|
+
!options.disableGroupEphemeralAutoInject) {
|
|
153
|
+
const cachedEphemeral = await this.deps.groupMetadataCache.resolveEphemeral(recipientJid);
|
|
154
|
+
if (cachedEphemeral !== null && cachedEphemeral > 0) {
|
|
155
|
+
optionsCtx = { ...optionsCtx, expirationSeconds: cachedEphemeral };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const ctx = resolveSendContextInfo({
|
|
159
|
+
contentLevel: pickContentContextInfo(content),
|
|
160
|
+
optionsLevel: optionsCtx,
|
|
161
|
+
quote: options.quote,
|
|
162
|
+
forward: options.forward,
|
|
163
|
+
mentions: options.mentions,
|
|
164
|
+
meLid: this.deps.getCurrentCredentials()?.meLid
|
|
165
|
+
});
|
|
166
|
+
const withCtx = ctx ? applyContextInfo(built.message, ctx) : built.message;
|
|
167
|
+
const withViewOnce = options.viewOnce ? wrapAsViewOnce(withCtx) : withCtx;
|
|
168
|
+
const editKey = options.editKey;
|
|
169
|
+
let editId;
|
|
170
|
+
let editParticipant;
|
|
171
|
+
let editTimestamp;
|
|
172
|
+
if (editKey) {
|
|
173
|
+
if ('rawNode' in editKey) {
|
|
174
|
+
editId = editKey.key?.id ?? undefined;
|
|
175
|
+
editParticipant = editKey.key?.participant ?? undefined;
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
editId = editKey.id;
|
|
179
|
+
editParticipant = editKey.participant;
|
|
180
|
+
editTimestamp = 'timestampMs' in editKey ? editKey.timestampMs : undefined;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const message = editKey
|
|
184
|
+
? {
|
|
185
|
+
protocolMessage: {
|
|
186
|
+
type: proto.Message.ProtocolMessage.Type.MESSAGE_EDIT,
|
|
187
|
+
key: {
|
|
188
|
+
remoteJid: recipientJid,
|
|
189
|
+
fromMe: true,
|
|
190
|
+
id: editId,
|
|
191
|
+
...(editParticipant ? { participant: editParticipant } : {})
|
|
192
|
+
},
|
|
193
|
+
editedMessage: withViewOnce,
|
|
194
|
+
timestampMs: editTimestamp ?? this.serverClock.nowMs()
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
: withViewOnce;
|
|
198
|
+
const upload = built.upload;
|
|
199
|
+
const messageWithOverride = options.messageSecret
|
|
200
|
+
? {
|
|
201
|
+
...message,
|
|
202
|
+
messageContextInfo: {
|
|
203
|
+
...(message.messageContextInfo ?? {}),
|
|
204
|
+
messageSecret: assertMessageSecret(options.messageSecret, 'options.messageSecret')
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
: message;
|
|
208
|
+
const messageWithSecret = await ensureMessageSecret(messageWithOverride);
|
|
209
|
+
const rawSecret = messageWithSecret.messageContextInfo?.messageSecret;
|
|
210
|
+
if (rawSecret &&
|
|
211
|
+
rawSecret.length > 0 &&
|
|
212
|
+
sendOptions.id &&
|
|
213
|
+
needsSecretPersistence(messageWithSecret)) {
|
|
214
|
+
const meJid = this.deps.getCurrentCredentials()?.meJid ?? '';
|
|
215
|
+
void this.deps.messageSecretStore
|
|
216
|
+
.set(sendOptions.id, { secret: rawSecret, senderJid: meJid })
|
|
217
|
+
.catch((error) => {
|
|
218
|
+
this.deps.logger.warn('failed to persist outgoing message secret', {
|
|
219
|
+
id: sendOptions.id,
|
|
220
|
+
to: recipientJid,
|
|
221
|
+
message: toError(error).message
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
const meJid = this.deps.getCurrentCredentials()?.meJid;
|
|
226
|
+
const regInfo = meJid ? await this.deps.signalStore.getRegistrationInfo() : null;
|
|
134
227
|
const localPubKey = regInfo?.identityKeyPair.pubKey;
|
|
135
228
|
const meParsed = meJid ? parseJidFull(meJid) : undefined;
|
|
136
229
|
const meUserJid = meParsed?.userJid;
|
|
@@ -142,67 +235,343 @@ export class WaMessageDispatchCoordinator {
|
|
|
142
235
|
]);
|
|
143
236
|
const messageWithIcdc = injectDeviceListMetadata(messageWithSecret, senderIcdc, recipientIcdc);
|
|
144
237
|
const plaintext = await writeRandomPadMax16(proto.Message.encode(messageWithIcdc).finish());
|
|
145
|
-
const
|
|
146
|
-
const
|
|
147
|
-
|
|
238
|
+
const buttonAddonKind = resolveButtonAddonKind(messageWithIcdc);
|
|
239
|
+
const buttonAddonNode = buttonAddonKind ? buildButtonAddonNode(buttonAddonKind) : undefined;
|
|
240
|
+
// when a <biz> companion is attached the stanza must advertise type=text and
|
|
241
|
+
// omit enc.mediatype; sending type=media + mediatype=list/button alongside the
|
|
242
|
+
// companion is rejected by the server as SMAX_INVALID (479).
|
|
243
|
+
const type = buttonAddonKind ? 'text' : resolveMessageTypeAttr(messageWithIcdc);
|
|
244
|
+
const edit = resolveEditAttr(messageWithIcdc) ?? undefined;
|
|
245
|
+
const mediatype = buttonAddonKind
|
|
246
|
+
? undefined
|
|
247
|
+
: (resolveEncMediaType(messageWithIcdc) ?? undefined);
|
|
148
248
|
const metaAttrs = resolveMetaAttrs(messageWithIcdc);
|
|
149
249
|
const metaNode = metaAttrs ? buildMetaNode(metaAttrs) : undefined;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
250
|
+
const customNodes = [];
|
|
251
|
+
if (metaNode)
|
|
252
|
+
customNodes.push(metaNode);
|
|
253
|
+
if (buttonAddonNode)
|
|
254
|
+
customNodes.push(buttonAddonNode);
|
|
255
|
+
if (options.customNodes) {
|
|
256
|
+
for (const node of options.customNodes) {
|
|
257
|
+
customNodes.push(node);
|
|
153
258
|
}
|
|
154
|
-
return this.publishGroupSenderKeyMessage(recipientJid, messageWithIcdc, plaintext, type, sendOptions, {}, edit, mediatype, metaNode);
|
|
155
259
|
}
|
|
156
|
-
const
|
|
157
|
-
|
|
260
|
+
const decryptFail = resolveDecryptFailAttr(messageWithIcdc);
|
|
261
|
+
const envelope = {
|
|
262
|
+
message: messageWithIcdc,
|
|
263
|
+
plaintext,
|
|
264
|
+
type,
|
|
265
|
+
edit,
|
|
266
|
+
mediatype,
|
|
267
|
+
decryptFail,
|
|
268
|
+
customNodes: customNodes.length > 0 ? customNodes : undefined,
|
|
269
|
+
sendOptions
|
|
270
|
+
};
|
|
271
|
+
const directRecipientJid = isGroup
|
|
272
|
+
? recipientJid
|
|
273
|
+
: await this.resolveDirectRecipientLid(toUserJid(recipientJid));
|
|
274
|
+
const publishResult = isGroup
|
|
275
|
+
? this.shouldUseGroupDirectPath(messageWithIcdc)
|
|
276
|
+
? await this.publishGroupDirectMessage(recipientJid, envelope)
|
|
277
|
+
: await this.publishGroupSenderKeyMessage(recipientJid, envelope)
|
|
278
|
+
: await this.publishDirectSignalMessageWithFanout(directRecipientJid, envelope);
|
|
279
|
+
return upload ? { ...publishResult, upload } : publishResult;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* For a 1:1 recipient passed in PN form, returns the LID-addressed user JID
|
|
283
|
+
* (cache-first; falls back to a one-shot `queryLidsByPhoneJids`). Switching
|
|
284
|
+
* to LID before fanout ensures the envelope, eligible-requester list, and
|
|
285
|
+
* retry-receipt addressing all agree, which keeps the retry tracker from
|
|
286
|
+
* rejecting receipts that arrive in LID form. Returns the original PN if
|
|
287
|
+
* no LID is known/resolvable. Inputs already in LID form pass through.
|
|
288
|
+
*/
|
|
289
|
+
async resolveDirectRecipientLid(pnUserJid) {
|
|
290
|
+
if (isLidJid(pnUserJid))
|
|
291
|
+
return pnUserJid;
|
|
292
|
+
const cached = await this.deps.deviceListStore.findByAnyUserJid(pnUserJid);
|
|
293
|
+
if (cached) {
|
|
294
|
+
if (isLidJid(cached.userJid))
|
|
295
|
+
return cached.userJid;
|
|
296
|
+
if (cached.altUserJid && isLidJid(cached.altUserJid))
|
|
297
|
+
return cached.altUserJid;
|
|
298
|
+
}
|
|
299
|
+
try {
|
|
300
|
+
const results = await this.deps.signalDeviceSync.queryLidsByPhoneJids([pnUserJid]);
|
|
301
|
+
const match = results.find((entry) => entry.phoneJid === pnUserJid);
|
|
302
|
+
if (match?.lidJid)
|
|
303
|
+
return match.lidJid;
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
this.deps.logger.debug('lid resolution failed for direct recipient', {
|
|
307
|
+
pnUserJid,
|
|
308
|
+
message: toError(error).message
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
return pnUserJid;
|
|
158
312
|
}
|
|
159
313
|
async syncSignalSession(jid, reasonIdentity = false) {
|
|
160
314
|
const address = parseSignalAddressFromJid(jid);
|
|
161
315
|
if (address.server === WA_DEFAULTS.GROUP_SERVER) {
|
|
162
316
|
throw new Error('syncSignalSession supports only direct chats');
|
|
163
317
|
}
|
|
164
|
-
await this.sessionResolver.ensureSession(address, jid, undefined, reasonIdentity);
|
|
318
|
+
await this.deps.sessionResolver.ensureSession(address, jid, undefined, reasonIdentity);
|
|
165
319
|
}
|
|
166
320
|
async sendReceipt(input) {
|
|
167
|
-
await this.messageClient.sendReceipt(input);
|
|
321
|
+
await this.deps.messageClient.sendReceipt(input);
|
|
322
|
+
}
|
|
323
|
+
async publishProtocolMessageToDevice(deviceJid, protocolMessage, options) {
|
|
324
|
+
const meJid = this.deps.getCurrentCredentials()?.meJid;
|
|
325
|
+
const meParsed = meJid ? parseJidFull(meJid) : undefined;
|
|
326
|
+
const meUserJid = meParsed?.userJid;
|
|
327
|
+
let senderIcdc = null;
|
|
328
|
+
if (meUserJid) {
|
|
329
|
+
const regInfo = await this.deps.signalStore.getRegistrationInfo();
|
|
330
|
+
const localPubKey = regInfo?.identityKeyPair.pubKey;
|
|
331
|
+
const localIdentity = meParsed && localPubKey
|
|
332
|
+
? { address: meParsed.address, pubKey: localPubKey }
|
|
333
|
+
: undefined;
|
|
334
|
+
senderIcdc = await this.resolveUserIcdc(meUserJid, localIdentity);
|
|
335
|
+
}
|
|
336
|
+
const message = injectDeviceListMetadata({ protocolMessage }, senderIcdc, null);
|
|
337
|
+
return this.publishSignalMessage({
|
|
338
|
+
to: deviceJid,
|
|
339
|
+
plaintext: proto.Message.encode(message).finish(),
|
|
340
|
+
id: options?.id,
|
|
341
|
+
type: 'text',
|
|
342
|
+
category: 'peer',
|
|
343
|
+
pushPriority: options?.pushPriority ?? 'high',
|
|
344
|
+
metaNode: buildMetaNode({ appdata: 'default' })
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
async publishStatusMessage(input) {
|
|
348
|
+
if (input.recipients.length === 0) {
|
|
349
|
+
throw new Error('publishStatusMessage requires at least one recipient');
|
|
350
|
+
}
|
|
351
|
+
this.requireCurrentMeJid('publishStatusMessage');
|
|
352
|
+
const meLid = this.deps.getCurrentCredentials()?.meLid;
|
|
353
|
+
if (!meLid) {
|
|
354
|
+
throw new Error('publishStatusMessage requires current me lid');
|
|
355
|
+
}
|
|
356
|
+
const senderJid = normalizeDeviceJid(meLid);
|
|
357
|
+
const meUserLid = toUserJid(meLid);
|
|
358
|
+
const seen = new Set();
|
|
359
|
+
const recipientsWithSelf = [];
|
|
360
|
+
for (const jid of input.recipients) {
|
|
361
|
+
if (seen.has(jid))
|
|
362
|
+
continue;
|
|
363
|
+
seen.add(jid);
|
|
364
|
+
recipientsWithSelf.push(jid);
|
|
365
|
+
}
|
|
366
|
+
if (!seen.has(meUserLid)) {
|
|
367
|
+
recipientsWithSelf.push(meUserLid);
|
|
368
|
+
}
|
|
369
|
+
const statusSetting = input.statusSetting ?? 'contacts';
|
|
370
|
+
return this.publishSenderKeyFanout({
|
|
371
|
+
groupJid: WA_DEFAULTS.STATUS_BROADCAST_JID,
|
|
372
|
+
senderJid,
|
|
373
|
+
recipients: recipientsWithSelf,
|
|
374
|
+
message: input.message,
|
|
375
|
+
options: input.options ?? {},
|
|
376
|
+
logTag: 'status',
|
|
377
|
+
replayStatusSetting: statusSetting,
|
|
378
|
+
// Bare `<to jid=user>` ack hints route the skmsg through primary
|
|
379
|
+
// devices that already hold the sender key.
|
|
380
|
+
customize: async ({ fanoutDeviceJids, distributionParticipants, messageWithSecret, sendOptions }) => {
|
|
381
|
+
const distributedAddressKeys = new Set();
|
|
382
|
+
for (let i = 0; i < distributionParticipants.length; i += 1) {
|
|
383
|
+
distributedAddressKeys.add(signalAddressKey(distributionParticipants[i].address));
|
|
384
|
+
}
|
|
385
|
+
const ackHints = [];
|
|
386
|
+
const seenAck = new Set();
|
|
387
|
+
for (let i = 0; i < fanoutDeviceJids.length; i += 1) {
|
|
388
|
+
const deviceJid = fanoutDeviceJids[i];
|
|
389
|
+
const address = parseSignalAddressFromJid(deviceJid);
|
|
390
|
+
if (distributedAddressKeys.has(signalAddressKey(address)))
|
|
391
|
+
continue;
|
|
392
|
+
if (address.device !== 0)
|
|
393
|
+
continue;
|
|
394
|
+
const userJid = toUserJid(deviceJid);
|
|
395
|
+
if (seenAck.has(userJid))
|
|
396
|
+
continue;
|
|
397
|
+
seenAck.add(userJid);
|
|
398
|
+
ackHints.push({ jid: userJid });
|
|
399
|
+
}
|
|
400
|
+
const reportingArtifacts = await this.tryBuildReportingTokenArtifacts({
|
|
401
|
+
message: messageWithSecret,
|
|
402
|
+
stanzaId: sendOptions.id,
|
|
403
|
+
senderUserJid: toUserJid(senderJid),
|
|
404
|
+
remoteJid: WA_DEFAULTS.STATUS_BROADCAST_JID,
|
|
405
|
+
context: 'status'
|
|
406
|
+
});
|
|
407
|
+
const customNodes = [buildMetaNode({ status_setting: statusSetting })];
|
|
408
|
+
if (reportingArtifacts?.node)
|
|
409
|
+
customNodes.push(reportingArtifacts.node);
|
|
410
|
+
return {
|
|
411
|
+
extraParticipants: ackHints,
|
|
412
|
+
customNodes
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
async publishBroadcastListMessage(input) {
|
|
418
|
+
if (input.recipients.length === 0) {
|
|
419
|
+
throw new Error('publishBroadcastListMessage requires at least one recipient');
|
|
420
|
+
}
|
|
421
|
+
const meJid = this.requireCurrentMeJid('publishBroadcastListMessage');
|
|
422
|
+
const senderJid = normalizeDeviceJid(meJid);
|
|
423
|
+
return this.publishSenderKeyFanout({
|
|
424
|
+
groupJid: input.listJid,
|
|
425
|
+
senderJid,
|
|
426
|
+
recipients: input.recipients,
|
|
427
|
+
message: input.message,
|
|
428
|
+
options: input.options ?? {},
|
|
429
|
+
logTag: 'broadcast list',
|
|
430
|
+
customize: ({ fanoutDeviceJids }) => {
|
|
431
|
+
const phashTargets = new Array(fanoutDeviceJids.length + 1);
|
|
432
|
+
let phashTargetCount = 0;
|
|
433
|
+
for (let i = 0; i < fanoutDeviceJids.length; i += 1) {
|
|
434
|
+
const candidate = fanoutDeviceJids[i];
|
|
435
|
+
if (isHostedDeviceJid(candidate))
|
|
436
|
+
continue;
|
|
437
|
+
phashTargets[phashTargetCount] = candidate;
|
|
438
|
+
phashTargetCount += 1;
|
|
439
|
+
}
|
|
440
|
+
phashTargets[phashTargetCount] = senderJid;
|
|
441
|
+
phashTargets.length = phashTargetCount + 1;
|
|
442
|
+
return Promise.resolve({ phash: computePhashV2(phashTargets) });
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
async publishSenderKeyFanout(input) {
|
|
447
|
+
const sendOptions = await this.withResolvedMessageId(input.options);
|
|
448
|
+
const sender = parseSignalAddressFromJid(input.senderJid);
|
|
449
|
+
const messageWithSecret = await ensureMessageSecret(input.message);
|
|
450
|
+
const plaintext = await writeRandomPadMax16(proto.Message.encode(messageWithSecret).finish());
|
|
451
|
+
const { distributionMessage, ciphertext: groupCiphertext, keyId: senderKeyId } = await this.deps.senderKeyManager.prepareGroupEncryption(input.groupJid, sender, plaintext);
|
|
452
|
+
const { fanoutDeviceJids, distributionParticipants } = await this.encryptGroupDistributionParticipants(input.groupJid, senderKeyId, distributionMessage, input.recipients);
|
|
453
|
+
let shouldAttachDeviceIdentity = false;
|
|
454
|
+
for (let i = 0; i < distributionParticipants.length; i += 1) {
|
|
455
|
+
if (distributionParticipants[i].encType === 'pkmsg') {
|
|
456
|
+
shouldAttachDeviceIdentity = true;
|
|
457
|
+
break;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
const extras = input.customize
|
|
461
|
+
? await input.customize({
|
|
462
|
+
fanoutDeviceJids,
|
|
463
|
+
distributionParticipants,
|
|
464
|
+
messageWithSecret,
|
|
465
|
+
sendOptions
|
|
466
|
+
})
|
|
467
|
+
: {};
|
|
468
|
+
const participants = distributionParticipants.map((p) => ({
|
|
469
|
+
jid: p.jid,
|
|
470
|
+
encType: p.encType,
|
|
471
|
+
ciphertext: p.ciphertext
|
|
472
|
+
}));
|
|
473
|
+
if (extras.extraParticipants) {
|
|
474
|
+
for (const entry of extras.extraParticipants) {
|
|
475
|
+
participants.push(entry);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
const messageNode = buildGroupSenderKeyMessageNode({
|
|
479
|
+
to: input.groupJid,
|
|
480
|
+
type: resolveMessageTypeAttr(messageWithSecret),
|
|
481
|
+
id: sendOptions.id,
|
|
482
|
+
phash: extras.phash,
|
|
483
|
+
edit: resolveEditAttr(messageWithSecret) ?? undefined,
|
|
484
|
+
mediatype: resolveEncMediaType(messageWithSecret) ?? undefined,
|
|
485
|
+
decryptFail: resolveDecryptFailAttr(messageWithSecret),
|
|
486
|
+
groupCiphertext: groupCiphertext.ciphertext,
|
|
487
|
+
participants,
|
|
488
|
+
deviceIdentity: shouldAttachDeviceIdentity
|
|
489
|
+
? this.getEncodedSignedDeviceIdentity()
|
|
490
|
+
: undefined,
|
|
491
|
+
customNodes: extras.customNodes,
|
|
492
|
+
additionalAttributes: sendOptions.additionalAttributes
|
|
493
|
+
});
|
|
494
|
+
const replayPayload = {
|
|
495
|
+
mode: 'plaintext',
|
|
496
|
+
to: input.groupJid,
|
|
497
|
+
type: messageNode.attrs.type,
|
|
498
|
+
plaintext,
|
|
499
|
+
...(input.replayStatusSetting ? { statusSetting: input.replayStatusSetting } : {})
|
|
500
|
+
};
|
|
501
|
+
const result = await this.deps.retryTracker.track({
|
|
502
|
+
messageIdHint: messageNode.attrs.id ?? sendOptions.id,
|
|
503
|
+
toJid: input.groupJid,
|
|
504
|
+
replayPayload,
|
|
505
|
+
eligibleRequesterDeviceJids: undefined
|
|
506
|
+
}, async () => this.deps.messageClient.publishNode(messageNode, sendOptions));
|
|
507
|
+
const distributedAddresses = new Array(distributionParticipants.length);
|
|
508
|
+
for (let i = 0; i < distributionParticipants.length; i += 1) {
|
|
509
|
+
distributedAddresses[i] = distributionParticipants[i].address;
|
|
510
|
+
}
|
|
511
|
+
try {
|
|
512
|
+
await this.deps.senderKeyManager.markSenderKeyDistributed(input.groupJid, senderKeyId, distributedAddresses);
|
|
513
|
+
}
|
|
514
|
+
catch (error) {
|
|
515
|
+
this.deps.logger.warn('failed to mark sender key distribution targets', {
|
|
516
|
+
logTag: input.logTag,
|
|
517
|
+
groupJid: input.groupJid,
|
|
518
|
+
participants: distributedAddresses.length,
|
|
519
|
+
message: toError(error).message
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
return result;
|
|
168
523
|
}
|
|
169
524
|
async requestAppStateSyncKeys(keyIds) {
|
|
170
|
-
return this.appStateSyncKeyProtocol.requestKeys(keyIds);
|
|
525
|
+
return this.deps.appStateSyncKeyProtocol.requestKeys(keyIds);
|
|
171
526
|
}
|
|
172
527
|
async sendAppStateSyncKeyShare(toDeviceJid, keys, missingKeyIds = []) {
|
|
173
|
-
await this.appStateSyncKeyProtocol.sendKeyShare(toDeviceJid, keys, missingKeyIds);
|
|
528
|
+
await this.deps.appStateSyncKeyProtocol.sendKeyShare(toDeviceJid, keys, missingKeyIds);
|
|
174
529
|
}
|
|
175
|
-
async
|
|
176
|
-
await this.
|
|
530
|
+
async mutateGroupMetadataCacheFromGroupEvent(event) {
|
|
531
|
+
await this.deps.groupMetadataCache.mutateFromGroupEvent(event);
|
|
177
532
|
}
|
|
533
|
+
// noop for now
|
|
178
534
|
shouldUseGroupDirectPath(message) {
|
|
179
|
-
|
|
180
|
-
if (protocolType === proto.Message.ProtocolMessage.Type.REVOKE ||
|
|
181
|
-
protocolType === proto.Message.ProtocolMessage.Type.MESSAGE_EDIT) {
|
|
182
|
-
return true;
|
|
183
|
-
}
|
|
184
|
-
return message.keepInChatMessage?.keepType === proto.KeepType.UNDO_KEEP_FOR_ALL;
|
|
535
|
+
return false;
|
|
185
536
|
}
|
|
186
|
-
async publishGroupDirectMessage(groupJid,
|
|
187
|
-
const sendOptions =
|
|
537
|
+
async publishGroupDirectMessage(groupJid, envelope, retryContext = {}) {
|
|
538
|
+
const { message, plaintext, type, edit, mediatype, sendOptions } = envelope;
|
|
188
539
|
const meJid = this.requireCurrentMeJid('sendMessage');
|
|
189
540
|
const participantUserJids = retryContext.forceRefreshParticipants
|
|
190
|
-
? await this.
|
|
191
|
-
: await this.
|
|
541
|
+
? await this.deps.groupMetadataCache.refreshParticipantUsers(groupJid)
|
|
542
|
+
: await this.deps.groupMetadataCache.resolveParticipantUsers(groupJid);
|
|
192
543
|
const addressingMode = retryContext.forceAddressingMode ??
|
|
193
544
|
this.resolveGroupAddressingMode(participantUserJids, groupJid);
|
|
194
545
|
const senderForPhash = this.resolveSenderForAddressingMode(addressingMode, meJid);
|
|
195
|
-
const fanoutDeviceJids = await this.fanoutResolver.resolveGroupParticipantDeviceJids(participantUserJids);
|
|
546
|
+
const fanoutDeviceJids = await this.deps.fanoutResolver.resolveGroupParticipantDeviceJids(participantUserJids);
|
|
196
547
|
if (fanoutDeviceJids.length === 0) {
|
|
197
548
|
throw new Error('group direct send resolved no target devices');
|
|
198
549
|
}
|
|
199
|
-
const resolvedFanoutTargets = await this.sessionResolver.ensureSessionsBatch(fanoutDeviceJids);
|
|
550
|
+
const resolvedFanoutTargets = await this.deps.sessionResolver.ensureSessionsBatch(fanoutDeviceJids);
|
|
551
|
+
const resolvedNormalizedJids = new Set();
|
|
552
|
+
for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
|
|
553
|
+
resolvedNormalizedJids.add(resolvedFanoutTargets[index].jid);
|
|
554
|
+
}
|
|
200
555
|
const uniqueNormalizedFanoutJids = new Set();
|
|
201
556
|
for (let index = 0; index < fanoutDeviceJids.length; index += 1) {
|
|
202
557
|
uniqueNormalizedFanoutJids.add(normalizeDeviceJid(fanoutDeviceJids[index]));
|
|
203
558
|
}
|
|
204
|
-
|
|
205
|
-
|
|
559
|
+
const droppedDevices = [];
|
|
560
|
+
for (const expected of uniqueNormalizedFanoutJids) {
|
|
561
|
+
if (!resolvedNormalizedJids.has(expected)) {
|
|
562
|
+
droppedDevices.push(expected);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
if (droppedDevices.length > 0) {
|
|
566
|
+
this.deps.logger.warn('group direct fanout dropping devices without signal session', {
|
|
567
|
+
groupJid,
|
|
568
|
+
droppedCount: droppedDevices.length,
|
|
569
|
+
totalExpected: uniqueNormalizedFanoutJids.size,
|
|
570
|
+
sample: droppedDevices.slice(0, 3)
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
if (resolvedFanoutTargets.length === 0) {
|
|
574
|
+
throw new Error('group direct send resolved no signal sessions');
|
|
206
575
|
}
|
|
207
576
|
const participantEncryptRequests = new Array(resolvedFanoutTargets.length);
|
|
208
577
|
for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
|
|
@@ -212,7 +581,7 @@ export class WaMessageDispatchCoordinator {
|
|
|
212
581
|
plaintext
|
|
213
582
|
};
|
|
214
583
|
}
|
|
215
|
-
const encryptedParticipants = await this.signalProtocol.encryptMessagesBatch(participantEncryptRequests, resolvedFanoutTargets);
|
|
584
|
+
const encryptedParticipants = await this.deps.signalProtocol.encryptMessagesBatch(participantEncryptRequests, resolvedFanoutTargets);
|
|
216
585
|
const participants = new Array(resolvedFanoutTargets.length);
|
|
217
586
|
for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
|
|
218
587
|
const target = resolvedFanoutTargets[index];
|
|
@@ -230,20 +599,27 @@ export class WaMessageDispatchCoordinator {
|
|
|
230
599
|
}
|
|
231
600
|
}
|
|
232
601
|
const phashTargets = new Array(resolvedFanoutTargets.length + 1);
|
|
602
|
+
let phashTargetCount = 0;
|
|
233
603
|
for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
604
|
+
const candidate = resolvedFanoutTargets[index].jid;
|
|
605
|
+
if (isHostedDeviceJid(candidate))
|
|
606
|
+
continue;
|
|
607
|
+
phashTargets[phashTargetCount] = candidate;
|
|
608
|
+
phashTargetCount += 1;
|
|
609
|
+
}
|
|
610
|
+
phashTargets[phashTargetCount] = senderForPhash;
|
|
611
|
+
phashTargets.length = phashTargetCount + 1;
|
|
612
|
+
const localPhash = computePhashV2(phashTargets);
|
|
613
|
+
const reportingArtifacts = await this.tryBuildReportingTokenArtifacts({
|
|
614
|
+
message,
|
|
615
|
+
stanzaId: sendOptions.id,
|
|
616
|
+
senderUserJid: toUserJid(senderForPhash),
|
|
617
|
+
remoteJid: groupJid,
|
|
618
|
+
context: 'group_direct'
|
|
619
|
+
});
|
|
620
|
+
const customNodes = envelope.customNodes ? [...envelope.customNodes] : [];
|
|
621
|
+
if (reportingArtifacts?.node)
|
|
622
|
+
customNodes.push(reportingArtifacts.node);
|
|
247
623
|
const messageNode = buildDirectMessageFanoutNode({
|
|
248
624
|
to: groupJid,
|
|
249
625
|
type,
|
|
@@ -255,9 +631,10 @@ export class WaMessageDispatchCoordinator {
|
|
|
255
631
|
deviceIdentity: shouldAttachDeviceIdentity
|
|
256
632
|
? this.getEncodedSignedDeviceIdentity()
|
|
257
633
|
: undefined,
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
634
|
+
customNodes: customNodes.length > 0 ? customNodes : undefined,
|
|
635
|
+
mediatype,
|
|
636
|
+
decryptFail: envelope.decryptFail,
|
|
637
|
+
additionalAttributes: sendOptions.additionalAttributes
|
|
261
638
|
});
|
|
262
639
|
const replayPayload = {
|
|
263
640
|
mode: 'plaintext',
|
|
@@ -265,13 +642,12 @@ export class WaMessageDispatchCoordinator {
|
|
|
265
642
|
type,
|
|
266
643
|
plaintext
|
|
267
644
|
};
|
|
268
|
-
const result = await this.retryTracker.track({
|
|
269
|
-
messageIdHint:
|
|
645
|
+
const result = await this.deps.retryTracker.track({
|
|
646
|
+
messageIdHint: messageNode.attrs.id ?? sendOptions.id,
|
|
270
647
|
toJid: groupJid,
|
|
271
|
-
type,
|
|
272
648
|
replayPayload,
|
|
273
649
|
eligibleRequesterDeviceJids: undefined
|
|
274
|
-
}, async () => this.messageClient.publishNode(messageNode, sendOptions));
|
|
650
|
+
}, async () => this.deps.messageClient.publishNode(messageNode, sendOptions));
|
|
275
651
|
const ackError = result.ack.error;
|
|
276
652
|
const serverPhash = result.ack.phash;
|
|
277
653
|
const serverAddressingMode = result.ack.addressingMode;
|
|
@@ -280,7 +656,7 @@ export class WaMessageDispatchCoordinator {
|
|
|
280
656
|
const hasAddressingError = ackError === 421;
|
|
281
657
|
if (!retryContext.retried &&
|
|
282
658
|
(hasPhashMismatch || hasAddressingMismatch || hasAddressingError)) {
|
|
283
|
-
this.logger.warn('group direct publish acknowledged with mismatch metadata', {
|
|
659
|
+
this.deps.logger.warn('group direct publish acknowledged with mismatch metadata', {
|
|
284
660
|
id: result.id,
|
|
285
661
|
groupJid,
|
|
286
662
|
localPhash,
|
|
@@ -289,28 +665,88 @@ export class WaMessageDispatchCoordinator {
|
|
|
289
665
|
serverAddressingMode,
|
|
290
666
|
ackError
|
|
291
667
|
});
|
|
292
|
-
return this.publishGroupDirectMessage(groupJid,
|
|
293
|
-
...
|
|
294
|
-
id: result.id
|
|
668
|
+
return this.publishGroupDirectMessage(groupJid, {
|
|
669
|
+
...envelope,
|
|
670
|
+
sendOptions: { ...sendOptions, id: result.id }
|
|
295
671
|
}, {
|
|
296
672
|
retried: true,
|
|
297
673
|
forceRefreshParticipants: true,
|
|
298
674
|
forceAddressingMode: serverAddressingMode
|
|
299
|
-
}
|
|
675
|
+
});
|
|
300
676
|
}
|
|
301
677
|
return result;
|
|
302
678
|
}
|
|
303
|
-
|
|
304
|
-
|
|
679
|
+
// Returns null on any failure so the group send still goes out unchanged.
|
|
680
|
+
async buildBotSidecarParticipant(message) {
|
|
681
|
+
const botJid = extractInvokedBotJid(message);
|
|
682
|
+
if (!botJid)
|
|
683
|
+
return null;
|
|
684
|
+
let address;
|
|
685
|
+
try {
|
|
686
|
+
address = parseSignalAddressFromJid(botJid);
|
|
687
|
+
}
|
|
688
|
+
catch (error) {
|
|
689
|
+
this.deps.logger.debug('bot sidecar: failed to parse bot jid', {
|
|
690
|
+
botJid,
|
|
691
|
+
message: toError(error).message
|
|
692
|
+
});
|
|
693
|
+
return null;
|
|
694
|
+
}
|
|
695
|
+
let resolvedTargets;
|
|
696
|
+
try {
|
|
697
|
+
resolvedTargets = await this.deps.sessionResolver.ensureSessionsBatch([botJid]);
|
|
698
|
+
}
|
|
699
|
+
catch (error) {
|
|
700
|
+
this.deps.logger.debug('bot sidecar: signal session sync failed', {
|
|
701
|
+
botJid,
|
|
702
|
+
message: toError(error).message
|
|
703
|
+
});
|
|
704
|
+
return null;
|
|
705
|
+
}
|
|
706
|
+
if (resolvedTargets.length === 0) {
|
|
707
|
+
this.deps.logger.debug('bot sidecar: signal session not established', { botJid });
|
|
708
|
+
return null;
|
|
709
|
+
}
|
|
710
|
+
// The bot seeds its streaming-response keys from this HKDF derivation.
|
|
711
|
+
const parentMessageSecret = message.messageContextInfo?.messageSecret;
|
|
712
|
+
const botMessageSecret = parentMessageSecret && parentMessageSecret.byteLength > 0
|
|
713
|
+
? genBotMsgSecret(parentMessageSecret)
|
|
714
|
+
: undefined;
|
|
715
|
+
const botCopy = buildBotInvokeProtoCopy(message, botMessageSecret);
|
|
716
|
+
const botPlaintext = await writeRandomPadMax16(proto.Message.encode(botCopy).finish());
|
|
717
|
+
try {
|
|
718
|
+
const [encrypted] = await this.deps.signalProtocol.encryptMessagesBatch([{ address, plaintext: botPlaintext }], resolvedTargets.map((target) => ({
|
|
719
|
+
address: target.address,
|
|
720
|
+
session: target.session
|
|
721
|
+
})));
|
|
722
|
+
if (!encrypted)
|
|
723
|
+
return null;
|
|
724
|
+
this.deps.logger.trace('bot sidecar encrypted', { botJid, encType: encrypted.type });
|
|
725
|
+
return {
|
|
726
|
+
jid: botJid,
|
|
727
|
+
encType: encrypted.type,
|
|
728
|
+
ciphertext: encrypted.ciphertext
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
catch (error) {
|
|
732
|
+
this.deps.logger.debug('bot sidecar: encryption failed', {
|
|
733
|
+
botJid,
|
|
734
|
+
message: toError(error).message
|
|
735
|
+
});
|
|
736
|
+
return null;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
async publishGroupSenderKeyMessage(groupJid, envelope, retryContext = {}) {
|
|
740
|
+
const { message, plaintext, type, edit, mediatype, sendOptions } = envelope;
|
|
305
741
|
const meJid = this.requireCurrentMeJid('sendMessage');
|
|
306
742
|
const participantUserJids = retryContext.forceRefreshParticipants
|
|
307
|
-
? await this.
|
|
308
|
-
: await this.
|
|
743
|
+
? await this.deps.groupMetadataCache.refreshParticipantUsers(groupJid)
|
|
744
|
+
: await this.deps.groupMetadataCache.resolveParticipantUsers(groupJid);
|
|
309
745
|
const addressingMode = retryContext.forceAddressingMode ??
|
|
310
746
|
this.resolveGroupAddressingMode(participantUserJids, groupJid);
|
|
311
747
|
const senderJid = this.resolveSenderForAddressingMode(addressingMode, meJid);
|
|
312
748
|
const sender = parseSignalAddressFromJid(senderJid);
|
|
313
|
-
const { distributionMessage: senderKeyDistributionMessage, ciphertext: groupCiphertext, keyId: senderKeyId } = await this.senderKeyManager.prepareGroupEncryption(groupJid, sender, plaintext);
|
|
749
|
+
const { distributionMessage: senderKeyDistributionMessage, ciphertext: groupCiphertext, keyId: senderKeyId } = await this.deps.senderKeyManager.prepareGroupEncryption(groupJid, sender, plaintext);
|
|
314
750
|
const distributionData = await this.distributionDedup.run(`dist:${groupJid}:${senderKeyId}`, () => this.encryptGroupDistributionParticipants(groupJid, senderKeyId, senderKeyDistributionMessage, participantUserJids));
|
|
315
751
|
const { fanoutDeviceJids, distributionParticipants } = distributionData;
|
|
316
752
|
let shouldAttachDeviceIdentity = false;
|
|
@@ -321,20 +757,28 @@ export class WaMessageDispatchCoordinator {
|
|
|
321
757
|
}
|
|
322
758
|
}
|
|
323
759
|
const phashTargets = new Array(fanoutDeviceJids.length + 1);
|
|
760
|
+
let phashTargetCount = 0;
|
|
324
761
|
for (let index = 0; index < fanoutDeviceJids.length; index += 1) {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
762
|
+
const candidate = fanoutDeviceJids[index];
|
|
763
|
+
if (isHostedDeviceJid(candidate))
|
|
764
|
+
continue;
|
|
765
|
+
phashTargets[phashTargetCount] = candidate;
|
|
766
|
+
phashTargetCount += 1;
|
|
767
|
+
}
|
|
768
|
+
phashTargets[phashTargetCount] = senderJid;
|
|
769
|
+
phashTargets.length = phashTargetCount + 1;
|
|
770
|
+
const localPhash = computePhashV2(phashTargets);
|
|
771
|
+
const reportingArtifacts = await this.tryBuildReportingTokenArtifacts({
|
|
772
|
+
message,
|
|
773
|
+
stanzaId: sendOptions.id,
|
|
774
|
+
senderUserJid: toUserJid(senderJid),
|
|
775
|
+
remoteJid: groupJid,
|
|
776
|
+
context: 'group_sender_key'
|
|
777
|
+
});
|
|
778
|
+
const botSidecar = await this.buildBotSidecarParticipant(message);
|
|
779
|
+
const customNodes = envelope.customNodes ? [...envelope.customNodes] : [];
|
|
780
|
+
if (reportingArtifacts?.node)
|
|
781
|
+
customNodes.push(reportingArtifacts.node);
|
|
338
782
|
const messageNode = buildGroupSenderKeyMessageNode({
|
|
339
783
|
to: groupJid,
|
|
340
784
|
type,
|
|
@@ -344,12 +788,14 @@ export class WaMessageDispatchCoordinator {
|
|
|
344
788
|
addressingMode,
|
|
345
789
|
groupCiphertext: groupCiphertext.ciphertext,
|
|
346
790
|
participants: distributionParticipants,
|
|
347
|
-
deviceIdentity: shouldAttachDeviceIdentity
|
|
791
|
+
deviceIdentity: shouldAttachDeviceIdentity || botSidecar?.encType === 'pkmsg'
|
|
348
792
|
? this.getEncodedSignedDeviceIdentity()
|
|
349
793
|
: undefined,
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
794
|
+
customNodes: customNodes.length > 0 ? customNodes : undefined,
|
|
795
|
+
mediatype,
|
|
796
|
+
decryptFail: envelope.decryptFail,
|
|
797
|
+
botParticipants: botSidecar ? [botSidecar] : undefined,
|
|
798
|
+
additionalAttributes: sendOptions.additionalAttributes
|
|
353
799
|
});
|
|
354
800
|
const replayPayload = {
|
|
355
801
|
mode: 'plaintext',
|
|
@@ -357,22 +803,21 @@ export class WaMessageDispatchCoordinator {
|
|
|
357
803
|
type,
|
|
358
804
|
plaintext
|
|
359
805
|
};
|
|
360
|
-
const result = await this.retryTracker.track({
|
|
361
|
-
messageIdHint:
|
|
806
|
+
const result = await this.deps.retryTracker.track({
|
|
807
|
+
messageIdHint: messageNode.attrs.id ?? sendOptions.id,
|
|
362
808
|
toJid: groupJid,
|
|
363
|
-
type,
|
|
364
809
|
replayPayload,
|
|
365
810
|
eligibleRequesterDeviceJids: undefined
|
|
366
|
-
}, async () => this.messageClient.publishNode(messageNode, sendOptions));
|
|
811
|
+
}, async () => this.deps.messageClient.publishNode(messageNode, sendOptions));
|
|
367
812
|
const distributedAddresses = new Array(distributionParticipants.length);
|
|
368
813
|
for (let index = 0; index < distributionParticipants.length; index += 1) {
|
|
369
814
|
distributedAddresses[index] = distributionParticipants[index].address;
|
|
370
815
|
}
|
|
371
816
|
try {
|
|
372
|
-
await this.senderKeyManager.markSenderKeyDistributed(groupJid, senderKeyId, distributedAddresses);
|
|
817
|
+
await this.deps.senderKeyManager.markSenderKeyDistributed(groupJid, senderKeyId, distributedAddresses);
|
|
373
818
|
}
|
|
374
819
|
catch (error) {
|
|
375
|
-
this.logger.warn('failed to mark sender key distribution targets', {
|
|
820
|
+
this.deps.logger.warn('failed to mark sender key distribution targets', {
|
|
376
821
|
groupJid,
|
|
377
822
|
participants: distributedAddresses.length,
|
|
378
823
|
message: toError(error).message
|
|
@@ -386,7 +831,7 @@ export class WaMessageDispatchCoordinator {
|
|
|
386
831
|
const hasAddressingError = ackError === 421;
|
|
387
832
|
if (!retryContext.retried &&
|
|
388
833
|
(hasPhashMismatch || hasAddressingMismatch || hasAddressingError)) {
|
|
389
|
-
this.logger.warn('group message publish acknowledged with mismatch metadata', {
|
|
834
|
+
this.deps.logger.warn('group message publish acknowledged with mismatch metadata', {
|
|
390
835
|
id: result.id,
|
|
391
836
|
groupJid,
|
|
392
837
|
localPhash,
|
|
@@ -395,30 +840,24 @@ export class WaMessageDispatchCoordinator {
|
|
|
395
840
|
serverAddressingMode,
|
|
396
841
|
ackError
|
|
397
842
|
});
|
|
398
|
-
return this.publishGroupSenderKeyMessage(groupJid,
|
|
399
|
-
...
|
|
400
|
-
id: result.id
|
|
843
|
+
return this.publishGroupSenderKeyMessage(groupJid, {
|
|
844
|
+
...envelope,
|
|
845
|
+
sendOptions: { ...sendOptions, id: result.id }
|
|
401
846
|
}, {
|
|
402
847
|
retried: true,
|
|
403
848
|
forceRefreshParticipants: true,
|
|
404
849
|
forceAddressingMode: serverAddressingMode
|
|
405
|
-
}
|
|
850
|
+
});
|
|
406
851
|
}
|
|
407
852
|
return result;
|
|
408
853
|
}
|
|
409
854
|
resolveGroupAddressingMode(participantUserJids, groupJid) {
|
|
410
855
|
for (let index = 0; index < participantUserJids.length; index += 1) {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
if (splitJid(participantJid).server === 'lid') {
|
|
414
|
-
return 'lid';
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
catch (error) {
|
|
418
|
-
this.logger.trace('ignoring malformed participant jid in addressing mode resolution', { participantJid, message: toError(error).message });
|
|
856
|
+
if (isLidJid(participantUserJids[index])) {
|
|
857
|
+
return 'lid';
|
|
419
858
|
}
|
|
420
859
|
}
|
|
421
|
-
this.logger.trace('group addressing mode resolved to pn (default)', {
|
|
860
|
+
this.deps.logger.trace('group addressing mode resolved to pn (default)', {
|
|
422
861
|
groupJid,
|
|
423
862
|
participants: participantUserJids.length
|
|
424
863
|
});
|
|
@@ -426,13 +865,13 @@ export class WaMessageDispatchCoordinator {
|
|
|
426
865
|
}
|
|
427
866
|
resolveSenderForAddressingMode(addressingMode, meJid) {
|
|
428
867
|
if (addressingMode === 'lid') {
|
|
429
|
-
const meLid = this.
|
|
868
|
+
const meLid = this.deps.getCurrentCredentials()?.meLid;
|
|
430
869
|
if (meLid && meLid.includes('@')) {
|
|
431
870
|
try {
|
|
432
871
|
return normalizeDeviceJid(meLid);
|
|
433
872
|
}
|
|
434
873
|
catch (error) {
|
|
435
|
-
this.logger.trace('ignoring malformed me lid jid', {
|
|
874
|
+
this.deps.logger.trace('ignoring malformed me lid jid', {
|
|
436
875
|
meLid,
|
|
437
876
|
message: toError(error).message
|
|
438
877
|
});
|
|
@@ -445,7 +884,7 @@ export class WaMessageDispatchCoordinator {
|
|
|
445
884
|
const distributionPayload = await writeRandomPadMax16(proto.Message.encode({
|
|
446
885
|
senderKeyDistributionMessage
|
|
447
886
|
}).finish());
|
|
448
|
-
const fanoutDeviceJids = await this.fanoutResolver.resolveGroupParticipantDeviceJids(participantUserJids);
|
|
887
|
+
const fanoutDeviceJids = await this.deps.fanoutResolver.resolveGroupParticipantDeviceJids(participantUserJids);
|
|
449
888
|
if (fanoutDeviceJids.length === 0) {
|
|
450
889
|
return {
|
|
451
890
|
fanoutDeviceJids,
|
|
@@ -460,7 +899,7 @@ export class WaMessageDispatchCoordinator {
|
|
|
460
899
|
fanoutAddresses[index] = address;
|
|
461
900
|
fanoutTargetsByAddressKey.set(signalAddressKey(address), { jid, address });
|
|
462
901
|
}
|
|
463
|
-
const pendingAddresses = await this.senderKeyManager.filterParticipantsNeedingDistribution(groupJid, senderKeyId, fanoutAddresses);
|
|
902
|
+
const pendingAddresses = await this.deps.senderKeyManager.filterParticipantsNeedingDistribution(groupJid, senderKeyId, fanoutAddresses);
|
|
464
903
|
if (pendingAddresses.length === 0) {
|
|
465
904
|
return {
|
|
466
905
|
fanoutDeviceJids,
|
|
@@ -493,7 +932,7 @@ export class WaMessageDispatchCoordinator {
|
|
|
493
932
|
let availableTargets = [];
|
|
494
933
|
let prefetchedAvailableTargets;
|
|
495
934
|
try {
|
|
496
|
-
const resolvedTargets = await this.sessionResolver.ensureSessionsBatch(pendingTargetJids);
|
|
935
|
+
const resolvedTargets = await this.deps.sessionResolver.ensureSessionsBatch(pendingTargetJids);
|
|
497
936
|
availableTargets = resolvedTargets;
|
|
498
937
|
prefetchedAvailableTargets = resolvedTargets;
|
|
499
938
|
}
|
|
@@ -502,7 +941,7 @@ export class WaMessageDispatchCoordinator {
|
|
|
502
941
|
if (normalized.message === 'identity mismatch') {
|
|
503
942
|
throw normalized;
|
|
504
943
|
}
|
|
505
|
-
this.logger.warn('group sender-key distribution session sync failed, continuing with available sessions', {
|
|
944
|
+
this.deps.logger.warn('group sender-key distribution session sync failed, continuing with available sessions', {
|
|
506
945
|
groupJid,
|
|
507
946
|
requested: pendingTargetJids.length,
|
|
508
947
|
message: normalized.message
|
|
@@ -511,7 +950,7 @@ export class WaMessageDispatchCoordinator {
|
|
|
511
950
|
for (let index = 0; index < pendingTargets.length; index += 1) {
|
|
512
951
|
pendingTargetAddresses[index] = pendingTargets[index].address;
|
|
513
952
|
}
|
|
514
|
-
const hasPendingSessions = await this.
|
|
953
|
+
const hasPendingSessions = await this.deps.sessionStore.hasSessions(pendingTargetAddresses);
|
|
515
954
|
const nextAvailableTargets = [];
|
|
516
955
|
for (let index = 0; index < pendingTargets.length; index += 1) {
|
|
517
956
|
if (hasPendingSessions[index]) {
|
|
@@ -534,7 +973,7 @@ export class WaMessageDispatchCoordinator {
|
|
|
534
973
|
plaintext: distributionPayload
|
|
535
974
|
};
|
|
536
975
|
}
|
|
537
|
-
const encryptedDistributionParticipants = await this.signalProtocol.encryptMessagesBatch(distributionEncryptRequests, prefetchedAvailableTargets);
|
|
976
|
+
const encryptedDistributionParticipants = await this.deps.signalProtocol.encryptMessagesBatch(distributionEncryptRequests, prefetchedAvailableTargets);
|
|
538
977
|
const distributionParticipants = new Array(availableTargets.length);
|
|
539
978
|
for (let index = 0; index < availableTargets.length; index += 1) {
|
|
540
979
|
const target = availableTargets[index];
|
|
@@ -550,12 +989,12 @@ export class WaMessageDispatchCoordinator {
|
|
|
550
989
|
distributionParticipants
|
|
551
990
|
};
|
|
552
991
|
}
|
|
553
|
-
async publishDirectSignalMessageWithFanout(recipientJid,
|
|
554
|
-
const sendOptions =
|
|
992
|
+
async publishDirectSignalMessageWithFanout(recipientJid, envelope) {
|
|
993
|
+
const { message, plaintext, type, edit, mediatype, sendOptions } = envelope;
|
|
555
994
|
const meJid = this.requireCurrentMeJid('sendMessage');
|
|
556
|
-
const meLid = this.
|
|
557
|
-
const selfDeviceJidForRecipient = this.fanoutResolver.resolveSelfDeviceJidForRecipient(recipientJid, meJid, meLid);
|
|
558
|
-
const deviceJids = await this.fanoutResolver.resolveDirectFanoutDeviceJids(recipientJid, selfDeviceJidForRecipient);
|
|
995
|
+
const meLid = this.deps.getCurrentCredentials()?.meLid;
|
|
996
|
+
const selfDeviceJidForRecipient = this.deps.fanoutResolver.resolveSelfDeviceJidForRecipient(recipientJid, meJid, meLid);
|
|
997
|
+
const deviceJids = await this.deps.fanoutResolver.resolveDirectFanoutDeviceJids(recipientJid, selfDeviceJidForRecipient);
|
|
559
998
|
const targets = new Array(deviceJids.length);
|
|
560
999
|
for (let index = 0; index < deviceJids.length; index += 1) {
|
|
561
1000
|
const jid = deviceJids[index];
|
|
@@ -568,7 +1007,7 @@ export class WaMessageDispatchCoordinator {
|
|
|
568
1007
|
}
|
|
569
1008
|
const recipientUserJid = toUserJid(recipientJid);
|
|
570
1009
|
const meUserJid = toUserJid(selfDeviceJidForRecipient);
|
|
571
|
-
this.logger.
|
|
1010
|
+
this.deps.logger.trace('wa client publish signal fanout', {
|
|
572
1011
|
to: recipientJid,
|
|
573
1012
|
devices: deviceJids.length,
|
|
574
1013
|
type
|
|
@@ -582,20 +1021,42 @@ export class WaMessageDispatchCoordinator {
|
|
|
582
1021
|
}
|
|
583
1022
|
}
|
|
584
1023
|
}
|
|
585
|
-
const resolvedFanoutTargets = await this.sessionResolver.ensureSessionsBatch(deviceJids, expectedIdentityByJid);
|
|
1024
|
+
const resolvedFanoutTargets = await this.deps.sessionResolver.ensureSessionsBatch(deviceJids, expectedIdentityByJid);
|
|
586
1025
|
const resolvedFanoutTargetsByJid = new Map();
|
|
587
1026
|
for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
|
|
588
1027
|
const target = resolvedFanoutTargets[index];
|
|
589
1028
|
resolvedFanoutTargetsByJid.set(normalizeDeviceJid(target.jid), target);
|
|
590
1029
|
}
|
|
1030
|
+
const liveTargets = [];
|
|
1031
|
+
const droppedSecondaryDevices = [];
|
|
591
1032
|
for (let index = 0; index < targets.length; index += 1) {
|
|
592
|
-
|
|
593
|
-
|
|
1033
|
+
const target = targets[index];
|
|
1034
|
+
if (resolvedFanoutTargetsByJid.has(target.normalizedJid)) {
|
|
1035
|
+
liveTargets.push(target);
|
|
1036
|
+
continue;
|
|
594
1037
|
}
|
|
1038
|
+
const isPrimaryRecipient = target.userJid === recipientUserJid && target.normalizedJid === target.userJid;
|
|
1039
|
+
if (isPrimaryRecipient) {
|
|
1040
|
+
this.deps.logger.error('direct fanout dropping primary recipient device without signal session', { to: recipientJid, device: target.jid });
|
|
1041
|
+
}
|
|
1042
|
+
else {
|
|
1043
|
+
droppedSecondaryDevices.push(target.jid);
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
if (droppedSecondaryDevices.length > 0) {
|
|
1047
|
+
this.deps.logger.warn('direct fanout dropping secondary devices without signal session', {
|
|
1048
|
+
to: recipientJid,
|
|
1049
|
+
droppedCount: droppedSecondaryDevices.length,
|
|
1050
|
+
totalExpected: targets.length,
|
|
1051
|
+
sample: droppedSecondaryDevices.slice(0, 3)
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
1054
|
+
if (liveTargets.length === 0) {
|
|
1055
|
+
throw new Error('direct fanout missing signal sessions for all targets');
|
|
595
1056
|
}
|
|
596
1057
|
let hasSelfDeviceFanout = false;
|
|
597
|
-
for (let index = 0; index <
|
|
598
|
-
if (
|
|
1058
|
+
for (let index = 0; index < liveTargets.length; index += 1) {
|
|
1059
|
+
if (liveTargets[index].userJid === meUserJid) {
|
|
599
1060
|
hasSelfDeviceFanout = true;
|
|
600
1061
|
break;
|
|
601
1062
|
}
|
|
@@ -603,13 +1064,10 @@ export class WaMessageDispatchCoordinator {
|
|
|
603
1064
|
const selfDevicePlaintext = hasSelfDeviceFanout
|
|
604
1065
|
? await writeRandomPadMax16(proto.Message.encode(wrapDeviceSentMessage(message, recipientUserJid)).finish())
|
|
605
1066
|
: null;
|
|
606
|
-
const participantRequests = new Array(
|
|
607
|
-
for (let index = 0; index <
|
|
608
|
-
const target =
|
|
1067
|
+
const participantRequests = new Array(liveTargets.length);
|
|
1068
|
+
for (let index = 0; index < liveTargets.length; index += 1) {
|
|
1069
|
+
const target = liveTargets[index];
|
|
609
1070
|
const resolvedTarget = resolvedFanoutTargetsByJid.get(target.normalizedJid);
|
|
610
|
-
if (!resolvedTarget) {
|
|
611
|
-
throw new Error('direct fanout missing signal session for target');
|
|
612
|
-
}
|
|
613
1071
|
participantRequests[index] = {
|
|
614
1072
|
target,
|
|
615
1073
|
address: resolvedTarget.address,
|
|
@@ -634,15 +1092,20 @@ export class WaMessageDispatchCoordinator {
|
|
|
634
1092
|
session: request.session
|
|
635
1093
|
};
|
|
636
1094
|
}
|
|
637
|
-
const encryptedParticipants = await this.signalProtocol.encryptMessagesBatch(encryptRequests, prefetchedSessions);
|
|
638
|
-
const
|
|
1095
|
+
const encryptedParticipants = await this.deps.signalProtocol.encryptMessagesBatch(encryptRequests, prefetchedSessions);
|
|
1096
|
+
const isBotRecipient = isBotJid(recipientJid);
|
|
1097
|
+
const participants = [];
|
|
639
1098
|
for (let index = 0; index < participantRequests.length; index += 1) {
|
|
640
1099
|
const request = participantRequests[index];
|
|
641
|
-
|
|
1100
|
+
const entry = {
|
|
642
1101
|
jid: request.target.jid,
|
|
643
1102
|
encType: encryptedParticipants[index].type,
|
|
644
1103
|
ciphertext: encryptedParticipants[index].ciphertext
|
|
645
1104
|
};
|
|
1105
|
+
// wa-web direct 1:1 to bot puts the bot device alongside self devices
|
|
1106
|
+
// inside `<participants>`; the `<bot>` envelope is only used for group
|
|
1107
|
+
// mentions (the sidecar copy) or for bot feedback / revoke flows.
|
|
1108
|
+
participants.push(entry);
|
|
646
1109
|
}
|
|
647
1110
|
let shouldAttachDeviceIdentity = false;
|
|
648
1111
|
for (let index = 0; index < participants.length; index += 1) {
|
|
@@ -662,16 +1125,23 @@ export class WaMessageDispatchCoordinator {
|
|
|
662
1125
|
context: 'direct_fanout'
|
|
663
1126
|
});
|
|
664
1127
|
let privacyTokenNode;
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
1128
|
+
if (!isBotRecipient) {
|
|
1129
|
+
try {
|
|
1130
|
+
privacyTokenNode =
|
|
1131
|
+
(await this.privacyTokenDedup.run(`pt:${recipientUserJid}`, () => this.deps.resolvePrivacyTokenNode(recipientUserJid))) ?? undefined;
|
|
1132
|
+
}
|
|
1133
|
+
catch (error) {
|
|
1134
|
+
this.deps.logger.warn('privacy token resolution failed', {
|
|
1135
|
+
to: recipientUserJid,
|
|
1136
|
+
message: toError(error).message
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
674
1139
|
}
|
|
1140
|
+
const customNodes = envelope.customNodes ? [...envelope.customNodes] : [];
|
|
1141
|
+
if (reportingArtifacts?.node)
|
|
1142
|
+
customNodes.push(reportingArtifacts.node);
|
|
1143
|
+
if (privacyTokenNode)
|
|
1144
|
+
customNodes.push(privacyTokenNode);
|
|
675
1145
|
const messageNode = buildDirectMessageFanoutNode({
|
|
676
1146
|
to: recipientJid,
|
|
677
1147
|
type,
|
|
@@ -679,10 +1149,10 @@ export class WaMessageDispatchCoordinator {
|
|
|
679
1149
|
edit,
|
|
680
1150
|
participants,
|
|
681
1151
|
deviceIdentity,
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
1152
|
+
customNodes: customNodes.length > 0 ? customNodes : undefined,
|
|
1153
|
+
mediatype,
|
|
1154
|
+
decryptFail: envelope.decryptFail,
|
|
1155
|
+
additionalAttributes: sendOptions.additionalAttributes
|
|
686
1156
|
});
|
|
687
1157
|
const replayPayload = {
|
|
688
1158
|
mode: 'plaintext',
|
|
@@ -690,14 +1160,13 @@ export class WaMessageDispatchCoordinator {
|
|
|
690
1160
|
type,
|
|
691
1161
|
plaintext
|
|
692
1162
|
};
|
|
693
|
-
const result = await this.retryTracker.track({
|
|
694
|
-
messageIdHint:
|
|
1163
|
+
const result = await this.deps.retryTracker.track({
|
|
1164
|
+
messageIdHint: messageNode.attrs.id ?? sendOptions.id,
|
|
695
1165
|
toJid: recipientJid,
|
|
696
|
-
type,
|
|
697
1166
|
replayPayload,
|
|
698
1167
|
eligibleRequesterDeviceJids: deviceJids
|
|
699
|
-
}, async () => this.messageClient.publishNode(messageNode, sendOptions));
|
|
700
|
-
this.onDirectMessageSent(recipientUserJid);
|
|
1168
|
+
}, async () => this.deps.messageClient.publishNode(messageNode, sendOptions));
|
|
1169
|
+
this.deps.onDirectMessageSent(recipientUserJid);
|
|
701
1170
|
return result;
|
|
702
1171
|
}
|
|
703
1172
|
async withResolvedMessageId(options) {
|
|
@@ -719,21 +1188,35 @@ export class WaMessageDispatchCoordinator {
|
|
|
719
1188
|
async generateOutgoingMessageId() {
|
|
720
1189
|
try {
|
|
721
1190
|
const meUserJid = toUserJid(this.requireCurrentMeJid('sendMessage'));
|
|
722
|
-
const timestampSeconds = Math.floor(Date.now() / 1000);
|
|
723
1191
|
const timestampBytes = new Uint8Array(8);
|
|
724
|
-
new DataView(timestampBytes.buffer, timestampBytes.byteOffset, timestampBytes.byteLength)
|
|
725
|
-
|
|
1192
|
+
const dv = new DataView(timestampBytes.buffer, timestampBytes.byteOffset, timestampBytes.byteLength);
|
|
1193
|
+
if (this.mobileMessageIdFormat) {
|
|
1194
|
+
dv.setBigUint64(0, BigInt(Date.now()), false);
|
|
1195
|
+
const digest = md5Bytes([
|
|
1196
|
+
timestampBytes,
|
|
1197
|
+
TEXT_ENCODER.encode(meUserJid),
|
|
1198
|
+
await randomBytesAsync(16)
|
|
1199
|
+
]);
|
|
1200
|
+
digest[0] = 0xac;
|
|
1201
|
+
return bytesToHex(digest).toUpperCase();
|
|
1202
|
+
}
|
|
1203
|
+
dv.setBigUint64(0, BigInt(Math.floor(Date.now() / 1000)), false);
|
|
1204
|
+
const digest = sha256([
|
|
726
1205
|
timestampBytes,
|
|
727
1206
|
TEXT_ENCODER.encode(meUserJid),
|
|
728
1207
|
await randomBytesAsync(8)
|
|
729
1208
|
]);
|
|
730
|
-
const digest = await sha256(entropy);
|
|
731
1209
|
return `3EB0${bytesToHex(digest.subarray(0, 9)).toUpperCase()}`;
|
|
732
1210
|
}
|
|
733
1211
|
catch (error) {
|
|
734
|
-
this.logger.warn('failed to generate
|
|
1212
|
+
this.deps.logger.warn('failed to generate message id, falling back to random', {
|
|
735
1213
|
message: toError(error).message
|
|
736
1214
|
});
|
|
1215
|
+
if (this.mobileMessageIdFormat) {
|
|
1216
|
+
const bytes = await randomBytesAsync(16);
|
|
1217
|
+
bytes[0] = 0xac;
|
|
1218
|
+
return bytesToHex(bytes).toUpperCase();
|
|
1219
|
+
}
|
|
737
1220
|
return `3EB0${bytesToHex(await randomBytesAsync(8)).toUpperCase()}`;
|
|
738
1221
|
}
|
|
739
1222
|
}
|
|
@@ -750,7 +1233,7 @@ export class WaMessageDispatchCoordinator {
|
|
|
750
1233
|
});
|
|
751
1234
|
}
|
|
752
1235
|
catch (error) {
|
|
753
|
-
this.logger.warn('failed to generate reporting token', {
|
|
1236
|
+
this.deps.logger.warn('failed to generate reporting token', {
|
|
754
1237
|
context: input.context,
|
|
755
1238
|
id: input.stanzaId,
|
|
756
1239
|
remoteJid: input.remoteJid,
|
|
@@ -760,24 +1243,24 @@ export class WaMessageDispatchCoordinator {
|
|
|
760
1243
|
}
|
|
761
1244
|
}
|
|
762
1245
|
getEncodedSignedDeviceIdentity() {
|
|
763
|
-
const signedIdentity = this.
|
|
1246
|
+
const signedIdentity = this.deps.getCurrentCredentials()?.signedIdentity;
|
|
764
1247
|
if (!signedIdentity) {
|
|
765
|
-
|
|
1248
|
+
return undefined;
|
|
766
1249
|
}
|
|
767
1250
|
return proto.ADVSignedDeviceIdentity.encode(signedIdentity).finish();
|
|
768
1251
|
}
|
|
769
1252
|
resolveUserIcdc(userJid, localIdentity) {
|
|
770
1253
|
return this.icdcDedup.run(`icdc:${userJid}:${localIdentity ? '1' : '0'}`, async () => {
|
|
771
1254
|
try {
|
|
772
|
-
const snapshots = await this.deviceListStore.getUserDevicesBatch([userJid]);
|
|
1255
|
+
const snapshots = await this.deps.deviceListStore.getUserDevicesBatch([userJid]);
|
|
773
1256
|
const snapshot = snapshots[0];
|
|
774
1257
|
if (!snapshot || snapshot.deviceJids.length === 0) {
|
|
775
1258
|
return null;
|
|
776
1259
|
}
|
|
777
|
-
return resolveIcdcMeta(snapshot.deviceJids, this.
|
|
1260
|
+
return resolveIcdcMeta(snapshot.deviceJids, this.deps.identityStore, snapshot.updatedAtMs, localIdentity, this.deps.getIcdcHashLength?.());
|
|
778
1261
|
}
|
|
779
1262
|
catch (error) {
|
|
780
|
-
this.logger.trace('icdc resolution failed', {
|
|
1263
|
+
this.deps.logger.trace('icdc resolution failed', {
|
|
781
1264
|
userJid,
|
|
782
1265
|
message: toError(error).message
|
|
783
1266
|
});
|
|
@@ -786,10 +1269,35 @@ export class WaMessageDispatchCoordinator {
|
|
|
786
1269
|
});
|
|
787
1270
|
}
|
|
788
1271
|
requireCurrentMeJid(context) {
|
|
789
|
-
const meJid = this.
|
|
1272
|
+
const meJid = this.deps.getCurrentCredentials()?.meJid;
|
|
790
1273
|
if (meJid) {
|
|
791
1274
|
return meJid;
|
|
792
1275
|
}
|
|
793
1276
|
throw new Error(`${context} requires registered meJid`);
|
|
794
1277
|
}
|
|
795
1278
|
}
|
|
1279
|
+
function pickContentContextInfo(content) {
|
|
1280
|
+
if (typeof content !== 'object' || content === null)
|
|
1281
|
+
return undefined;
|
|
1282
|
+
if (isSendTextMessage(content) || isSendMediaMessage(content)) {
|
|
1283
|
+
return content.contextInfo;
|
|
1284
|
+
}
|
|
1285
|
+
return undefined;
|
|
1286
|
+
}
|
|
1287
|
+
function assertNewsletterContextInfoCompatible(ctx) {
|
|
1288
|
+
if (!ctx)
|
|
1289
|
+
return;
|
|
1290
|
+
const unsupported = [];
|
|
1291
|
+
if (ctx.quotedMessageId !== undefined)
|
|
1292
|
+
unsupported.push('quote');
|
|
1293
|
+
if (ctx.mentionedJids?.length)
|
|
1294
|
+
unsupported.push('mentions');
|
|
1295
|
+
if (ctx.isSpoiler === true)
|
|
1296
|
+
unsupported.push('isSpoiler');
|
|
1297
|
+
if (ctx.groupSubject !== undefined || ctx.parentGroupJid !== undefined) {
|
|
1298
|
+
unsupported.push('group invite reply (groupSubject/parentGroupJid)');
|
|
1299
|
+
}
|
|
1300
|
+
if (unsupported.length > 0) {
|
|
1301
|
+
throw new Error(`newsletter sends do not support: ${unsupported.join(', ')}`);
|
|
1302
|
+
}
|
|
1303
|
+
}
|