zapo-js 0.2.0 → 0.3.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 +7 -3
- package/dist/appstate/WaAppStateCrypto.js +49 -41
- package/dist/appstate/WaAppStateSyncClient.js +79 -42
- package/dist/appstate/index.js +2 -2
- package/dist/auth/WaAuthClient.js +20 -11
- package/dist/auth/{flow/WaAuthCredentialsFlow.js → credentials-flow.js} +83 -18
- package/dist/auth/pairing/WaPairingFlow.js +26 -29
- package/dist/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +29 -13
- package/dist/client/WaClient.js +115 -75
- package/dist/client/WaClientFactory.js +113 -30
- package/dist/client/connection/WaConnectionManager.js +4 -1
- package/dist/client/coordinators/WaAbPropsCoordinator.js +141 -0
- package/dist/client/coordinators/WaBusinessCoordinator.js +3 -12
- package/dist/client/coordinators/WaEmailCoordinator.js +63 -0
- package/dist/client/coordinators/WaIncomingNodeCoordinator.js +33 -8
- package/dist/client/coordinators/WaMessageDispatchCoordinator.js +55 -25
- package/dist/client/coordinators/WaOfflineResumeCoordinator.js +114 -0
- package/dist/client/coordinators/WaPassiveTasksCoordinator.js +38 -20
- package/dist/client/coordinators/WaProfileCoordinator.js +3 -1
- package/dist/client/coordinators/WaRetryCoordinator.js +11 -9
- package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +22 -4
- package/dist/client/dirty.js +1 -1
- package/dist/client/events/abprops.js +43 -0
- package/dist/client/events/privacy-token.js +1 -2
- package/dist/client/events/registration.js +42 -0
- package/dist/client/incoming.js +37 -0
- package/dist/client/mailbox.js +17 -1
- package/dist/client/media.js +243 -0
- package/dist/client/messages.js +163 -86
- package/dist/crypto/core/index.js +4 -1
- package/dist/crypto/core/random.js +3 -9
- package/dist/crypto/core/xeddsa.js +57 -0
- package/dist/crypto/curves/X25519.js +18 -0
- package/dist/crypto/curves/constants.js +2 -1
- package/dist/esm/appstate/WaAppStateCrypto.js +39 -31
- package/dist/esm/appstate/WaAppStateSyncClient.js +68 -31
- package/dist/esm/appstate/index.js +1 -1
- package/dist/esm/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +1 -1
- package/dist/esm/auth/WaAuthClient.js +17 -8
- package/dist/esm/auth/{flow/WaAuthCredentialsFlow.js → credentials-flow.js} +83 -18
- package/dist/esm/auth/pairing/WaPairingFlow.js +25 -28
- package/dist/esm/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +20 -6
- package/dist/esm/client/WaClient.js +116 -76
- package/dist/esm/client/WaClientFactory.js +114 -31
- package/dist/esm/client/connection/WaConnectionManager.js +4 -1
- package/dist/esm/client/coordinators/WaAbPropsCoordinator.js +137 -0
- package/dist/esm/client/coordinators/WaBusinessCoordinator.js +4 -13
- package/dist/esm/client/coordinators/WaEmailCoordinator.js +60 -0
- package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +35 -10
- package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +47 -17
- package/dist/esm/client/coordinators/WaOfflineResumeCoordinator.js +110 -0
- package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +38 -20
- package/dist/esm/client/coordinators/WaProfileCoordinator.js +3 -1
- package/dist/esm/client/coordinators/WaRetryCoordinator.js +11 -9
- package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +24 -6
- package/dist/esm/client/dirty.js +1 -1
- package/dist/esm/client/events/abprops.js +40 -0
- package/dist/esm/client/events/privacy-token.js +1 -2
- package/dist/esm/client/events/registration.js +39 -0
- package/dist/esm/client/incoming.js +36 -0
- package/dist/esm/client/mailbox.js +17 -1
- package/dist/esm/client/media.js +234 -0
- package/dist/esm/client/messages.js +162 -85
- package/dist/esm/crypto/core/index.js +1 -0
- package/dist/esm/crypto/core/random.js +2 -7
- package/dist/esm/crypto/core/xeddsa.js +53 -0
- package/dist/esm/crypto/curves/X25519.js +20 -2
- package/dist/esm/crypto/curves/constants.js +1 -0
- package/dist/esm/infra/perf/StoreLock.js +7 -4
- package/dist/esm/media/WaMediaCrypto.js +257 -62
- package/dist/esm/media/WaMediaTransferClient.js +47 -190
- package/dist/esm/media/constants.js +2 -0
- package/dist/esm/media/processor.js +1 -0
- package/dist/esm/message/addon-crypto.js +130 -3
- package/dist/esm/message/content.js +12 -6
- package/dist/esm/message/icdc.js +8 -8
- package/dist/esm/message/incoming.js +14 -12
- package/dist/esm/message/phash.js +32 -12
- package/dist/esm/message/reporting-token.js +3 -3
- package/dist/esm/message/use-case-secret.js +1 -1
- package/dist/esm/protocol/abprops.js +159 -0
- package/dist/esm/protocol/browser.js +14 -0
- package/dist/esm/protocol/constants.js +3 -1
- package/dist/esm/protocol/email.js +30 -0
- package/dist/esm/protocol/jid.js +44 -10
- package/dist/esm/protocol/nodes.js +6 -2
- package/dist/esm/protocol/notification.js +7 -1
- package/dist/esm/retry/reason.js +1 -1
- package/dist/esm/signal/api/SignalDeviceSyncApi.js +5 -2
- package/dist/esm/signal/api/SignalDigestSyncApi.js +8 -6
- package/dist/esm/signal/api/SignalIdentitySyncApi.js +4 -4
- package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +1 -1
- package/dist/esm/signal/api/SignalSessionSyncApi.js +1 -1
- package/dist/esm/signal/crypto/WaAdvSignature.js +5 -51
- package/dist/esm/signal/crypto/constants.js +0 -4
- package/dist/esm/signal/encoding.js +11 -54
- package/dist/esm/signal/group/SenderKeyChain.js +3 -3
- package/dist/esm/signal/group/SenderKeyCodec.js +5 -6
- package/dist/esm/signal/group/SenderKeyManager.js +13 -10
- package/dist/esm/signal/registration/keygen.js +2 -3
- package/dist/esm/signal/registration/utils.js +2 -2
- package/dist/esm/signal/session/SignalProtocol.js +18 -17
- package/dist/esm/signal/session/SignalRatchet.js +21 -10
- package/dist/esm/signal/session/SignalSerializer.js +5 -6
- package/dist/esm/signal/session/SignalSession.js +11 -9
- package/dist/esm/signal/session/resolver.js +6 -6
- 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 +48 -12
- package/dist/esm/store/index.js +4 -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/noop.store.js +20 -0
- package/dist/esm/store/providers/memory/device-list.store.js +3 -0
- package/dist/esm/store/providers/memory/identity.store.js +31 -0
- package/dist/esm/store/providers/memory/message-secret.store.js +81 -0
- package/dist/esm/store/providers/memory/participants.store.js +3 -0
- package/dist/esm/store/providers/memory/pre-key.store.js +97 -0
- package/dist/esm/store/providers/memory/retry.store.js +25 -11
- package/dist/esm/store/providers/memory/session.store.js +45 -0
- package/dist/esm/store/providers/memory/signal.store.js +1 -164
- package/dist/esm/transport/WaComms.js +4 -3
- package/dist/esm/transport/WaWebSocket.js +9 -1
- package/dist/esm/transport/index.js +6 -0
- package/dist/esm/transport/keepalive/WaKeepAlive.js +17 -8
- package/dist/esm/transport/node/WaMobileTcpSocket.js +114 -0
- package/dist/esm/transport/node/WaNodeOrchestrator.js +17 -8
- package/dist/esm/transport/node/builders/abprops.js +20 -0
- package/dist/esm/transport/node/builders/device.js +11 -0
- package/dist/esm/transport/node/builders/email.js +65 -0
- package/dist/esm/transport/node/builders/offline.js +14 -0
- package/dist/esm/transport/node/builders/prekeys.js +37 -40
- package/dist/esm/transport/node/builders/presence.js +13 -0
- package/dist/esm/transport/node/builders/privacy-token.js +19 -23
- package/dist/esm/transport/node/builders/retry.js +1 -1
- package/dist/esm/transport/node/helpers.js +24 -0
- package/dist/esm/transport/node/mex/argo-decoder.js +152 -0
- package/dist/esm/transport/node/mex/client.js +83 -0
- package/dist/esm/transport/node/mex/persist-ids.js +10 -0
- package/dist/esm/transport/noise/WaClientPayload.js +15 -10
- package/dist/esm/transport/noise/WaFrameCodec.js +2 -2
- package/dist/esm/transport/noise/WaMobileClientPayload.js +53 -0
- package/dist/esm/transport/noise/WaNoiseCert.js +9 -27
- package/dist/esm/transport/noise/WaNoiseSession.js +12 -11
- package/dist/infra/perf/StoreLock.js +7 -4
- package/dist/media/WaMediaCrypto.js +253 -58
- package/dist/media/WaMediaTransferClient.js +50 -223
- package/dist/media/constants.js +3 -1
- package/dist/media/processor.js +2 -0
- package/dist/message/addon-crypto.js +131 -0
- package/dist/message/content.js +13 -5
- package/dist/message/icdc.js +8 -8
- package/dist/message/incoming.js +14 -12
- package/dist/message/phash.js +32 -12
- package/dist/message/reporting-token.js +2 -2
- package/dist/message/use-case-secret.js +1 -1
- package/dist/protocol/abprops.js +163 -0
- package/dist/protocol/browser.js +15 -0
- package/dist/protocol/constants.js +14 -2
- package/dist/protocol/email.js +33 -0
- package/dist/protocol/jid.js +45 -10
- package/dist/protocol/nodes.js +6 -2
- package/dist/protocol/notification.js +8 -2
- package/dist/retry/reason.js +1 -1
- package/dist/signal/api/SignalDeviceSyncApi.js +5 -2
- package/dist/signal/api/SignalDigestSyncApi.js +8 -6
- package/dist/signal/api/SignalIdentitySyncApi.js +4 -4
- package/dist/signal/crypto/WaAdvSignature.js +2 -50
- package/dist/signal/crypto/constants.js +1 -5
- package/dist/signal/encoding.js +11 -49
- package/dist/signal/group/SenderKeyChain.js +2 -2
- package/dist/signal/group/SenderKeyCodec.js +4 -5
- package/dist/signal/group/SenderKeyManager.js +12 -9
- package/dist/signal/registration/keygen.js +1 -2
- package/dist/signal/registration/utils.js +2 -2
- package/dist/signal/session/SignalProtocol.js +18 -17
- package/dist/signal/session/SignalRatchet.js +19 -8
- package/dist/signal/session/SignalSerializer.js +5 -6
- package/dist/signal/session/SignalSession.js +11 -9
- package/dist/signal/session/resolver.js +6 -6
- 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 +47 -11
- package/dist/store/index.js +9 -1
- 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/noop.store.js +21 -1
- package/dist/store/providers/memory/device-list.store.js +3 -0
- package/dist/store/providers/memory/identity.store.js +35 -0
- package/dist/store/providers/memory/message-secret.store.js +85 -0
- package/dist/store/providers/memory/participants.store.js +3 -0
- package/dist/store/providers/memory/pre-key.store.js +101 -0
- package/dist/store/providers/memory/retry.store.js +24 -10
- package/dist/store/providers/memory/session.store.js +49 -0
- package/dist/store/providers/memory/signal.store.js +1 -164
- package/dist/transport/WaComms.js +4 -3
- package/dist/transport/WaWebSocket.js +9 -1
- package/dist/transport/index.js +17 -1
- package/dist/transport/keepalive/WaKeepAlive.js +17 -8
- package/dist/transport/node/WaMobileTcpSocket.js +118 -0
- package/dist/transport/node/WaNodeOrchestrator.js +16 -7
- package/dist/transport/node/builders/abprops.js +23 -0
- package/dist/transport/node/builders/device.js +14 -0
- package/dist/transport/node/builders/email.js +72 -0
- package/dist/transport/node/builders/offline.js +17 -0
- package/dist/transport/node/builders/prekeys.js +36 -39
- package/dist/transport/node/builders/presence.js +16 -0
- package/dist/transport/node/builders/privacy-token.js +18 -22
- package/dist/transport/node/builders/retry.js +1 -1
- package/dist/transport/node/helpers.js +26 -0
- package/dist/transport/node/mex/argo-decoder.js +189 -0
- package/dist/transport/node/mex/client.js +86 -0
- package/dist/transport/node/mex/persist-ids.js +13 -0
- package/dist/transport/noise/WaClientPayload.js +14 -9
- package/dist/transport/noise/WaFrameCodec.js +1 -1
- package/dist/transport/noise/WaMobileClientPayload.js +56 -0
- package/dist/transport/noise/WaNoiseCert.js +8 -26
- package/dist/transport/noise/WaNoiseSession.js +11 -10
- package/dist/types/appstate/WaAppStateCrypto.d.ts +11 -8
- package/dist/types/appstate/WaAppStateSyncClient.d.ts +6 -2
- package/dist/types/appstate/index.d.ts +1 -1
- package/dist/types/appstate/{WaAppStateSyncResponseParser.d.ts → response-parser.d.ts} +1 -1
- package/dist/types/appstate/types.d.ts +1 -1
- package/dist/types/auth/WaAuthClient.d.ts +9 -3
- package/dist/types/auth/credentials-flow.d.ts +20 -0
- package/dist/types/auth/pairing/WaPairingFlow.d.ts +3 -2
- package/dist/types/auth/pairing/{WaPairingCodeCrypto.d.ts → pairing-code-crypto.d.ts} +6 -1
- package/dist/types/auth/types.d.ts +40 -0
- package/dist/types/client/WaClient.d.ts +19 -8
- package/dist/types/client/WaClientFactory.d.ts +10 -4
- package/dist/types/client/coordinators/WaAbPropsCoordinator.d.ts +26 -0
- package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +1 -1
- package/dist/types/client/coordinators/WaEmailCoordinator.d.ts +24 -0
- package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +6 -1
- package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +15 -2
- package/dist/types/client/coordinators/WaOfflineResumeCoordinator.d.ts +31 -0
- package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +13 -2
- package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +1 -1
- package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +4 -2
- package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +6 -0
- package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +11 -1
- package/dist/types/client/dirty.d.ts +3 -1
- package/dist/types/client/events/abprops.d.ts +14 -0
- package/dist/types/client/events/registration.d.ts +17 -0
- package/dist/types/client/incoming.d.ts +6 -1
- package/dist/types/client/mailbox.d.ts +2 -0
- package/dist/types/client/media.d.ts +31 -0
- package/dist/types/client/messages.d.ts +2 -0
- package/dist/types/client/persistence/WriteBehindPersistence.d.ts +1 -1
- package/dist/types/client/types.d.ts +100 -1
- package/dist/types/crypto/core/index.d.ts +1 -0
- package/dist/types/crypto/core/primitives.d.ts +1 -1
- package/dist/types/crypto/core/random.d.ts +1 -1
- package/dist/types/crypto/core/xeddsa.d.ts +2 -0
- package/dist/types/crypto/curves/constants.d.ts +1 -0
- package/dist/types/crypto/index.d.ts +1 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/infra/log/ConsoleLogger.d.ts +1 -1
- package/dist/types/infra/log/PinoLogger.d.ts +1 -1
- package/dist/types/infra/perf/StoreLock.d.ts +1 -0
- package/dist/types/media/WaMediaCrypto.d.ts +15 -6
- package/dist/types/media/WaMediaTransferClient.d.ts +3 -11
- package/dist/types/media/constants.d.ts +2 -0
- package/dist/types/media/index.d.ts +1 -0
- package/dist/types/media/processor.d.ts +28 -0
- package/dist/types/media/types.d.ts +9 -3
- package/dist/types/message/addon-crypto.d.ts +34 -3
- package/dist/types/message/content.d.ts +3 -1
- package/dist/types/message/icdc.d.ts +4 -4
- package/dist/types/message/types.d.ts +16 -24
- package/dist/types/protocol/abprops.d.ts +142 -0
- package/dist/types/protocol/browser.d.ts +1 -0
- package/dist/types/protocol/constants.d.ts +5 -1
- package/dist/types/protocol/email.d.ts +32 -0
- package/dist/types/protocol/jid.d.ts +1 -0
- package/dist/types/protocol/nodes.d.ts +4 -0
- package/dist/types/protocol/notification.d.ts +6 -0
- package/dist/types/protocol/stream.d.ts +1 -0
- package/dist/types/retry/reason.d.ts +1 -1
- package/dist/types/signal/api/SignalDigestSyncApi.d.ts +3 -0
- package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +3 -3
- package/dist/types/signal/crypto/WaAdvSignature.d.ts +0 -2
- package/dist/types/signal/crypto/constants.d.ts +0 -1
- package/dist/types/signal/encoding.d.ts +7 -1
- package/dist/types/signal/group/SenderKeyChain.d.ts +1 -1
- package/dist/types/signal/group/SenderKeyManager.d.ts +7 -2
- package/dist/types/signal/registration/utils.d.ts +2 -1
- package/dist/types/signal/session/SignalProtocol.d.ts +11 -2
- package/dist/types/signal/session/SignalSerializer.d.ts +2 -1
- package/dist/types/signal/session/resolver.d.ts +4 -2
- package/dist/types/signal/types.d.ts +16 -4
- 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/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/index.d.ts +9 -1
- 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/noop.store.d.ts +4 -0
- package/dist/types/store/providers/memory/identity.store.d.ts +18 -0
- package/dist/types/store/providers/memory/message-secret.store.d.ts +21 -0
- package/dist/types/store/providers/memory/pre-key.store.d.ts +23 -0
- package/dist/types/store/providers/memory/retry.store.d.ts +7 -1
- package/dist/types/store/providers/memory/session.store.d.ts +21 -0
- package/dist/types/store/providers/memory/signal.store.d.ts +3 -45
- package/dist/types/store/providers/memory/thread.store.d.ts +1 -1
- package/dist/types/store/types.d.ts +21 -1
- package/dist/types/transport/WaWebSocket.d.ts +1 -0
- package/dist/types/transport/index.d.ts +8 -1
- package/dist/types/transport/keepalive/WaKeepAlive.d.ts +4 -1
- package/dist/types/transport/node/WaMobileTcpSocket.d.ts +18 -0
- package/dist/types/transport/node/WaNodeOrchestrator.d.ts +6 -2
- package/dist/types/transport/node/builders/abprops.d.ts +5 -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/offline.d.ts +2 -0
- package/dist/types/transport/node/builders/prekeys.d.ts +4 -3
- package/dist/types/transport/node/builders/presence.d.ts +6 -0
- package/dist/types/transport/node/helpers.d.ts +3 -0
- package/dist/types/transport/node/mex/argo-decoder.d.ts +11 -0
- package/dist/types/transport/node/mex/client.d.ts +18 -0
- package/dist/types/transport/node/mex/persist-ids.d.ts +14 -0
- package/dist/types/transport/noise/WaMobileClientPayload.d.ts +29 -0
- package/dist/types/transport/noise/WaNoiseCert.d.ts +7 -1
- package/dist/types/transport/noise/WaNoiseSession.d.ts +1 -0
- package/dist/types/transport/types.d.ts +8 -0
- package/package.json +6 -4
- package/dist/auth/pairing/constants.js +0 -5
- package/dist/client/connection/WaKeyShareCoordinator.js +0 -63
- package/dist/esm/auth/pairing/constants.js +0 -2
- package/dist/esm/client/connection/WaKeyShareCoordinator.js +0 -59
- package/dist/esm/transport/node/builders/index.js +0 -11
- package/dist/transport/node/builders/index.js +0 -51
- 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/transport/node/builders/index.d.ts +0 -11
- /package/dist/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +0 -0
|
@@ -6,7 +6,7 @@ const constants_1 = require("../../protocol/constants");
|
|
|
6
6
|
const helpers_1 = require("../../transport/node/helpers");
|
|
7
7
|
const parse_1 = require("../../transport/stream/parse");
|
|
8
8
|
const primitives_1 = require("../../util/primitives");
|
|
9
|
-
const
|
|
9
|
+
const INFO_BULLETIN_CHILD_TAGS = new Set([
|
|
10
10
|
'offline',
|
|
11
11
|
'offline_preview',
|
|
12
12
|
'priority_offline_complete',
|
|
@@ -18,6 +18,7 @@ class WaIncomingNodeCoordinator {
|
|
|
18
18
|
constructor(options) {
|
|
19
19
|
this.logger = options.logger;
|
|
20
20
|
this.runtime = options.runtime;
|
|
21
|
+
this.offlineResume = options.offlineResume;
|
|
21
22
|
this.nodeHandlerRegistry = new Map();
|
|
22
23
|
this.registerDefaultIncomingHandlers();
|
|
23
24
|
this.mediaConnWarmupPromise = null;
|
|
@@ -28,6 +29,9 @@ class WaIncomingNodeCoordinator {
|
|
|
28
29
|
id: node.attrs.id,
|
|
29
30
|
type: node.attrs.type
|
|
30
31
|
});
|
|
32
|
+
if (node.attrs.offline !== undefined) {
|
|
33
|
+
this.offlineResume.trackOfflineStanza();
|
|
34
|
+
}
|
|
31
35
|
const streamControlResult = (0, parse_1.parseStreamControlNode)(node);
|
|
32
36
|
if (streamControlResult) {
|
|
33
37
|
await this.runtime.handleStreamControlResult(streamControlResult);
|
|
@@ -147,6 +151,16 @@ class WaIncomingNodeCoordinator {
|
|
|
147
151
|
emitUnhandledStanza: runtime.emitUnhandledIncomingNode
|
|
148
152
|
})
|
|
149
153
|
});
|
|
154
|
+
this.registerIncomingHandler({
|
|
155
|
+
tag: constants_1.WA_NODE_TAGS.NOTIFICATION,
|
|
156
|
+
subtype: constants_1.WA_NOTIFICATION_TYPES.REGISTRATION,
|
|
157
|
+
handler: (0, incoming_1.createIncomingRegistrationNotificationHandler)({
|
|
158
|
+
logger: this.logger,
|
|
159
|
+
sendNode: runtime.sendNode,
|
|
160
|
+
emitRegistrationCode: runtime.emitRegistrationCode,
|
|
161
|
+
emitAccountTakeoverNotice: runtime.emitAccountTakeoverNotice
|
|
162
|
+
})
|
|
163
|
+
});
|
|
150
164
|
this.registerIncomingHandler({
|
|
151
165
|
tag: constants_1.WA_NODE_TAGS.NOTIFICATION,
|
|
152
166
|
handler: (0, incoming_1.createIncomingNotificationHandler)({
|
|
@@ -266,13 +280,24 @@ class WaIncomingNodeCoordinator {
|
|
|
266
280
|
return false;
|
|
267
281
|
}
|
|
268
282
|
let handled = false;
|
|
269
|
-
const
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
283
|
+
const children = (0, helpers_1.getNodeChildren)(node);
|
|
284
|
+
for (const child of children) {
|
|
285
|
+
if (INFO_BULLETIN_CHILD_TAGS.has(child.tag)) {
|
|
286
|
+
this.runtime.emitIncomingNotification((0, incoming_1.createInfoBulletinNotificationEvent)(node, child.tag, {
|
|
287
|
+
count: (0, primitives_1.parseOptionalInt)(child.attrs.count),
|
|
288
|
+
message: (0, primitives_1.parseOptionalInt)(child.attrs.message),
|
|
289
|
+
receipt: (0, primitives_1.parseOptionalInt)(child.attrs.receipt),
|
|
290
|
+
notification: (0, primitives_1.parseOptionalInt)(child.attrs.notification),
|
|
291
|
+
t: (0, primitives_1.parseOptionalInt)(child.attrs.t)
|
|
292
|
+
}));
|
|
293
|
+
if (child.tag === 'offline_preview') {
|
|
294
|
+
this.offlineResume.handleOfflinePreview((0, primitives_1.parseOptionalInt)(child.attrs.count) ?? 0);
|
|
295
|
+
}
|
|
296
|
+
if (child.tag === 'offline') {
|
|
297
|
+
this.offlineResume.handleOfflineComplete((0, primitives_1.parseOptionalInt)(child.attrs.count) ?? 0);
|
|
298
|
+
}
|
|
299
|
+
handled = true;
|
|
300
|
+
}
|
|
276
301
|
}
|
|
277
302
|
const edgeRoutingNode = (0, helpers_1.findNodeChild)(node, constants_1.WA_NODE_TAGS.EDGE_ROUTING);
|
|
278
303
|
if (edgeRoutingNode) {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WaMessageDispatchCoordinator = void 0;
|
|
4
4
|
const _crypto_1 = require("../../crypto/index.js");
|
|
5
|
+
const primitives_1 = require("../../crypto/core/primitives");
|
|
5
6
|
const PromiseDedup_1 = require("../../infra/perf/PromiseDedup");
|
|
6
7
|
const _message_1 = require("../../message/index.js");
|
|
7
8
|
const content_1 = require("../../message/content");
|
|
@@ -13,11 +14,10 @@ const reporting_token_1 = require("../../message/reporting-token");
|
|
|
13
14
|
const _proto_1 = require("../../proto.js");
|
|
14
15
|
const constants_1 = require("../../protocol/constants");
|
|
15
16
|
const jid_1 = require("../../protocol/jid");
|
|
16
|
-
const jid_2 = require("../../protocol/jid");
|
|
17
17
|
const binary_1 = require("../../transport/binary");
|
|
18
18
|
const message_1 = require("../../transport/node/builders/message");
|
|
19
19
|
const bytes_1 = require("../../util/bytes");
|
|
20
|
-
const
|
|
20
|
+
const primitives_2 = require("../../util/primitives");
|
|
21
21
|
class WaMessageDispatchCoordinator {
|
|
22
22
|
constructor(options) {
|
|
23
23
|
this.icdcDedup = new PromiseDedup_1.PromiseDedup();
|
|
@@ -34,12 +34,17 @@ class WaMessageDispatchCoordinator {
|
|
|
34
34
|
this.senderKeyManager = options.senderKeyManager;
|
|
35
35
|
this.signalProtocol = options.signalProtocol;
|
|
36
36
|
this.signalStore = options.signalStore;
|
|
37
|
+
this.sessionStore = options.sessionStore;
|
|
38
|
+
this.identityStore = options.identityStore;
|
|
37
39
|
this.deviceListStore = options.deviceListStore;
|
|
40
|
+
this.messageSecretStore = options.messageSecretStore;
|
|
38
41
|
this.getCurrentMeJid = options.getCurrentMeJid;
|
|
39
42
|
this.getCurrentMeLid = options.getCurrentMeLid;
|
|
40
43
|
this.getCurrentSignedIdentity = options.getCurrentSignedIdentity;
|
|
41
44
|
this.resolvePrivacyTokenNode = options.resolvePrivacyTokenNode;
|
|
42
45
|
this.onDirectMessageSent = options.onDirectMessageSent;
|
|
46
|
+
this.getIcdcHashLength = options.getIcdcHashLength;
|
|
47
|
+
this.mobileMessageIdFormat = options.mobileMessageIdFormat ?? false;
|
|
43
48
|
}
|
|
44
49
|
async publishMessageNode(node, options = {}) {
|
|
45
50
|
this.logger.debug('wa client publish message node', {
|
|
@@ -132,6 +137,21 @@ class WaMessageDispatchCoordinator {
|
|
|
132
137
|
this.withResolvedMessageId(options)
|
|
133
138
|
]);
|
|
134
139
|
const messageWithSecret = await (0, _message_1.ensureMessageSecret)(message);
|
|
140
|
+
const rawSecret = messageWithSecret.messageContextInfo?.messageSecret;
|
|
141
|
+
if (rawSecret &&
|
|
142
|
+
rawSecret.length > 0 &&
|
|
143
|
+
sendOptions.id &&
|
|
144
|
+
(0, content_1.needsSecretPersistence)(messageWithSecret)) {
|
|
145
|
+
const meJid = this.getCurrentMeJid() ?? '';
|
|
146
|
+
void this.messageSecretStore
|
|
147
|
+
.set(sendOptions.id, { secret: rawSecret, senderJid: meJid })
|
|
148
|
+
.catch((error) => {
|
|
149
|
+
this.logger.warn('failed to persist outgoing message secret', {
|
|
150
|
+
id: sendOptions.id,
|
|
151
|
+
message: (0, primitives_2.toError)(error).message
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
}
|
|
135
155
|
const meJid = this.getCurrentMeJid();
|
|
136
156
|
const regInfo = meJid ? await this.signalStore.getRegistrationInfo() : null;
|
|
137
157
|
const localPubKey = regInfo?.identityKeyPair.pubKey;
|
|
@@ -378,7 +398,7 @@ class WaMessageDispatchCoordinator {
|
|
|
378
398
|
this.logger.warn('failed to mark sender key distribution targets', {
|
|
379
399
|
groupJid,
|
|
380
400
|
participants: distributedAddresses.length,
|
|
381
|
-
message: (0,
|
|
401
|
+
message: (0, primitives_2.toError)(error).message
|
|
382
402
|
});
|
|
383
403
|
}
|
|
384
404
|
const ackError = result.ack.error;
|
|
@@ -411,14 +431,8 @@ class WaMessageDispatchCoordinator {
|
|
|
411
431
|
}
|
|
412
432
|
resolveGroupAddressingMode(participantUserJids, groupJid) {
|
|
413
433
|
for (let index = 0; index < participantUserJids.length; index += 1) {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
if ((0, jid_1.splitJid)(participantJid).server === 'lid') {
|
|
417
|
-
return 'lid';
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
catch (error) {
|
|
421
|
-
this.logger.trace('ignoring malformed participant jid in addressing mode resolution', { participantJid, message: (0, primitives_1.toError)(error).message });
|
|
434
|
+
if ((0, jid_1.isLidJid)(participantUserJids[index])) {
|
|
435
|
+
return 'lid';
|
|
422
436
|
}
|
|
423
437
|
}
|
|
424
438
|
this.logger.trace('group addressing mode resolved to pn (default)', {
|
|
@@ -437,7 +451,7 @@ class WaMessageDispatchCoordinator {
|
|
|
437
451
|
catch (error) {
|
|
438
452
|
this.logger.trace('ignoring malformed me lid jid', {
|
|
439
453
|
meLid,
|
|
440
|
-
message: (0,
|
|
454
|
+
message: (0, primitives_2.toError)(error).message
|
|
441
455
|
});
|
|
442
456
|
}
|
|
443
457
|
}
|
|
@@ -461,7 +475,7 @@ class WaMessageDispatchCoordinator {
|
|
|
461
475
|
const jid = fanoutDeviceJids[index];
|
|
462
476
|
const address = (0, jid_1.parseSignalAddressFromJid)(jid);
|
|
463
477
|
fanoutAddresses[index] = address;
|
|
464
|
-
fanoutTargetsByAddressKey.set((0,
|
|
478
|
+
fanoutTargetsByAddressKey.set((0, jid_1.signalAddressKey)(address), { jid, address });
|
|
465
479
|
}
|
|
466
480
|
const pendingAddresses = await this.senderKeyManager.filterParticipantsNeedingDistribution(groupJid, senderKeyId, fanoutAddresses);
|
|
467
481
|
if (pendingAddresses.length === 0) {
|
|
@@ -473,7 +487,7 @@ class WaMessageDispatchCoordinator {
|
|
|
473
487
|
const pendingAddressKeys = new Set();
|
|
474
488
|
const pendingTargets = [];
|
|
475
489
|
for (let index = 0; index < pendingAddresses.length; index += 1) {
|
|
476
|
-
const key = (0,
|
|
490
|
+
const key = (0, jid_1.signalAddressKey)(pendingAddresses[index]);
|
|
477
491
|
if (pendingAddressKeys.has(key)) {
|
|
478
492
|
continue;
|
|
479
493
|
}
|
|
@@ -501,7 +515,7 @@ class WaMessageDispatchCoordinator {
|
|
|
501
515
|
prefetchedAvailableTargets = resolvedTargets;
|
|
502
516
|
}
|
|
503
517
|
catch (error) {
|
|
504
|
-
const normalized = (0,
|
|
518
|
+
const normalized = (0, primitives_2.toError)(error);
|
|
505
519
|
if (normalized.message === 'identity mismatch') {
|
|
506
520
|
throw normalized;
|
|
507
521
|
}
|
|
@@ -514,7 +528,7 @@ class WaMessageDispatchCoordinator {
|
|
|
514
528
|
for (let index = 0; index < pendingTargets.length; index += 1) {
|
|
515
529
|
pendingTargetAddresses[index] = pendingTargets[index].address;
|
|
516
530
|
}
|
|
517
|
-
const hasPendingSessions = await this.
|
|
531
|
+
const hasPendingSessions = await this.sessionStore.hasSessions(pendingTargetAddresses);
|
|
518
532
|
const nextAvailableTargets = [];
|
|
519
533
|
for (let index = 0; index < pendingTargets.length; index += 1) {
|
|
520
534
|
if (hasPendingSessions[index]) {
|
|
@@ -672,7 +686,7 @@ class WaMessageDispatchCoordinator {
|
|
|
672
686
|
catch (error) {
|
|
673
687
|
this.logger.warn('privacy token resolution failed', {
|
|
674
688
|
to: recipientUserJid,
|
|
675
|
-
message: (0,
|
|
689
|
+
message: (0, primitives_2.toError)(error).message
|
|
676
690
|
});
|
|
677
691
|
}
|
|
678
692
|
const messageNode = (0, message_1.buildDirectMessageFanoutNode)({
|
|
@@ -722,9 +736,20 @@ class WaMessageDispatchCoordinator {
|
|
|
722
736
|
async generateOutgoingMessageId() {
|
|
723
737
|
try {
|
|
724
738
|
const meUserJid = (0, jid_1.toUserJid)(this.requireCurrentMeJid('sendMessage'));
|
|
725
|
-
const timestampSeconds = Math.floor(Date.now() / 1000);
|
|
726
739
|
const timestampBytes = new Uint8Array(8);
|
|
727
|
-
new DataView(timestampBytes.buffer, timestampBytes.byteOffset, timestampBytes.byteLength)
|
|
740
|
+
const dv = new DataView(timestampBytes.buffer, timestampBytes.byteOffset, timestampBytes.byteLength);
|
|
741
|
+
if (this.mobileMessageIdFormat) {
|
|
742
|
+
dv.setBigUint64(0, BigInt(Date.now()), false);
|
|
743
|
+
const entropy = (0, bytes_1.concatBytes)([
|
|
744
|
+
timestampBytes,
|
|
745
|
+
bytes_1.TEXT_ENCODER.encode(meUserJid),
|
|
746
|
+
await (0, _crypto_1.randomBytesAsync)(16)
|
|
747
|
+
]);
|
|
748
|
+
const digest = (0, primitives_1.md5Bytes)(entropy);
|
|
749
|
+
digest[0] = 0xac;
|
|
750
|
+
return (0, bytes_1.bytesToHex)(digest).toUpperCase();
|
|
751
|
+
}
|
|
752
|
+
dv.setBigUint64(0, BigInt(Math.floor(Date.now() / 1000)), false);
|
|
728
753
|
const entropy = (0, bytes_1.concatBytes)([
|
|
729
754
|
timestampBytes,
|
|
730
755
|
bytes_1.TEXT_ENCODER.encode(meUserJid),
|
|
@@ -734,9 +759,14 @@ class WaMessageDispatchCoordinator {
|
|
|
734
759
|
return `3EB0${(0, bytes_1.bytesToHex)(digest.subarray(0, 9)).toUpperCase()}`;
|
|
735
760
|
}
|
|
736
761
|
catch (error) {
|
|
737
|
-
this.logger.warn('failed to generate
|
|
738
|
-
message: (0,
|
|
762
|
+
this.logger.warn('failed to generate message id, falling back to random', {
|
|
763
|
+
message: (0, primitives_2.toError)(error).message
|
|
739
764
|
});
|
|
765
|
+
if (this.mobileMessageIdFormat) {
|
|
766
|
+
const bytes = await (0, _crypto_1.randomBytesAsync)(16);
|
|
767
|
+
bytes[0] = 0xac;
|
|
768
|
+
return (0, bytes_1.bytesToHex)(bytes).toUpperCase();
|
|
769
|
+
}
|
|
740
770
|
return `3EB0${(0, bytes_1.bytesToHex)(await (0, _crypto_1.randomBytesAsync)(8)).toUpperCase()}`;
|
|
741
771
|
}
|
|
742
772
|
}
|
|
@@ -757,7 +787,7 @@ class WaMessageDispatchCoordinator {
|
|
|
757
787
|
context: input.context,
|
|
758
788
|
id: input.stanzaId,
|
|
759
789
|
remoteJid: input.remoteJid,
|
|
760
|
-
message: (0,
|
|
790
|
+
message: (0, primitives_2.toError)(error).message
|
|
761
791
|
});
|
|
762
792
|
return null;
|
|
763
793
|
}
|
|
@@ -765,7 +795,7 @@ class WaMessageDispatchCoordinator {
|
|
|
765
795
|
getEncodedSignedDeviceIdentity() {
|
|
766
796
|
const signedIdentity = this.getCurrentSignedIdentity();
|
|
767
797
|
if (!signedIdentity) {
|
|
768
|
-
|
|
798
|
+
return undefined;
|
|
769
799
|
}
|
|
770
800
|
return _proto_1.proto.ADVSignedDeviceIdentity.encode(signedIdentity).finish();
|
|
771
801
|
}
|
|
@@ -777,12 +807,12 @@ class WaMessageDispatchCoordinator {
|
|
|
777
807
|
if (!snapshot || snapshot.deviceJids.length === 0) {
|
|
778
808
|
return null;
|
|
779
809
|
}
|
|
780
|
-
return (0, icdc_1.resolveIcdcMeta)(snapshot.deviceJids, this.
|
|
810
|
+
return (0, icdc_1.resolveIcdcMeta)(snapshot.deviceJids, this.identityStore, snapshot.updatedAtMs, localIdentity, this.getIcdcHashLength?.());
|
|
781
811
|
}
|
|
782
812
|
catch (error) {
|
|
783
813
|
this.logger.trace('icdc resolution failed', {
|
|
784
814
|
userJid,
|
|
785
|
-
message: (0,
|
|
815
|
+
message: (0, primitives_2.toError)(error).message
|
|
786
816
|
});
|
|
787
817
|
return null;
|
|
788
818
|
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WaOfflineResumeCoordinator = void 0;
|
|
4
|
+
const offline_1 = require("../../transport/node/builders/offline");
|
|
5
|
+
const primitives_1 = require("../../util/primitives");
|
|
6
|
+
const WA_OFFLINE_RESUME = Object.freeze({
|
|
7
|
+
BATCH_SIZE: 200,
|
|
8
|
+
STANZA_TIMEOUT_MS: 60000
|
|
9
|
+
});
|
|
10
|
+
const WA_OFFLINE_RESUME_STATE = Object.freeze({
|
|
11
|
+
INIT: 'init',
|
|
12
|
+
RESUMING: 'resuming',
|
|
13
|
+
COMPLETE: 'complete'
|
|
14
|
+
});
|
|
15
|
+
class WaOfflineResumeCoordinator {
|
|
16
|
+
constructor(options) {
|
|
17
|
+
this.logger = options.logger;
|
|
18
|
+
this.runtime = options.runtime;
|
|
19
|
+
this.state = WA_OFFLINE_RESUME_STATE.INIT;
|
|
20
|
+
this.totalStanzas = 0;
|
|
21
|
+
this.pendingStanzas = 0;
|
|
22
|
+
this.stanzaTimeout = null;
|
|
23
|
+
}
|
|
24
|
+
get isComplete() {
|
|
25
|
+
return this.state === WA_OFFLINE_RESUME_STATE.COMPLETE;
|
|
26
|
+
}
|
|
27
|
+
get isResuming() {
|
|
28
|
+
return this.state === WA_OFFLINE_RESUME_STATE.RESUMING;
|
|
29
|
+
}
|
|
30
|
+
handleOfflinePreview(stanzaCount) {
|
|
31
|
+
this.clearTimers();
|
|
32
|
+
this.state = WA_OFFLINE_RESUME_STATE.RESUMING;
|
|
33
|
+
this.totalStanzas = stanzaCount;
|
|
34
|
+
this.pendingStanzas = stanzaCount;
|
|
35
|
+
this.logger.info('offline resume started', {
|
|
36
|
+
totalStanzas: stanzaCount
|
|
37
|
+
});
|
|
38
|
+
this.runtime.emitOfflineResume({
|
|
39
|
+
status: 'resuming',
|
|
40
|
+
totalStanzas: stanzaCount,
|
|
41
|
+
remainingStanzas: stanzaCount,
|
|
42
|
+
forced: false
|
|
43
|
+
});
|
|
44
|
+
void this.sendOfflineBatch();
|
|
45
|
+
this.resetStanzaTimeout();
|
|
46
|
+
}
|
|
47
|
+
handleOfflineComplete(serverStanzaCount) {
|
|
48
|
+
if (this.state !== WA_OFFLINE_RESUME_STATE.RESUMING) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
this.completeResume(false, serverStanzaCount);
|
|
52
|
+
}
|
|
53
|
+
trackOfflineStanza() {
|
|
54
|
+
if (this.state !== WA_OFFLINE_RESUME_STATE.RESUMING) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
this.pendingStanzas = Math.max(0, this.pendingStanzas - 1);
|
|
58
|
+
this.resetStanzaTimeout();
|
|
59
|
+
}
|
|
60
|
+
reset() {
|
|
61
|
+
this.clearTimers();
|
|
62
|
+
this.state = WA_OFFLINE_RESUME_STATE.INIT;
|
|
63
|
+
this.totalStanzas = 0;
|
|
64
|
+
this.pendingStanzas = 0;
|
|
65
|
+
}
|
|
66
|
+
completeResume(forced, serverStanzaCount) {
|
|
67
|
+
this.clearTimers();
|
|
68
|
+
this.state = WA_OFFLINE_RESUME_STATE.COMPLETE;
|
|
69
|
+
this.logger.info('offline resume complete', {
|
|
70
|
+
totalStanzas: this.totalStanzas,
|
|
71
|
+
remainingStanzas: this.pendingStanzas,
|
|
72
|
+
serverStanzaCount,
|
|
73
|
+
forced
|
|
74
|
+
});
|
|
75
|
+
this.runtime.emitOfflineResume({
|
|
76
|
+
status: 'complete',
|
|
77
|
+
totalStanzas: this.totalStanzas,
|
|
78
|
+
remainingStanzas: this.pendingStanzas,
|
|
79
|
+
forced
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
async sendOfflineBatch() {
|
|
83
|
+
try {
|
|
84
|
+
await this.runtime.sendNode((0, offline_1.buildOfflineBatchNode)(WA_OFFLINE_RESUME.BATCH_SIZE));
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
this.logger.warn('offline batch request failed', {
|
|
88
|
+
message: (0, primitives_1.toError)(err).message
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
resetStanzaTimeout() {
|
|
93
|
+
if (this.stanzaTimeout !== null) {
|
|
94
|
+
clearTimeout(this.stanzaTimeout);
|
|
95
|
+
}
|
|
96
|
+
this.stanzaTimeout = setTimeout(() => {
|
|
97
|
+
this.stanzaTimeout = null;
|
|
98
|
+
if (this.state === WA_OFFLINE_RESUME_STATE.RESUMING) {
|
|
99
|
+
this.logger.warn('offline resume forced complete due to stanza timeout', {
|
|
100
|
+
totalStanzas: this.totalStanzas,
|
|
101
|
+
remainingStanzas: this.pendingStanzas
|
|
102
|
+
});
|
|
103
|
+
this.completeResume(true);
|
|
104
|
+
}
|
|
105
|
+
}, WA_OFFLINE_RESUME.STANZA_TIMEOUT_MS);
|
|
106
|
+
}
|
|
107
|
+
clearTimers() {
|
|
108
|
+
if (this.stanzaTimeout !== null) {
|
|
109
|
+
clearTimeout(this.stanzaTimeout);
|
|
110
|
+
this.stanzaTimeout = null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.WaOfflineResumeCoordinator = WaOfflineResumeCoordinator;
|
|
@@ -10,6 +10,7 @@ class WaPassiveTasksCoordinator {
|
|
|
10
10
|
constructor(options) {
|
|
11
11
|
this.logger = options.logger;
|
|
12
12
|
this.signalStore = options.signalStore;
|
|
13
|
+
this.preKeyStore = options.preKeyStore;
|
|
13
14
|
this.signalDigestSync = options.signalDigestSync;
|
|
14
15
|
this.signalRotateKey = options.signalRotateKey;
|
|
15
16
|
this.signedPreKeyRotationIntervalMs =
|
|
@@ -17,6 +18,8 @@ class WaPassiveTasksCoordinator {
|
|
|
17
18
|
this.signedPreKeyServerErrorBackoffMs =
|
|
18
19
|
options.signedPreKeyServerErrorBackoffMs ?? constants_2.SIGNAL_SIGNED_PREKEY_SERVER_ERROR_BACKOFF_MS;
|
|
19
20
|
this.runtime = options.runtime;
|
|
21
|
+
this.mobilePrimary = options.mobilePrimary ?? false;
|
|
22
|
+
this.appStateSync = options.appStateSync;
|
|
20
23
|
this.passiveTasksPromise = null;
|
|
21
24
|
}
|
|
22
25
|
startPassiveTasksAfterConnect() {
|
|
@@ -36,7 +39,7 @@ class WaPassiveTasksCoordinator {
|
|
|
36
39
|
}
|
|
37
40
|
async handlePreKeyLowNotification() {
|
|
38
41
|
await Promise.all([
|
|
39
|
-
this.
|
|
42
|
+
this.preKeyStore.setServerHasPreKeys(false),
|
|
40
43
|
this.runtime.persistServerHasPreKeys(false)
|
|
41
44
|
]);
|
|
42
45
|
await this.uploadPreKeysIfMissing(false);
|
|
@@ -57,11 +60,29 @@ class WaPassiveTasksCoordinator {
|
|
|
57
60
|
this.logger.trace('passive connect tasks skipped: session is not registered');
|
|
58
61
|
return;
|
|
59
62
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
this.runtime.syncAbProps();
|
|
64
|
+
if (this.mobilePrimary && this.appStateSync) {
|
|
65
|
+
await this.appStateSync.ensureInitialSyncKey().catch((error) => {
|
|
66
|
+
this.logger.warn('app-state initial key generation failed', {
|
|
67
|
+
message: (0, primitives_1.toError)(error).message
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
await this.runtime.sendPresenceAvailable().catch((error) => {
|
|
72
|
+
this.logger.warn('presence available send failed', {
|
|
73
|
+
message: (0, primitives_1.toError)(error).message
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
const [registrationInfo, signedPreKey, serverHasPreKeys, signedPreKeyRotationTs] = await Promise.all([
|
|
77
|
+
this.signalStore.getRegistrationInfo(),
|
|
78
|
+
this.signalStore.getSignedPreKey(),
|
|
79
|
+
this.preKeyStore.getServerHasPreKeys(),
|
|
80
|
+
this.signalStore.getSignedPreKeyRotationTs()
|
|
81
|
+
]);
|
|
82
|
+
const prefetchedLocalKeyBundle = registrationInfo && signedPreKey ? { registrationInfo, signedPreKey } : null;
|
|
83
|
+
await this.uploadPreKeysIfMissing(serverHasPreKeys, prefetchedLocalKeyBundle);
|
|
63
84
|
await this.validateDigestAndRecoverPreKeys(prefetchedLocalKeyBundle);
|
|
64
|
-
await this.rotateSignedPreKeyIfDue(
|
|
85
|
+
await this.rotateSignedPreKeyIfDue(signedPreKeyRotationTs);
|
|
65
86
|
await this.flushDanglingReceipts();
|
|
66
87
|
}
|
|
67
88
|
async validateDigestAndRecoverPreKeys(prefetchedLocalKeyBundle) {
|
|
@@ -84,7 +105,7 @@ class WaPassiveTasksCoordinator {
|
|
|
84
105
|
return;
|
|
85
106
|
}
|
|
86
107
|
await Promise.all([
|
|
87
|
-
this.
|
|
108
|
+
this.preKeyStore.setServerHasPreKeys(false),
|
|
88
109
|
this.runtime.persistServerHasPreKeys(false)
|
|
89
110
|
]);
|
|
90
111
|
await this.uploadPreKeysIfMissing(false, prefetchedLocalKeyBundle);
|
|
@@ -96,7 +117,7 @@ class WaPassiveTasksCoordinator {
|
|
|
96
117
|
}
|
|
97
118
|
}
|
|
98
119
|
async uploadPreKeysIfMissing(serverHasPreKeysHint, prefetchedLocalKeyBundle) {
|
|
99
|
-
const serverHasPreKeys = serverHasPreKeysHint ?? (await this.
|
|
120
|
+
const serverHasPreKeys = serverHasPreKeysHint ?? (await this.preKeyStore.getServerHasPreKeys());
|
|
100
121
|
if (serverHasPreKeys) {
|
|
101
122
|
this.logger.trace('prekey upload skipped: server already has prekeys');
|
|
102
123
|
return;
|
|
@@ -107,7 +128,7 @@ class WaPassiveTasksCoordinator {
|
|
|
107
128
|
return;
|
|
108
129
|
}
|
|
109
130
|
const { registrationInfo, signedPreKey } = resolvedLocalKeyBundle;
|
|
110
|
-
const preKeys = await this.
|
|
131
|
+
const preKeys = await this.preKeyStore.getOrGenPreKeys(constants_2.SIGNAL_UPLOAD_PREKEYS_COUNT, keygen_1.generatePreKeyPair);
|
|
111
132
|
if (preKeys.length === 0) {
|
|
112
133
|
throw new Error('no prekey available for upload');
|
|
113
134
|
}
|
|
@@ -116,12 +137,12 @@ class WaPassiveTasksCoordinator {
|
|
|
116
137
|
const response = await this.runtime.queryWithContext('prekeys.upload', uploadNode, constants_1.WA_DEFAULTS.IQ_TIMEOUT_MS, {
|
|
117
138
|
count: preKeys.length,
|
|
118
139
|
lastPreKeyId
|
|
119
|
-
});
|
|
140
|
+
}, this.mobilePrimary ? { useSystemId: true } : undefined);
|
|
120
141
|
if (response.attrs.type === 'result') {
|
|
121
142
|
// Mark uploaded key first so the serverHasPreKeys flag never commits ahead of local key progress.
|
|
122
|
-
await this.
|
|
143
|
+
await this.preKeyStore.markKeyAsUploaded(lastPreKeyId);
|
|
123
144
|
await Promise.all([
|
|
124
|
-
this.
|
|
145
|
+
this.preKeyStore.setServerHasPreKeys(true),
|
|
125
146
|
this.runtime.persistServerHasPreKeys(true)
|
|
126
147
|
]);
|
|
127
148
|
this.logger.info('uploaded prekeys to server', {
|
|
@@ -168,18 +189,15 @@ class WaPassiveTasksCoordinator {
|
|
|
168
189
|
});
|
|
169
190
|
}
|
|
170
191
|
}
|
|
171
|
-
|
|
172
|
-
const
|
|
192
|
+
async resolveLocalKeyBundleFromStore() {
|
|
193
|
+
const [registrationInfo, signedPreKey] = await Promise.all([
|
|
194
|
+
this.signalStore.getRegistrationInfo(),
|
|
195
|
+
this.signalStore.getSignedPreKey()
|
|
196
|
+
]);
|
|
173
197
|
if (!registrationInfo || !signedPreKey) {
|
|
174
198
|
return null;
|
|
175
199
|
}
|
|
176
|
-
return {
|
|
177
|
-
registrationInfo,
|
|
178
|
-
signedPreKey
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
async resolveLocalKeyBundleFromStore() {
|
|
182
|
-
return this.resolveLocalKeyBundle(await this.signalStore.getSignalMeta());
|
|
200
|
+
return { registrationInfo, signedPreKey };
|
|
183
201
|
}
|
|
184
202
|
resolveRotationTimestamp(nowMs, errorCode) {
|
|
185
203
|
if (errorCode !== undefined && errorCode >= 500) {
|
|
@@ -175,7 +175,9 @@ function createProfileCoordinator(options) {
|
|
|
175
175
|
},
|
|
176
176
|
setStatus: async (text) => {
|
|
177
177
|
const node = (0, profile_1.buildSetStatusIq)(text);
|
|
178
|
-
const result = await queryWithContext('profile.setStatus', node
|
|
178
|
+
const result = await queryWithContext('profile.setStatus', node, undefined, undefined, {
|
|
179
|
+
useSystemId: true
|
|
180
|
+
});
|
|
179
181
|
(0, query_1.assertIqResult)(result, 'profile.setStatus');
|
|
180
182
|
},
|
|
181
183
|
getProfiles: async (jids) => {
|
|
@@ -40,6 +40,8 @@ class WaRetryCoordinator {
|
|
|
40
40
|
this.retryStore = options.retryStore;
|
|
41
41
|
this.retryTtlMs = this.retryStore.getTtlMs?.() ?? constants_2.RETRY_OUTBOUND_TTL_MS;
|
|
42
42
|
this.signalStore = options.signalStore;
|
|
43
|
+
this.preKeyStore = options.preKeyStore;
|
|
44
|
+
this.sessionStore = options.sessionStore;
|
|
43
45
|
this.senderKeyStore = options.senderKeyStore;
|
|
44
46
|
this.signalProtocol = options.signalProtocol;
|
|
45
47
|
this.signalDeviceSync = options.signalDeviceSync;
|
|
@@ -341,13 +343,13 @@ class WaRetryCoordinator {
|
|
|
341
343
|
async buildRetryKeysSection(identity) {
|
|
342
344
|
const [signedPreKey, preKey] = await Promise.all([
|
|
343
345
|
this.signalStore.getSignedPreKey(),
|
|
344
|
-
this.
|
|
346
|
+
this.preKeyStore.getOrGenSinglePreKey(keygen_1.generatePreKeyPair)
|
|
345
347
|
]);
|
|
346
348
|
if (!signedPreKey) {
|
|
347
349
|
this.logger.warn('retry keys section skipped: signed prekey unavailable');
|
|
348
350
|
return undefined;
|
|
349
351
|
}
|
|
350
|
-
await this.
|
|
352
|
+
await this.preKeyStore.markKeyAsUploaded(preKey.keyId);
|
|
351
353
|
const signedIdentity = this.getCurrentSignedIdentity();
|
|
352
354
|
return {
|
|
353
355
|
identity,
|
|
@@ -368,11 +370,11 @@ class WaRetryCoordinator {
|
|
|
368
370
|
async updateLocalSessionFromRetryRequest(request, requesterJid, requesterAddress, requesterNormalizedDeviceJid) {
|
|
369
371
|
const [, currentSession] = await Promise.all([
|
|
370
372
|
this.markRetryRequesterSenderKeyAsStale(request, requesterJid, requesterAddress),
|
|
371
|
-
this.
|
|
373
|
+
this.sessionStore.getSession(requesterAddress)
|
|
372
374
|
]);
|
|
373
375
|
const regIdMismatch = !!currentSession && request.regId > 0 && currentSession.remote.regId !== request.regId;
|
|
374
376
|
if (regIdMismatch && !request.keyBundle) {
|
|
375
|
-
await this.
|
|
377
|
+
await this.sessionStore.deleteSession(requesterAddress);
|
|
376
378
|
}
|
|
377
379
|
if (request.keyBundle) {
|
|
378
380
|
if (!request.keyBundle.key || !request.keyBundle.skey.signature) {
|
|
@@ -387,7 +389,7 @@ class WaRetryCoordinator {
|
|
|
387
389
|
remoteRetryCount: request.retryCount,
|
|
388
390
|
...getRemoteRetryReasonLogFields(request.retryReason)
|
|
389
391
|
});
|
|
390
|
-
await this.
|
|
392
|
+
await this.sessionStore.deleteSession(requesterAddress);
|
|
391
393
|
return false;
|
|
392
394
|
}
|
|
393
395
|
if (regIdMismatch) {
|
|
@@ -398,12 +400,12 @@ class WaRetryCoordinator {
|
|
|
398
400
|
remoteRetryCount: request.retryCount,
|
|
399
401
|
...getRemoteRetryReasonLogFields(request.retryReason)
|
|
400
402
|
});
|
|
401
|
-
await this.
|
|
403
|
+
await this.sessionStore.deleteSession(requesterAddress);
|
|
402
404
|
return false;
|
|
403
405
|
}
|
|
404
406
|
}
|
|
405
407
|
else if (regIdMismatch) {
|
|
406
|
-
await this.
|
|
408
|
+
await this.sessionStore.deleteSession(requesterAddress);
|
|
407
409
|
}
|
|
408
410
|
await this.signalProtocol.establishOutgoingSession(requesterAddress, {
|
|
409
411
|
regId: request.regId,
|
|
@@ -435,7 +437,7 @@ class WaRetryCoordinator {
|
|
|
435
437
|
if (request.retryCount < 2) {
|
|
436
438
|
return true;
|
|
437
439
|
}
|
|
438
|
-
const currentSession = await this.
|
|
440
|
+
const currentSession = await this.sessionStore.getSession(requesterAddress);
|
|
439
441
|
const sessionBaseKey = currentSession?.aliceBaseKey ?? null;
|
|
440
442
|
if (!sessionBaseKey) {
|
|
441
443
|
return true;
|
|
@@ -449,7 +451,7 @@ class WaRetryCoordinator {
|
|
|
449
451
|
if (!saved || !(0, bytes_1.uint8Equal)(saved.baseKey, sessionBaseKey)) {
|
|
450
452
|
return true;
|
|
451
453
|
}
|
|
452
|
-
await this.
|
|
454
|
+
await this.sessionStore.deleteSession(requesterAddress);
|
|
453
455
|
this.logger.info('retry request forcing session refresh due to repeated base key', {
|
|
454
456
|
id: request.stanzaId,
|
|
455
457
|
originalMsgId: request.originalMsgId,
|