zapo-js 0.1.2 → 0.2.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/README.md +12 -4
- package/dist/appstate/WaAppStateCrypto.js +1 -1
- package/dist/appstate/WaAppStateSyncClient.js +138 -93
- package/dist/appstate/{store/sqlite.js → encoding.js} +13 -8
- package/dist/appstate/index.js +8 -6
- package/dist/appstate/utils.js +0 -5
- package/dist/auth/WaAuthClient.js +36 -47
- package/dist/auth/flow/WaAuthCredentialsFlow.js +7 -7
- package/dist/auth/index.js +1 -6
- package/dist/auth/pairing/WaPairingCodeCrypto.js +6 -4
- package/dist/auth/pairing/WaPairingFlow.js +13 -3
- package/dist/client/WaClient.js +225 -101
- package/dist/client/WaClientFactory.js +294 -44
- package/dist/client/connection/WaConnectionManager.js +19 -10
- package/dist/client/coordinators/WaBusinessCoordinator.js +241 -0
- package/dist/client/coordinators/WaGroupCoordinator.js +11 -7
- package/dist/client/coordinators/WaIncomingNodeCoordinator.js +1 -0
- package/dist/client/coordinators/WaMessageDispatchCoordinator.js +292 -99
- package/dist/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
- package/dist/client/coordinators/WaPrivacyCoordinator.js +134 -0
- package/dist/client/coordinators/WaProfileCoordinator.js +212 -0
- package/dist/client/coordinators/WaRetryCoordinator.js +179 -27
- package/dist/client/coordinators/WaStreamControlCoordinator.js +18 -11
- package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +166 -0
- package/dist/client/dirty.js +40 -20
- package/dist/client/events/devices.js +72 -0
- package/dist/client/events/group.js +3 -11
- package/dist/client/events/identity.js +22 -0
- package/dist/client/events/privacy-token.js +39 -0
- package/dist/client/history-sync.js +50 -9
- package/dist/client/incoming.js +37 -7
- package/dist/client/mailbox.js +24 -23
- package/dist/client/messages.js +107 -31
- package/dist/client/messaging/fanout.js +21 -11
- package/dist/client/messaging/participants.js +6 -4
- package/dist/client/persistence/WriteBehindPersistence.js +129 -0
- package/dist/client/tokens/cs-token.js +50 -0
- package/dist/client/tokens/tc-token.js +25 -0
- package/dist/crypto/core/index.js +2 -2
- package/dist/crypto/core/keys.js +4 -4
- package/dist/crypto/core/nonce.js +2 -0
- package/dist/crypto/core/primitives.js +0 -8
- package/dist/crypto/core/random.js +22 -0
- package/dist/crypto/curves/X25519.js +25 -6
- package/dist/crypto/index.js +3 -0
- package/dist/crypto/math/constants.js +13 -36
- package/dist/crypto/math/edwards.js +171 -44
- package/dist/crypto/math/fe.js +706 -0
- package/dist/crypto/math/mod.js +10 -3
- package/dist/esm/appstate/WaAppStateCrypto.js +1 -1
- package/dist/esm/appstate/WaAppStateSyncClient.js +138 -93
- package/dist/esm/appstate/{store/sqlite.js → encoding.js} +13 -8
- package/dist/esm/appstate/index.js +2 -2
- package/dist/esm/appstate/utils.js +2 -5
- package/dist/esm/auth/WaAuthClient.js +36 -47
- package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +7 -7
- package/dist/esm/auth/index.js +0 -2
- package/dist/esm/auth/pairing/WaPairingCodeCrypto.js +6 -4
- package/dist/esm/auth/pairing/WaPairingFlow.js +14 -4
- package/dist/esm/client/WaClient.js +225 -101
- package/dist/esm/client/WaClientFactory.js +295 -45
- package/dist/esm/client/connection/WaConnectionManager.js +19 -10
- package/dist/esm/client/coordinators/WaBusinessCoordinator.js +238 -0
- package/dist/esm/client/coordinators/WaGroupCoordinator.js +11 -7
- package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +1 -0
- package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +295 -102
- package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
- package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +131 -0
- package/dist/esm/client/coordinators/WaProfileCoordinator.js +209 -0
- package/dist/esm/client/coordinators/WaRetryCoordinator.js +181 -29
- package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +19 -12
- package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +162 -0
- package/dist/esm/client/dirty.js +40 -20
- package/dist/esm/client/events/devices.js +68 -0
- package/dist/esm/client/events/group.js +3 -11
- package/dist/esm/client/events/identity.js +19 -0
- package/dist/esm/client/events/privacy-token.js +36 -0
- package/dist/esm/client/history-sync.js +50 -9
- package/dist/esm/client/incoming.js +38 -8
- package/dist/esm/client/mailbox.js +24 -23
- package/dist/esm/client/messages.js +108 -32
- package/dist/esm/client/messaging/fanout.js +22 -12
- package/dist/esm/client/messaging/participants.js +6 -4
- package/dist/esm/client/persistence/WriteBehindPersistence.js +125 -0
- package/dist/esm/client/tokens/cs-token.js +46 -0
- package/dist/esm/client/tokens/tc-token.js +18 -0
- package/dist/esm/crypto/core/index.js +2 -2
- package/dist/esm/crypto/core/keys.js +1 -1
- package/dist/esm/crypto/core/nonce.js +2 -0
- package/dist/esm/crypto/core/primitives.js +0 -7
- package/dist/esm/crypto/core/random.js +22 -1
- package/dist/esm/crypto/curves/X25519.js +25 -6
- package/dist/esm/crypto/index.js +1 -0
- package/dist/esm/crypto/math/constants.js +12 -35
- package/dist/esm/crypto/math/edwards.js +174 -47
- package/dist/esm/crypto/math/fe.js +691 -0
- package/dist/esm/crypto/math/mod.js +10 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/infra/perf/BackgroundQueue.js +478 -0
- package/dist/esm/infra/perf/BoundedTaskQueue.js +3 -1
- package/dist/esm/infra/perf/PromiseDedup.js +20 -0
- package/dist/esm/infra/perf/SharedExclusiveGate.js +109 -0
- package/dist/esm/infra/perf/StoreLock.js +77 -0
- package/dist/esm/media/WaMediaCrypto.js +95 -13
- package/dist/esm/media/WaMediaTransferClient.js +39 -47
- package/dist/esm/media/constants.js +2 -1
- package/dist/esm/message/WaMessageClient.js +26 -19
- package/dist/esm/message/content.js +195 -9
- package/dist/esm/message/icdc.js +76 -0
- package/dist/esm/message/incoming.js +24 -12
- package/dist/esm/message/phash.js +3 -1
- package/dist/esm/message/reporting-token.js +14 -27
- package/dist/esm/protocol/appstate.js +9 -40
- package/dist/esm/protocol/browser.js +10 -18
- package/dist/esm/protocol/constants.js +5 -3
- package/dist/esm/protocol/defaults.js +6 -0
- package/dist/esm/protocol/index.js +1 -2
- package/dist/esm/protocol/jid.js +105 -36
- package/dist/esm/protocol/message.js +61 -1
- package/dist/esm/protocol/nodes.js +2 -0
- package/dist/esm/protocol/notification.js +3 -1
- package/dist/esm/protocol/privacy-token.js +17 -0
- package/dist/esm/protocol/privacy.js +55 -0
- package/dist/esm/protocol/stream.js +26 -1
- package/dist/esm/retry/codec.js +216 -0
- package/dist/esm/retry/constants.js +1 -1
- package/dist/esm/retry/index.js +2 -2
- package/dist/esm/retry/parse.js +50 -30
- package/dist/esm/retry/replay.js +11 -7
- package/dist/esm/retry/tracker.js +50 -12
- package/dist/esm/signal/api/SignalDeviceSyncApi.js +49 -32
- package/dist/esm/signal/api/SignalDigestSyncApi.js +13 -9
- package/dist/esm/signal/api/SignalIdentitySyncApi.js +26 -11
- package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +18 -7
- package/dist/esm/signal/api/SignalRotateKeyApi.js +4 -2
- package/dist/esm/signal/api/SignalSessionSyncApi.js +16 -7
- package/dist/esm/signal/api/result-map.js +10 -0
- package/dist/esm/signal/constants.js +0 -4
- package/dist/esm/signal/crypto/WaAdvSignature.js +12 -6
- package/dist/esm/signal/{store/sqlite.js → encoding.js} +78 -24
- package/dist/esm/signal/group/SenderKeyCodec.js +3 -2
- package/dist/esm/signal/group/SenderKeyManager.js +125 -106
- package/dist/esm/signal/index.js +1 -0
- package/dist/esm/signal/registration/keygen.js +6 -2
- package/dist/esm/signal/registration/utils.js +1 -0
- package/dist/esm/signal/session/SignalProtocol.js +150 -74
- package/dist/esm/signal/session/resolver.js +137 -102
- package/dist/esm/store/contracts/privacy-token.store.js +1 -0
- package/dist/esm/store/createStore.js +101 -187
- package/dist/esm/store/index.js +1 -10
- package/dist/esm/store/locks/appstate.lock.js +26 -0
- package/dist/esm/store/locks/auth.lock.js +15 -0
- package/dist/esm/store/locks/contact.lock.js +20 -0
- package/dist/esm/store/locks/device-list.lock.js +20 -0
- package/dist/esm/store/locks/message.lock.js +21 -0
- package/dist/esm/store/locks/participants.lock.js +20 -0
- package/dist/esm/store/locks/privacy-token.lock.js +18 -0
- package/dist/esm/store/locks/retry.lock.js +29 -0
- package/dist/esm/store/locks/sender-key.lock.js +52 -0
- package/dist/esm/store/locks/signal.lock.js +63 -0
- package/dist/esm/store/locks/thread.lock.js +21 -0
- package/dist/esm/store/noop.store.js +1 -1
- package/dist/esm/store/providers/memory/appstate.store.js +22 -24
- package/dist/esm/store/providers/memory/device-list.store.js +10 -5
- package/dist/esm/store/providers/memory/privacy-token.store.js +43 -0
- package/dist/esm/store/providers/memory/retry.store.js +77 -2
- package/dist/esm/store/providers/memory/sender-key.store.js +6 -1
- package/dist/esm/store/providers/memory/signal.store.js +36 -19
- package/dist/esm/transport/WaComms.js +3 -1
- package/dist/esm/transport/WaWebSocket.js +0 -6
- package/dist/esm/transport/binary/constants.js +0 -30
- package/dist/esm/transport/binary/decoder.js +4 -4
- package/dist/esm/transport/binary/encoder.js +8 -15
- package/dist/esm/transport/binary/index.js +0 -1
- package/dist/esm/transport/node/WaNodeOrchestrator.js +25 -19
- package/dist/esm/transport/node/builders/business.js +129 -0
- package/dist/esm/transport/node/builders/global.js +370 -0
- package/dist/esm/transport/node/builders/index.js +5 -2
- package/dist/esm/transport/node/builders/message.js +63 -239
- package/dist/esm/transport/node/builders/pairing.js +0 -24
- package/dist/esm/transport/node/builders/privacy-token.js +41 -0
- package/dist/esm/transport/node/builders/privacy.js +48 -0
- package/dist/esm/transport/node/builders/profile.js +70 -0
- package/dist/esm/transport/node/builders/retry.js +10 -22
- package/dist/esm/transport/node/builders/usync.js +6 -2
- package/dist/esm/transport/node/helpers.js +19 -1
- package/dist/esm/transport/node/usync.js +3 -33
- package/dist/esm/transport/node/xml.js +35 -14
- package/dist/esm/transport/noise/WaClientPayload.js +10 -10
- package/dist/esm/transport/noise/WaNoiseCert.js +3 -3
- package/dist/esm/transport/noise/WaNoiseSession.js +64 -23
- package/dist/esm/transport/noise/WaNoiseSocket.js +8 -4
- package/dist/esm/transport/stream/parse.js +8 -4
- package/dist/esm/util/bytes.js +22 -18
- package/dist/esm/util/index.js +5 -0
- package/dist/esm/util/primitives.js +3 -2
- package/dist/index.js +7 -1
- package/dist/infra/perf/BackgroundQueue.js +482 -0
- package/dist/infra/perf/BoundedTaskQueue.js +3 -1
- package/dist/infra/perf/PromiseDedup.js +24 -0
- package/dist/infra/perf/SharedExclusiveGate.js +113 -0
- package/dist/infra/perf/StoreLock.js +81 -0
- package/dist/media/WaMediaCrypto.js +94 -12
- package/dist/media/WaMediaTransferClient.js +39 -47
- package/dist/media/constants.js +2 -1
- package/dist/message/WaMessageClient.js +26 -19
- package/dist/message/content.js +198 -9
- package/dist/message/icdc.js +81 -0
- package/dist/message/incoming.js +24 -12
- package/dist/message/phash.js +3 -1
- package/dist/message/reporting-token.js +14 -28
- package/dist/protocol/appstate.js +10 -41
- package/dist/protocol/browser.js +10 -18
- package/dist/protocol/constants.js +21 -2
- package/dist/protocol/defaults.js +6 -0
- package/dist/protocol/index.js +8 -5
- package/dist/protocol/jid.js +111 -36
- package/dist/protocol/message.js +62 -2
- package/dist/protocol/nodes.js +2 -0
- package/dist/protocol/notification.js +3 -1
- package/dist/protocol/privacy-token.js +20 -0
- package/dist/protocol/privacy.js +58 -0
- package/dist/protocol/stream.js +27 -2
- package/dist/retry/codec.js +220 -0
- package/dist/retry/constants.js +1 -1
- package/dist/retry/index.js +5 -5
- package/dist/retry/parse.js +51 -30
- package/dist/retry/replay.js +10 -6
- package/dist/retry/tracker.js +50 -12
- package/dist/signal/api/SignalDeviceSyncApi.js +48 -31
- package/dist/signal/api/SignalDigestSyncApi.js +13 -9
- package/dist/signal/api/SignalIdentitySyncApi.js +25 -10
- package/dist/signal/api/SignalMissingPreKeysSyncApi.js +17 -6
- package/dist/signal/api/SignalRotateKeyApi.js +4 -2
- package/dist/signal/api/SignalSessionSyncApi.js +16 -7
- package/dist/signal/api/result-map.js +13 -0
- package/dist/signal/constants.js +1 -5
- package/dist/signal/crypto/WaAdvSignature.js +11 -5
- package/dist/signal/{store/sqlite.js → encoding.js} +79 -25
- package/dist/signal/group/SenderKeyCodec.js +4 -3
- package/dist/signal/group/SenderKeyManager.js +125 -106
- package/dist/signal/index.js +13 -1
- package/dist/signal/registration/keygen.js +6 -2
- package/dist/signal/registration/utils.js +1 -0
- package/dist/signal/session/SignalProtocol.js +150 -74
- package/dist/signal/session/resolver.js +135 -100
- package/dist/store/contracts/privacy-token.store.js +2 -0
- package/dist/store/createStore.js +101 -187
- package/dist/store/index.js +15 -33
- package/dist/store/locks/appstate.lock.js +29 -0
- package/dist/store/locks/auth.lock.js +18 -0
- package/dist/store/locks/contact.lock.js +23 -0
- package/dist/store/locks/device-list.lock.js +23 -0
- package/dist/store/locks/message.lock.js +24 -0
- package/dist/store/locks/participants.lock.js +23 -0
- package/dist/store/locks/privacy-token.lock.js +21 -0
- package/dist/store/locks/retry.lock.js +32 -0
- package/dist/store/locks/sender-key.lock.js +55 -0
- package/dist/store/locks/signal.lock.js +66 -0
- package/dist/store/locks/thread.lock.js +24 -0
- package/dist/store/noop.store.js +1 -1
- package/dist/store/providers/memory/appstate.store.js +22 -24
- package/dist/store/providers/memory/device-list.store.js +10 -5
- package/dist/store/providers/memory/privacy-token.store.js +47 -0
- package/dist/store/providers/memory/retry.store.js +77 -2
- package/dist/store/providers/memory/sender-key.store.js +6 -1
- package/dist/store/providers/memory/signal.store.js +36 -19
- package/dist/transport/WaComms.js +3 -1
- package/dist/transport/WaWebSocket.js +0 -6
- package/dist/transport/binary/constants.js +1 -31
- package/dist/transport/binary/decoder.js +4 -4
- package/dist/transport/binary/encoder.js +8 -15
- package/dist/transport/binary/index.js +0 -4
- package/dist/transport/node/WaNodeOrchestrator.js +24 -18
- package/dist/transport/node/builders/business.js +137 -0
- package/dist/transport/node/builders/global.js +375 -0
- package/dist/transport/node/builders/index.js +18 -9
- package/dist/transport/node/builders/message.js +64 -245
- package/dist/transport/node/builders/pairing.js +0 -26
- package/dist/transport/node/builders/privacy-token.js +46 -0
- package/dist/transport/node/builders/privacy.js +55 -0
- package/dist/transport/node/builders/profile.js +78 -0
- package/dist/transport/node/builders/retry.js +9 -21
- package/dist/transport/node/builders/usync.js +6 -2
- package/dist/transport/node/helpers.js +20 -1
- package/dist/transport/node/usync.js +2 -32
- package/dist/transport/node/xml.js +35 -14
- package/dist/transport/noise/WaClientPayload.js +13 -13
- package/dist/transport/noise/WaNoiseCert.js +2 -2
- package/dist/transport/noise/WaNoiseSession.js +64 -23
- package/dist/transport/noise/WaNoiseSocket.js +8 -4
- package/dist/transport/stream/parse.js +7 -3
- package/dist/types/appstate/encoding.d.ts +7 -0
- package/dist/types/appstate/index.d.ts +3 -3
- package/dist/types/appstate/utils.d.ts +0 -2
- package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +1 -1
- package/dist/types/auth/index.d.ts +0 -2
- package/dist/types/auth/types.d.ts +1 -0
- package/dist/types/client/WaClient.d.ts +27 -12
- package/dist/types/client/WaClientFactory.d.ts +12 -4
- package/dist/types/client/connection/WaConnectionManager.d.ts +2 -0
- package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +57 -0
- package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +3 -1
- package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +14 -0
- package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +4 -0
- package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +26 -0
- package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +36 -0
- package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +6 -0
- package/dist/types/client/coordinators/WaStreamControlCoordinator.d.ts +3 -2
- package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +45 -0
- package/dist/types/client/events/devices.d.ts +20 -0
- package/dist/types/client/events/identity.d.ts +9 -0
- package/dist/types/client/events/privacy-token.d.ts +7 -0
- package/dist/types/client/history-sync.d.ts +9 -6
- package/dist/types/client/incoming.d.ts +3 -1
- package/dist/types/client/index.d.ts +1 -1
- package/dist/types/client/mailbox.d.ts +3 -5
- package/dist/types/client/messages.d.ts +1 -2
- package/dist/types/client/persistence/WriteBehindPersistence.d.ts +34 -0
- package/dist/types/client/tokens/cs-token.d.ts +10 -0
- package/dist/types/client/tokens/tc-token.d.ts +5 -0
- package/dist/types/client/types.d.ts +51 -3
- package/dist/types/crypto/core/index.d.ts +2 -2
- package/dist/types/crypto/core/nonce.d.ts +2 -0
- package/dist/types/crypto/core/primitives.d.ts +0 -1
- package/dist/types/crypto/core/random.d.ts +1 -0
- package/dist/types/crypto/index.d.ts +1 -0
- package/dist/types/crypto/math/constants.d.ts +4 -2
- package/dist/types/crypto/math/fe.d.ts +30 -0
- package/dist/types/crypto/math/mod.d.ts +0 -2
- package/dist/types/crypto/math/types.d.ts +11 -4
- package/dist/types/index.d.ts +5 -3
- package/dist/types/infra/perf/BackgroundQueue.d.ts +58 -0
- package/dist/types/infra/perf/PromiseDedup.d.ts +4 -0
- package/dist/types/infra/perf/SharedExclusiveGate.d.ts +17 -0
- package/dist/types/infra/perf/StoreLock.d.ts +10 -0
- package/dist/types/media/WaMediaCrypto.d.ts +3 -2
- package/dist/types/media/WaMediaTransferClient.d.ts +3 -12
- package/dist/types/media/constants.d.ts +1 -1
- package/dist/types/media/index.d.ts +1 -1
- package/dist/types/media/types.d.ts +10 -2
- package/dist/types/message/content.d.ts +8 -0
- package/dist/types/message/icdc.d.ts +13 -0
- package/dist/types/message/reporting-token.d.ts +0 -1
- package/dist/types/message/types.d.ts +45 -6
- package/dist/types/protocol/appstate.d.ts +0 -11
- package/dist/types/protocol/constants.d.ts +7 -3
- package/dist/types/protocol/defaults.d.ts +6 -0
- package/dist/types/protocol/index.d.ts +1 -2
- package/dist/types/protocol/jid.d.ts +19 -2
- package/dist/types/protocol/message.d.ts +60 -0
- package/dist/types/protocol/nodes.d.ts +2 -0
- package/dist/types/protocol/notification.d.ts +2 -0
- package/dist/types/protocol/privacy-token.d.ts +17 -0
- package/dist/types/protocol/privacy.d.ts +75 -0
- package/dist/types/protocol/stream.d.ts +30 -0
- package/dist/types/retry/codec.d.ts +3 -0
- package/dist/types/retry/index.d.ts +3 -3
- package/dist/types/retry/parse.d.ts +5 -2
- package/dist/types/retry/tracker.d.ts +1 -0
- package/dist/types/retry/types.d.ts +6 -1
- package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +2 -1
- package/dist/types/signal/api/SignalDigestSyncApi.d.ts +6 -0
- package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +2 -0
- package/dist/types/signal/api/SignalRotateKeyApi.d.ts +4 -5
- package/dist/types/signal/api/SignalSessionSyncApi.d.ts +8 -6
- package/dist/types/signal/api/result-map.d.ts +1 -0
- package/dist/types/signal/constants.d.ts +0 -3
- package/dist/types/signal/{store/sqlite.d.ts → encoding.d.ts} +3 -3
- package/dist/types/signal/group/SenderKeyManager.d.ts +10 -5
- package/dist/types/signal/index.d.ts +2 -0
- package/dist/types/signal/session/SignalProtocol.d.ts +10 -4
- package/dist/types/signal/session/resolver.d.ts +7 -2
- package/dist/types/store/contracts/appstate.store.d.ts +1 -1
- package/dist/types/store/contracts/privacy-token.store.d.ts +16 -0
- package/dist/types/store/contracts/retry.store.d.ts +7 -0
- package/dist/types/store/contracts/signal.store.d.ts +7 -0
- package/dist/types/store/createStore.d.ts +1 -1
- package/dist/types/store/index.d.ts +5 -13
- package/dist/types/store/locks/appstate.lock.d.ts +3 -0
- package/dist/types/store/locks/auth.lock.d.ts +3 -0
- package/dist/types/store/locks/contact.lock.d.ts +3 -0
- package/dist/types/store/locks/device-list.lock.d.ts +2 -0
- package/dist/types/store/locks/message.lock.d.ts +3 -0
- package/dist/types/store/locks/participants.lock.d.ts +2 -0
- package/dist/types/store/locks/privacy-token.lock.d.ts +2 -0
- package/dist/types/store/locks/retry.lock.d.ts +2 -0
- package/dist/types/store/locks/sender-key.lock.d.ts +3 -0
- package/dist/types/store/locks/signal.lock.d.ts +3 -0
- package/dist/types/store/locks/thread.lock.d.ts +3 -0
- package/dist/types/store/providers/memory/appstate.store.d.ts +1 -1
- package/dist/types/store/providers/memory/privacy-token.store.d.ts +13 -0
- package/dist/types/store/providers/memory/retry.store.d.ts +8 -0
- package/dist/types/store/providers/memory/signal.store.d.ts +2 -1
- package/dist/types/store/types.d.ts +49 -61
- package/dist/types/transport/WaWebSocket.d.ts +0 -1
- package/dist/types/transport/binary/constants.d.ts +0 -30
- package/dist/types/transport/binary/index.d.ts +0 -1
- package/dist/types/transport/node/WaNodeOrchestrator.d.ts +3 -4
- package/dist/types/transport/node/builders/business.d.ts +29 -0
- package/dist/types/transport/node/builders/global.d.ts +102 -0
- package/dist/types/transport/node/builders/index.d.ts +5 -2
- package/dist/types/transport/node/builders/message.d.ts +8 -7
- package/dist/types/transport/node/builders/pairing.d.ts +0 -2
- package/dist/types/transport/node/builders/privacy-token.d.ts +9 -0
- package/dist/types/transport/node/builders/privacy.d.ts +7 -0
- package/dist/types/transport/node/builders/profile.d.ts +8 -0
- package/dist/types/transport/node/builders/retry.d.ts +0 -1
- package/dist/types/transport/node/helpers.d.ts +5 -0
- package/dist/types/transport/noise/WaNoiseSession.d.ts +3 -2
- package/dist/types/transport/noise/WaNoiseSocket.d.ts +4 -2
- package/dist/types/util/bytes.d.ts +1 -1
- package/dist/types/util/index.d.ts +5 -0
- package/dist/types/util/primitives.d.ts +0 -1
- package/dist/util/bytes.js +22 -18
- package/dist/util/index.js +23 -0
- package/dist/util/primitives.js +2 -2
- package/package.json +29 -7
- package/proto/index.js +1 -1
- package/dist/crypto/core/constants.js +0 -4
- package/dist/esm/crypto/core/constants.js +0 -1
- package/dist/esm/retry/outbound.js +0 -82
- package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +0 -37
- package/dist/esm/store/providers/sqlite/appstate.store.js +0 -250
- package/dist/esm/store/providers/sqlite/auth.store.js +0 -176
- package/dist/esm/store/providers/sqlite/connection.js +0 -245
- package/dist/esm/store/providers/sqlite/contact.store.js +0 -74
- package/dist/esm/store/providers/sqlite/device-list.store.js +0 -127
- package/dist/esm/store/providers/sqlite/message.store.js +0 -132
- package/dist/esm/store/providers/sqlite/migrations.js +0 -347
- package/dist/esm/store/providers/sqlite/participants.store.js +0 -77
- package/dist/esm/store/providers/sqlite/retry.store.js +0 -141
- package/dist/esm/store/providers/sqlite/sender-key.store.js +0 -198
- package/dist/esm/store/providers/sqlite/signal.store.js +0 -435
- package/dist/esm/store/providers/sqlite/table-names.js +0 -107
- package/dist/esm/store/providers/sqlite/thread.store.js +0 -85
- package/dist/retry/outbound.js +0 -87
- package/dist/store/providers/sqlite/BaseSqliteStore.js +0 -41
- package/dist/store/providers/sqlite/appstate.store.js +0 -254
- package/dist/store/providers/sqlite/auth.store.js +0 -180
- package/dist/store/providers/sqlite/connection.js +0 -281
- package/dist/store/providers/sqlite/contact.store.js +0 -78
- package/dist/store/providers/sqlite/device-list.store.js +0 -131
- package/dist/store/providers/sqlite/message.store.js +0 -136
- package/dist/store/providers/sqlite/migrations.js +0 -350
- package/dist/store/providers/sqlite/participants.store.js +0 -81
- package/dist/store/providers/sqlite/retry.store.js +0 -145
- package/dist/store/providers/sqlite/sender-key.store.js +0 -202
- package/dist/store/providers/sqlite/signal.store.js +0 -439
- package/dist/store/providers/sqlite/table-names.js +0 -113
- package/dist/store/providers/sqlite/thread.store.js +0 -89
- package/dist/types/appstate/store/sqlite.d.ts +0 -7
- package/dist/types/crypto/core/constants.d.ts +0 -1
- package/dist/types/retry/outbound.d.ts +0 -4
- package/dist/types/store/providers/sqlite/BaseSqliteStore.d.ts +0 -12
- package/dist/types/store/providers/sqlite/appstate.store.d.ts +0 -17
- package/dist/types/store/providers/sqlite/auth.store.d.ts +0 -10
- package/dist/types/store/providers/sqlite/connection.d.ts +0 -10
- package/dist/types/store/providers/sqlite/contact.store.d.ts +0 -12
- package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -15
- package/dist/types/store/providers/sqlite/message.store.d.ts +0 -13
- package/dist/types/store/providers/sqlite/migrations.d.ts +0 -3
- package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -12
- package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -15
- package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -24
- package/dist/types/store/providers/sqlite/signal.store.d.ts +0 -53
- package/dist/types/store/providers/sqlite/table-names.d.ts +0 -5
- package/dist/types/store/providers/sqlite/thread.store.d.ts +0 -13
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import { randomBytesAsync, sha256 } from '../../crypto/index.js';
|
|
2
|
+
import { PromiseDedup } from '../../infra/perf/PromiseDedup.js';
|
|
2
3
|
import { ensureMessageSecret } from '../../message/index.js';
|
|
3
|
-
import { resolveMessageTypeAttr } from '../../message/content.js';
|
|
4
|
+
import { resolveEditAttr, resolveEncMediaType, resolveMessageTypeAttr, resolveMetaAttrs } from '../../message/content.js';
|
|
4
5
|
import { wrapDeviceSentMessage } from '../../message/device-sent.js';
|
|
6
|
+
import { injectDeviceListMetadata, resolveIcdcMeta } from '../../message/icdc.js';
|
|
5
7
|
import { writeRandomPadMax16 } from '../../message/padding.js';
|
|
6
8
|
import { computePhashV2 } from '../../message/phash.js';
|
|
7
9
|
import { buildReportingTokenArtifacts } from '../../message/reporting-token.js';
|
|
8
10
|
import { proto } from '../../proto.js';
|
|
9
11
|
import { WA_DEFAULTS } from '../../protocol/constants.js';
|
|
10
|
-
import { isGroupJid, normalizeDeviceJid, normalizeRecipientJid, parseSignalAddressFromJid, splitJid, toUserJid } from '../../protocol/jid.js';
|
|
12
|
+
import { isGroupJid, normalizeDeviceJid, normalizeRecipientJid, parseJidFull, parseSignalAddressFromJid, splitJid, toUserJid } from '../../protocol/jid.js';
|
|
11
13
|
import { signalAddressKey } from '../../protocol/jid.js';
|
|
12
14
|
import { encodeBinaryNode } from '../../transport/binary/index.js';
|
|
13
|
-
import { buildDirectMessageFanoutNode,
|
|
15
|
+
import { buildDirectMessageFanoutNode, buildGroupSenderKeyMessageNode, buildMetaNode } from '../../transport/node/builders/message.js';
|
|
14
16
|
import { bytesToHex, concatBytes, TEXT_ENCODER } from '../../util/bytes.js';
|
|
15
17
|
import { toError } from '../../util/primitives.js';
|
|
16
18
|
export class WaMessageDispatchCoordinator {
|
|
17
19
|
constructor(options) {
|
|
20
|
+
this.icdcDedup = new PromiseDedup();
|
|
21
|
+
this.privacyTokenDedup = new PromiseDedup();
|
|
22
|
+
this.distributionDedup = new PromiseDedup();
|
|
18
23
|
this.logger = options.logger;
|
|
19
24
|
this.messageClient = options.messageClient;
|
|
20
25
|
this.retryTracker = options.retryTracker;
|
|
@@ -25,9 +30,13 @@ export class WaMessageDispatchCoordinator {
|
|
|
25
30
|
this.buildMessageContent = options.buildMessageContent;
|
|
26
31
|
this.senderKeyManager = options.senderKeyManager;
|
|
27
32
|
this.signalProtocol = options.signalProtocol;
|
|
33
|
+
this.signalStore = options.signalStore;
|
|
34
|
+
this.deviceListStore = options.deviceListStore;
|
|
28
35
|
this.getCurrentMeJid = options.getCurrentMeJid;
|
|
29
36
|
this.getCurrentMeLid = options.getCurrentMeLid;
|
|
30
37
|
this.getCurrentSignedIdentity = options.getCurrentSignedIdentity;
|
|
38
|
+
this.resolvePrivacyTokenNode = options.resolvePrivacyTokenNode;
|
|
39
|
+
this.onDirectMessageSent = options.onDirectMessageSent;
|
|
31
40
|
}
|
|
32
41
|
async publishMessageNode(node, options = {}) {
|
|
33
42
|
this.logger.debug('wa client publish message node', {
|
|
@@ -68,7 +77,8 @@ export class WaMessageDispatchCoordinator {
|
|
|
68
77
|
toJid: input.to,
|
|
69
78
|
type: input.type ?? 'text',
|
|
70
79
|
replayPayload,
|
|
71
|
-
participantJid: input.participant
|
|
80
|
+
participantJid: input.participant,
|
|
81
|
+
eligibleRequesterDeviceJids: [input.to]
|
|
72
82
|
}, async () => this.messageClient.publishEncrypted(input, options));
|
|
73
83
|
}
|
|
74
84
|
async publishSignalMessage(input, options = {}) {
|
|
@@ -98,7 +108,8 @@ export class WaMessageDispatchCoordinator {
|
|
|
98
108
|
toJid: input.to,
|
|
99
109
|
type: messageType,
|
|
100
110
|
replayPayload,
|
|
101
|
-
participantJid: input.participant
|
|
111
|
+
participantJid: input.participant,
|
|
112
|
+
eligibleRequesterDeviceJids: [input.to]
|
|
102
113
|
}, async () => this.messageClient.publishEncrypted({
|
|
103
114
|
to: input.to,
|
|
104
115
|
encType: encrypted.type,
|
|
@@ -118,16 +129,32 @@ export class WaMessageDispatchCoordinator {
|
|
|
118
129
|
this.withResolvedMessageId(options)
|
|
119
130
|
]);
|
|
120
131
|
const messageWithSecret = await ensureMessageSecret(message);
|
|
121
|
-
const
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
132
|
+
const meJid = this.getCurrentMeJid();
|
|
133
|
+
const regInfo = meJid ? await this.signalStore.getRegistrationInfo() : null;
|
|
134
|
+
const localPubKey = regInfo?.identityKeyPair.pubKey;
|
|
135
|
+
const meParsed = meJid ? parseJidFull(meJid) : undefined;
|
|
136
|
+
const meUserJid = meParsed?.userJid;
|
|
137
|
+
const localIdentity = meParsed && localPubKey ? { address: meParsed.address, pubKey: localPubKey } : undefined;
|
|
138
|
+
const isGroup = isGroupJid(recipientJid);
|
|
139
|
+
const [senderIcdc, recipientIcdc] = await Promise.all([
|
|
140
|
+
meUserJid ? this.resolveUserIcdc(meUserJid, localIdentity) : null,
|
|
141
|
+
!isGroup ? this.resolveUserIcdc(toUserJid(recipientJid)) : null
|
|
142
|
+
]);
|
|
143
|
+
const messageWithIcdc = injectDeviceListMetadata(messageWithSecret, senderIcdc, recipientIcdc);
|
|
144
|
+
const plaintext = await writeRandomPadMax16(proto.Message.encode(messageWithIcdc).finish());
|
|
145
|
+
const type = resolveMessageTypeAttr(messageWithIcdc);
|
|
146
|
+
const edit = resolveEditAttr(messageWithIcdc, sendOptions.subtype) ?? undefined;
|
|
147
|
+
const mediatype = resolveEncMediaType(messageWithIcdc) ?? undefined;
|
|
148
|
+
const metaAttrs = resolveMetaAttrs(messageWithIcdc);
|
|
149
|
+
const metaNode = metaAttrs ? buildMetaNode(metaAttrs) : undefined;
|
|
150
|
+
if (isGroup) {
|
|
151
|
+
if (this.shouldUseGroupDirectPath(messageWithIcdc)) {
|
|
152
|
+
return this.publishGroupDirectMessage(recipientJid, messageWithIcdc, plaintext, type, sendOptions, {}, edit, mediatype, metaNode);
|
|
126
153
|
}
|
|
127
|
-
return this.publishGroupSenderKeyMessage(recipientJid,
|
|
154
|
+
return this.publishGroupSenderKeyMessage(recipientJid, messageWithIcdc, plaintext, type, sendOptions, {}, edit, mediatype, metaNode);
|
|
128
155
|
}
|
|
129
156
|
const directRecipientJid = toUserJid(recipientJid);
|
|
130
|
-
return this.publishDirectSignalMessageWithFanout(directRecipientJid,
|
|
157
|
+
return this.publishDirectSignalMessageWithFanout(directRecipientJid, messageWithIcdc, plaintext, type, sendOptions, edit, mediatype, metaNode);
|
|
131
158
|
}
|
|
132
159
|
async syncSignalSession(jid, reasonIdentity = false) {
|
|
133
160
|
const address = parseSignalAddressFromJid(jid);
|
|
@@ -156,7 +183,7 @@ export class WaMessageDispatchCoordinator {
|
|
|
156
183
|
}
|
|
157
184
|
return message.keepInChatMessage?.keepType === proto.KeepType.UNDO_KEEP_FOR_ALL;
|
|
158
185
|
}
|
|
159
|
-
async publishGroupDirectMessage(groupJid, message, plaintext, type, options, retryContext = {}) {
|
|
186
|
+
async publishGroupDirectMessage(groupJid, message, plaintext, type, options, retryContext = {}, edit, mediatype, metaNode) {
|
|
160
187
|
const sendOptions = await this.withResolvedMessageId(options);
|
|
161
188
|
const meJid = this.requireCurrentMeJid('sendMessage');
|
|
162
189
|
const participantUserJids = retryContext.forceRefreshParticipants
|
|
@@ -169,37 +196,68 @@ export class WaMessageDispatchCoordinator {
|
|
|
169
196
|
if (fanoutDeviceJids.length === 0) {
|
|
170
197
|
throw new Error('group direct send resolved no target devices');
|
|
171
198
|
}
|
|
172
|
-
await this.sessionResolver.ensureSessionsBatch(fanoutDeviceJids);
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
199
|
+
const resolvedFanoutTargets = await this.sessionResolver.ensureSessionsBatch(fanoutDeviceJids);
|
|
200
|
+
const uniqueNormalizedFanoutJids = new Set();
|
|
201
|
+
for (let index = 0; index < fanoutDeviceJids.length; index += 1) {
|
|
202
|
+
uniqueNormalizedFanoutJids.add(normalizeDeviceJid(fanoutDeviceJids[index]));
|
|
203
|
+
}
|
|
204
|
+
if (resolvedFanoutTargets.length !== uniqueNormalizedFanoutJids.size) {
|
|
205
|
+
throw new Error('group direct send resolved incomplete signal sessions');
|
|
206
|
+
}
|
|
207
|
+
const participantEncryptRequests = new Array(resolvedFanoutTargets.length);
|
|
208
|
+
for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
|
|
209
|
+
const target = resolvedFanoutTargets[index];
|
|
210
|
+
participantEncryptRequests[index] = {
|
|
211
|
+
address: target.address,
|
|
212
|
+
plaintext
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
const encryptedParticipants = await this.signalProtocol.encryptMessagesBatch(participantEncryptRequests, resolvedFanoutTargets);
|
|
216
|
+
const participants = new Array(resolvedFanoutTargets.length);
|
|
217
|
+
for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
|
|
218
|
+
const target = resolvedFanoutTargets[index];
|
|
219
|
+
participants[index] = {
|
|
220
|
+
jid: target.jid,
|
|
221
|
+
encType: encryptedParticipants[index].type,
|
|
222
|
+
ciphertext: encryptedParticipants[index].ciphertext
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
let shouldAttachDeviceIdentity = false;
|
|
226
|
+
for (let index = 0; index < participants.length; index += 1) {
|
|
227
|
+
if (participants[index].encType === 'pkmsg') {
|
|
228
|
+
shouldAttachDeviceIdentity = true;
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
const phashTargets = new Array(resolvedFanoutTargets.length + 1);
|
|
233
|
+
for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
|
|
234
|
+
phashTargets[index] = resolvedFanoutTargets[index].jid;
|
|
235
|
+
}
|
|
236
|
+
phashTargets[resolvedFanoutTargets.length] = senderForPhash;
|
|
237
|
+
const [localPhash, reportingArtifacts] = await Promise.all([
|
|
238
|
+
computePhashV2(phashTargets),
|
|
239
|
+
this.tryBuildReportingTokenArtifacts({
|
|
240
|
+
message,
|
|
241
|
+
stanzaId: sendOptions.id,
|
|
242
|
+
senderUserJid: toUserJid(senderForPhash),
|
|
243
|
+
remoteJid: groupJid,
|
|
244
|
+
context: 'group_direct'
|
|
245
|
+
})
|
|
246
|
+
]);
|
|
247
|
+
const messageNode = buildDirectMessageFanoutNode({
|
|
193
248
|
to: groupJid,
|
|
194
249
|
type,
|
|
195
250
|
id: sendOptions.id,
|
|
251
|
+
edit,
|
|
196
252
|
phash: localPhash,
|
|
197
253
|
addressingMode,
|
|
198
254
|
participants,
|
|
199
255
|
deviceIdentity: shouldAttachDeviceIdentity
|
|
200
256
|
? this.getEncodedSignedDeviceIdentity()
|
|
201
257
|
: undefined,
|
|
202
|
-
reportingNode: reportingArtifacts?.node ?? undefined
|
|
258
|
+
reportingNode: reportingArtifacts?.node ?? undefined,
|
|
259
|
+
metaNode,
|
|
260
|
+
mediatype
|
|
203
261
|
});
|
|
204
262
|
const replayPayload = {
|
|
205
263
|
mode: 'plaintext',
|
|
@@ -211,7 +269,8 @@ export class WaMessageDispatchCoordinator {
|
|
|
211
269
|
messageIdHint: sendOptions.id ?? messageNode.attrs.id,
|
|
212
270
|
toJid: groupJid,
|
|
213
271
|
type,
|
|
214
|
-
replayPayload
|
|
272
|
+
replayPayload,
|
|
273
|
+
eligibleRequesterDeviceJids: undefined
|
|
215
274
|
}, async () => this.messageClient.publishNode(messageNode, sendOptions));
|
|
216
275
|
const ackError = result.ack.error;
|
|
217
276
|
const serverPhash = result.ack.phash;
|
|
@@ -237,11 +296,11 @@ export class WaMessageDispatchCoordinator {
|
|
|
237
296
|
retried: true,
|
|
238
297
|
forceRefreshParticipants: true,
|
|
239
298
|
forceAddressingMode: serverAddressingMode
|
|
240
|
-
});
|
|
299
|
+
}, edit, mediatype, metaNode);
|
|
241
300
|
}
|
|
242
301
|
return result;
|
|
243
302
|
}
|
|
244
|
-
async publishGroupSenderKeyMessage(groupJid, message, plaintext, type, options, retryContext = {}) {
|
|
303
|
+
async publishGroupSenderKeyMessage(groupJid, message, plaintext, type, options, retryContext = {}, edit, mediatype, metaNode) {
|
|
245
304
|
const sendOptions = await this.withResolvedMessageId(options);
|
|
246
305
|
const meJid = this.requireCurrentMeJid('sendMessage');
|
|
247
306
|
const participantUserJids = retryContext.forceRefreshParticipants
|
|
@@ -251,23 +310,36 @@ export class WaMessageDispatchCoordinator {
|
|
|
251
310
|
this.resolveGroupAddressingMode(participantUserJids, groupJid);
|
|
252
311
|
const senderJid = this.resolveSenderForAddressingMode(addressingMode, meJid);
|
|
253
312
|
const sender = parseSignalAddressFromJid(senderJid);
|
|
254
|
-
const senderKeyDistributionMessage = await this.senderKeyManager.
|
|
255
|
-
const
|
|
256
|
-
const distributionData = await this.encryptGroupDistributionParticipants(groupJid, sender, senderKeyDistributionMessage, participantUserJids);
|
|
313
|
+
const { distributionMessage: senderKeyDistributionMessage, ciphertext: groupCiphertext, keyId: senderKeyId } = await this.senderKeyManager.prepareGroupEncryption(groupJid, sender, plaintext);
|
|
314
|
+
const distributionData = await this.distributionDedup.run(`dist:${groupJid}:${senderKeyId}`, () => this.encryptGroupDistributionParticipants(groupJid, senderKeyId, senderKeyDistributionMessage, participantUserJids));
|
|
257
315
|
const { fanoutDeviceJids, distributionParticipants } = distributionData;
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
316
|
+
let shouldAttachDeviceIdentity = false;
|
|
317
|
+
for (let index = 0; index < distributionParticipants.length; index += 1) {
|
|
318
|
+
if (distributionParticipants[index].encType === 'pkmsg') {
|
|
319
|
+
shouldAttachDeviceIdentity = true;
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
const phashTargets = new Array(fanoutDeviceJids.length + 1);
|
|
324
|
+
for (let index = 0; index < fanoutDeviceJids.length; index += 1) {
|
|
325
|
+
phashTargets[index] = fanoutDeviceJids[index];
|
|
326
|
+
}
|
|
327
|
+
phashTargets[fanoutDeviceJids.length] = senderJid;
|
|
328
|
+
const [localPhash, reportingArtifacts] = await Promise.all([
|
|
329
|
+
computePhashV2(phashTargets),
|
|
330
|
+
this.tryBuildReportingTokenArtifacts({
|
|
331
|
+
message,
|
|
332
|
+
stanzaId: sendOptions.id,
|
|
333
|
+
senderUserJid: toUserJid(senderJid),
|
|
334
|
+
remoteJid: groupJid,
|
|
335
|
+
context: 'group_sender_key'
|
|
336
|
+
})
|
|
337
|
+
]);
|
|
267
338
|
const messageNode = buildGroupSenderKeyMessageNode({
|
|
268
339
|
to: groupJid,
|
|
269
340
|
type,
|
|
270
341
|
id: sendOptions.id,
|
|
342
|
+
edit,
|
|
271
343
|
phash: localPhash,
|
|
272
344
|
addressingMode,
|
|
273
345
|
groupCiphertext: groupCiphertext.ciphertext,
|
|
@@ -275,7 +347,9 @@ export class WaMessageDispatchCoordinator {
|
|
|
275
347
|
deviceIdentity: shouldAttachDeviceIdentity
|
|
276
348
|
? this.getEncodedSignedDeviceIdentity()
|
|
277
349
|
: undefined,
|
|
278
|
-
reportingNode: reportingArtifacts?.node ?? undefined
|
|
350
|
+
reportingNode: reportingArtifacts?.node ?? undefined,
|
|
351
|
+
metaNode,
|
|
352
|
+
mediatype
|
|
279
353
|
});
|
|
280
354
|
const replayPayload = {
|
|
281
355
|
mode: 'plaintext',
|
|
@@ -287,11 +361,15 @@ export class WaMessageDispatchCoordinator {
|
|
|
287
361
|
messageIdHint: sendOptions.id ?? messageNode.attrs.id,
|
|
288
362
|
toJid: groupJid,
|
|
289
363
|
type,
|
|
290
|
-
replayPayload
|
|
364
|
+
replayPayload,
|
|
365
|
+
eligibleRequesterDeviceJids: undefined
|
|
291
366
|
}, async () => this.messageClient.publishNode(messageNode, sendOptions));
|
|
292
|
-
const distributedAddresses = distributionParticipants.
|
|
367
|
+
const distributedAddresses = new Array(distributionParticipants.length);
|
|
368
|
+
for (let index = 0; index < distributionParticipants.length; index += 1) {
|
|
369
|
+
distributedAddresses[index] = distributionParticipants[index].address;
|
|
370
|
+
}
|
|
293
371
|
try {
|
|
294
|
-
await this.senderKeyManager.markSenderKeyDistributed(groupJid,
|
|
372
|
+
await this.senderKeyManager.markSenderKeyDistributed(groupJid, senderKeyId, distributedAddresses);
|
|
295
373
|
}
|
|
296
374
|
catch (error) {
|
|
297
375
|
this.logger.warn('failed to mark sender key distribution targets', {
|
|
@@ -324,12 +402,13 @@ export class WaMessageDispatchCoordinator {
|
|
|
324
402
|
retried: true,
|
|
325
403
|
forceRefreshParticipants: true,
|
|
326
404
|
forceAddressingMode: serverAddressingMode
|
|
327
|
-
});
|
|
405
|
+
}, edit, mediatype, metaNode);
|
|
328
406
|
}
|
|
329
407
|
return result;
|
|
330
408
|
}
|
|
331
409
|
resolveGroupAddressingMode(participantUserJids, groupJid) {
|
|
332
|
-
for (
|
|
410
|
+
for (let index = 0; index < participantUserJids.length; index += 1) {
|
|
411
|
+
const participantJid = participantUserJids[index];
|
|
333
412
|
try {
|
|
334
413
|
if (splitJid(participantJid).server === 'lid') {
|
|
335
414
|
return 'lid';
|
|
@@ -362,7 +441,7 @@ export class WaMessageDispatchCoordinator {
|
|
|
362
441
|
}
|
|
363
442
|
return normalizeDeviceJid(meJid);
|
|
364
443
|
}
|
|
365
|
-
async encryptGroupDistributionParticipants(groupJid,
|
|
444
|
+
async encryptGroupDistributionParticipants(groupJid, senderKeyId, senderKeyDistributionMessage, participantUserJids) {
|
|
366
445
|
const distributionPayload = await writeRandomPadMax16(proto.Message.encode({
|
|
367
446
|
senderKeyDistributionMessage
|
|
368
447
|
}).finish());
|
|
@@ -381,7 +460,7 @@ export class WaMessageDispatchCoordinator {
|
|
|
381
460
|
fanoutAddresses[index] = address;
|
|
382
461
|
fanoutTargetsByAddressKey.set(signalAddressKey(address), { jid, address });
|
|
383
462
|
}
|
|
384
|
-
const pendingAddresses = await this.senderKeyManager.filterParticipantsNeedingDistribution(groupJid,
|
|
463
|
+
const pendingAddresses = await this.senderKeyManager.filterParticipantsNeedingDistribution(groupJid, senderKeyId, fanoutAddresses);
|
|
385
464
|
if (pendingAddresses.length === 0) {
|
|
386
465
|
return {
|
|
387
466
|
fanoutDeviceJids,
|
|
@@ -411,50 +490,82 @@ export class WaMessageDispatchCoordinator {
|
|
|
411
490
|
for (let index = 0; index < pendingTargets.length; index += 1) {
|
|
412
491
|
pendingTargetJids[index] = pendingTargets[index].jid;
|
|
413
492
|
}
|
|
493
|
+
let availableTargets = [];
|
|
494
|
+
let prefetchedAvailableTargets;
|
|
414
495
|
try {
|
|
415
|
-
await this.sessionResolver.ensureSessionsBatch(pendingTargetJids);
|
|
496
|
+
const resolvedTargets = await this.sessionResolver.ensureSessionsBatch(pendingTargetJids);
|
|
497
|
+
availableTargets = resolvedTargets;
|
|
498
|
+
prefetchedAvailableTargets = resolvedTargets;
|
|
416
499
|
}
|
|
417
500
|
catch (error) {
|
|
501
|
+
const normalized = toError(error);
|
|
502
|
+
if (normalized.message === 'identity mismatch') {
|
|
503
|
+
throw normalized;
|
|
504
|
+
}
|
|
418
505
|
this.logger.warn('group sender-key distribution session sync failed, continuing with available sessions', {
|
|
419
506
|
groupJid,
|
|
420
507
|
requested: pendingTargetJids.length,
|
|
421
|
-
message:
|
|
508
|
+
message: normalized.message
|
|
422
509
|
});
|
|
510
|
+
const pendingTargetAddresses = new Array(pendingTargets.length);
|
|
511
|
+
for (let index = 0; index < pendingTargets.length; index += 1) {
|
|
512
|
+
pendingTargetAddresses[index] = pendingTargets[index].address;
|
|
513
|
+
}
|
|
514
|
+
const hasPendingSessions = await this.signalStore.hasSessions(pendingTargetAddresses);
|
|
515
|
+
const nextAvailableTargets = [];
|
|
516
|
+
for (let index = 0; index < pendingTargets.length; index += 1) {
|
|
517
|
+
if (hasPendingSessions[index]) {
|
|
518
|
+
nextAvailableTargets.push(pendingTargets[index]);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
availableTargets = nextAvailableTargets;
|
|
423
522
|
}
|
|
424
|
-
const hasPendingSessions = await this.signalProtocol.hasSessions(pendingTargets.map((target) => target.address));
|
|
425
|
-
const availableTargets = pendingTargets.filter((_target, index) => hasPendingSessions[index]);
|
|
426
523
|
if (availableTargets.length === 0) {
|
|
427
524
|
return {
|
|
428
525
|
fanoutDeviceJids,
|
|
429
526
|
distributionParticipants: []
|
|
430
527
|
};
|
|
431
528
|
}
|
|
432
|
-
const
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
529
|
+
const distributionEncryptRequests = new Array(availableTargets.length);
|
|
530
|
+
for (let index = 0; index < availableTargets.length; index += 1) {
|
|
531
|
+
const target = availableTargets[index];
|
|
532
|
+
distributionEncryptRequests[index] = {
|
|
533
|
+
address: target.address,
|
|
534
|
+
plaintext: distributionPayload
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
const encryptedDistributionParticipants = await this.signalProtocol.encryptMessagesBatch(distributionEncryptRequests, prefetchedAvailableTargets);
|
|
538
|
+
const distributionParticipants = new Array(availableTargets.length);
|
|
539
|
+
for (let index = 0; index < availableTargets.length; index += 1) {
|
|
540
|
+
const target = availableTargets[index];
|
|
541
|
+
distributionParticipants[index] = {
|
|
542
|
+
jid: target.jid,
|
|
543
|
+
address: target.address,
|
|
544
|
+
encType: encryptedDistributionParticipants[index].type,
|
|
545
|
+
ciphertext: encryptedDistributionParticipants[index].ciphertext
|
|
546
|
+
};
|
|
547
|
+
}
|
|
442
548
|
return {
|
|
443
549
|
fanoutDeviceJids,
|
|
444
550
|
distributionParticipants
|
|
445
551
|
};
|
|
446
552
|
}
|
|
447
|
-
async publishDirectSignalMessageWithFanout(recipientJid, message, plaintext, type, options) {
|
|
553
|
+
async publishDirectSignalMessageWithFanout(recipientJid, message, plaintext, type, options, edit, mediatype, metaNode) {
|
|
448
554
|
const sendOptions = await this.withResolvedMessageId(options);
|
|
449
555
|
const meJid = this.requireCurrentMeJid('sendMessage');
|
|
450
556
|
const meLid = this.getCurrentMeLid();
|
|
451
557
|
const selfDeviceJidForRecipient = this.fanoutResolver.resolveSelfDeviceJidForRecipient(recipientJid, meJid, meLid);
|
|
452
558
|
const deviceJids = await this.fanoutResolver.resolveDirectFanoutDeviceJids(recipientJid, selfDeviceJidForRecipient);
|
|
453
|
-
const targets = deviceJids.
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
559
|
+
const targets = new Array(deviceJids.length);
|
|
560
|
+
for (let index = 0; index < deviceJids.length; index += 1) {
|
|
561
|
+
const jid = deviceJids[index];
|
|
562
|
+
const parsed = parseJidFull(jid);
|
|
563
|
+
targets[index] = {
|
|
564
|
+
jid,
|
|
565
|
+
normalizedJid: parsed.normalizedJid,
|
|
566
|
+
userJid: parsed.userJid
|
|
567
|
+
};
|
|
568
|
+
}
|
|
458
569
|
const recipientUserJid = toUserJid(recipientJid);
|
|
459
570
|
const meUserJid = toUserJid(selfDeviceJidForRecipient);
|
|
460
571
|
this.logger.debug('wa client publish signal fanout', {
|
|
@@ -471,30 +582,75 @@ export class WaMessageDispatchCoordinator {
|
|
|
471
582
|
}
|
|
472
583
|
}
|
|
473
584
|
}
|
|
474
|
-
await this.sessionResolver.ensureSessionsBatch(deviceJids, expectedIdentityByJid);
|
|
475
|
-
const
|
|
585
|
+
const resolvedFanoutTargets = await this.sessionResolver.ensureSessionsBatch(deviceJids, expectedIdentityByJid);
|
|
586
|
+
const resolvedFanoutTargetsByJid = new Map();
|
|
587
|
+
for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
|
|
588
|
+
const target = resolvedFanoutTargets[index];
|
|
589
|
+
resolvedFanoutTargetsByJid.set(normalizeDeviceJid(target.jid), target);
|
|
590
|
+
}
|
|
591
|
+
for (let index = 0; index < targets.length; index += 1) {
|
|
592
|
+
if (!resolvedFanoutTargetsByJid.has(targets[index].normalizedJid)) {
|
|
593
|
+
throw new Error('direct fanout missing signal sessions for one or more targets');
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
let hasSelfDeviceFanout = false;
|
|
597
|
+
for (let index = 0; index < targets.length; index += 1) {
|
|
598
|
+
if (targets[index].userJid === meUserJid) {
|
|
599
|
+
hasSelfDeviceFanout = true;
|
|
600
|
+
break;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
476
603
|
const selfDevicePlaintext = hasSelfDeviceFanout
|
|
477
604
|
? await writeRandomPadMax16(proto.Message.encode(wrapDeviceSentMessage(message, recipientUserJid)).finish())
|
|
478
605
|
: null;
|
|
479
|
-
const participantRequests = targets.
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
const
|
|
606
|
+
const participantRequests = new Array(targets.length);
|
|
607
|
+
for (let index = 0; index < targets.length; index += 1) {
|
|
608
|
+
const target = targets[index];
|
|
609
|
+
const resolvedTarget = resolvedFanoutTargetsByJid.get(target.normalizedJid);
|
|
610
|
+
if (!resolvedTarget) {
|
|
611
|
+
throw new Error('direct fanout missing signal session for target');
|
|
612
|
+
}
|
|
613
|
+
participantRequests[index] = {
|
|
614
|
+
target,
|
|
615
|
+
address: resolvedTarget.address,
|
|
616
|
+
session: resolvedTarget.session,
|
|
617
|
+
expectedIdentity: target.userJid === recipientUserJid ? sendOptions.expectedIdentity : undefined,
|
|
618
|
+
plaintext: selfDevicePlaintext && target.userJid === meUserJid
|
|
619
|
+
? selfDevicePlaintext
|
|
620
|
+
: plaintext
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
const encryptRequests = new Array(participantRequests.length);
|
|
624
|
+
const prefetchedSessions = new Array(participantRequests.length);
|
|
625
|
+
for (let index = 0; index < participantRequests.length; index += 1) {
|
|
626
|
+
const request = participantRequests[index];
|
|
627
|
+
encryptRequests[index] = {
|
|
628
|
+
address: request.address,
|
|
629
|
+
plaintext: request.plaintext,
|
|
630
|
+
expectedIdentity: request.expectedIdentity
|
|
631
|
+
};
|
|
632
|
+
prefetchedSessions[index] = {
|
|
633
|
+
address: request.address,
|
|
634
|
+
session: request.session
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
const encryptedParticipants = await this.signalProtocol.encryptMessagesBatch(encryptRequests, prefetchedSessions);
|
|
638
|
+
const participants = new Array(participantRequests.length);
|
|
639
|
+
for (let index = 0; index < participantRequests.length; index += 1) {
|
|
640
|
+
const request = participantRequests[index];
|
|
641
|
+
participants[index] = {
|
|
642
|
+
jid: request.target.jid,
|
|
643
|
+
encType: encryptedParticipants[index].type,
|
|
644
|
+
ciphertext: encryptedParticipants[index].ciphertext
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
let shouldAttachDeviceIdentity = false;
|
|
648
|
+
for (let index = 0; index < participants.length; index += 1) {
|
|
649
|
+
if (participants[index].encType === 'pkmsg') {
|
|
650
|
+
shouldAttachDeviceIdentity = true;
|
|
651
|
+
break;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
498
654
|
const deviceIdentity = shouldAttachDeviceIdentity
|
|
499
655
|
? this.getEncodedSignedDeviceIdentity()
|
|
500
656
|
: undefined;
|
|
@@ -505,13 +661,28 @@ export class WaMessageDispatchCoordinator {
|
|
|
505
661
|
remoteJid: recipientUserJid,
|
|
506
662
|
context: 'direct_fanout'
|
|
507
663
|
});
|
|
664
|
+
let privacyTokenNode;
|
|
665
|
+
try {
|
|
666
|
+
privacyTokenNode =
|
|
667
|
+
(await this.privacyTokenDedup.run(`pt:${recipientUserJid}`, () => this.resolvePrivacyTokenNode(recipientUserJid))) ?? undefined;
|
|
668
|
+
}
|
|
669
|
+
catch (error) {
|
|
670
|
+
this.logger.warn('privacy token resolution failed', {
|
|
671
|
+
to: recipientUserJid,
|
|
672
|
+
message: toError(error).message
|
|
673
|
+
});
|
|
674
|
+
}
|
|
508
675
|
const messageNode = buildDirectMessageFanoutNode({
|
|
509
676
|
to: recipientJid,
|
|
510
677
|
type,
|
|
511
678
|
id: sendOptions.id,
|
|
679
|
+
edit,
|
|
512
680
|
participants,
|
|
513
681
|
deviceIdentity,
|
|
514
|
-
reportingNode: reportingArtifacts?.node ?? undefined
|
|
682
|
+
reportingNode: reportingArtifacts?.node ?? undefined,
|
|
683
|
+
privacyTokenNode,
|
|
684
|
+
metaNode,
|
|
685
|
+
mediatype
|
|
515
686
|
});
|
|
516
687
|
const replayPayload = {
|
|
517
688
|
mode: 'plaintext',
|
|
@@ -519,12 +690,15 @@ export class WaMessageDispatchCoordinator {
|
|
|
519
690
|
type,
|
|
520
691
|
plaintext
|
|
521
692
|
};
|
|
522
|
-
|
|
693
|
+
const result = await this.retryTracker.track({
|
|
523
694
|
messageIdHint: sendOptions.id ?? messageNode.attrs.id,
|
|
524
695
|
toJid: recipientJid,
|
|
525
696
|
type,
|
|
526
|
-
replayPayload
|
|
697
|
+
replayPayload,
|
|
698
|
+
eligibleRequesterDeviceJids: deviceJids
|
|
527
699
|
}, async () => this.messageClient.publishNode(messageNode, sendOptions));
|
|
700
|
+
this.onDirectMessageSent(recipientUserJid);
|
|
701
|
+
return result;
|
|
528
702
|
}
|
|
529
703
|
async withResolvedMessageId(options) {
|
|
530
704
|
const normalizedId = options.id?.trim();
|
|
@@ -592,6 +766,25 @@ export class WaMessageDispatchCoordinator {
|
|
|
592
766
|
}
|
|
593
767
|
return proto.ADVSignedDeviceIdentity.encode(signedIdentity).finish();
|
|
594
768
|
}
|
|
769
|
+
resolveUserIcdc(userJid, localIdentity) {
|
|
770
|
+
return this.icdcDedup.run(`icdc:${userJid}:${localIdentity ? '1' : '0'}`, async () => {
|
|
771
|
+
try {
|
|
772
|
+
const snapshots = await this.deviceListStore.getUserDevicesBatch([userJid]);
|
|
773
|
+
const snapshot = snapshots[0];
|
|
774
|
+
if (!snapshot || snapshot.deviceJids.length === 0) {
|
|
775
|
+
return null;
|
|
776
|
+
}
|
|
777
|
+
return resolveIcdcMeta(snapshot.deviceJids, this.signalStore, snapshot.updatedAtMs, localIdentity);
|
|
778
|
+
}
|
|
779
|
+
catch (error) {
|
|
780
|
+
this.logger.trace('icdc resolution failed', {
|
|
781
|
+
userJid,
|
|
782
|
+
message: toError(error).message
|
|
783
|
+
});
|
|
784
|
+
return null;
|
|
785
|
+
}
|
|
786
|
+
});
|
|
787
|
+
}
|
|
595
788
|
requireCurrentMeJid(context) {
|
|
596
789
|
const meJid = this.getCurrentMeJid();
|
|
597
790
|
if (meJid) {
|