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
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SignalProtocol = void 0;
|
|
4
4
|
const _crypto_1 = require("../../crypto/index.js");
|
|
5
5
|
const ConsoleLogger_1 = require("../../infra/log/ConsoleLogger");
|
|
6
|
+
const StoreLock_1 = require("../../infra/perf/StoreLock");
|
|
6
7
|
const constants_1 = require("../constants");
|
|
7
8
|
const SignalRatchet_1 = require("../session/SignalRatchet");
|
|
8
9
|
const SignalSerializer_1 = require("../session/SignalSerializer");
|
|
@@ -11,26 +12,37 @@ const bytes_1 = require("../../util/bytes");
|
|
|
11
12
|
function signalAddressMapKey(address) {
|
|
12
13
|
return `${address.user}\u0001${address.server ?? ''}\u0001${address.device}`;
|
|
13
14
|
}
|
|
15
|
+
function signalAddressLockKey(address) {
|
|
16
|
+
return `signal:${signalAddressMapKey(address)}`;
|
|
17
|
+
}
|
|
14
18
|
class SignalProtocol {
|
|
15
19
|
constructor(store, logger = new ConsoleLogger_1.ConsoleLogger('info')) {
|
|
16
20
|
this.store = store;
|
|
17
21
|
this.logger = logger;
|
|
22
|
+
this.sessionMutationLock = new StoreLock_1.StoreLock();
|
|
18
23
|
}
|
|
19
|
-
async
|
|
20
|
-
return this.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
async establishOutgoingSession(address, remoteBundle, options = {}) {
|
|
25
|
+
return this.runWithAddressLock(address, async () => {
|
|
26
|
+
if (options.reuseExisting) {
|
|
27
|
+
const existing = await this.store.getSession(address);
|
|
28
|
+
if (existing) {
|
|
29
|
+
const remoteIdentity = (0, _crypto_1.toSerializedPubKey)(remoteBundle.identity);
|
|
30
|
+
if (!(0, bytes_1.uint8Equal)(existing.remote.pubKey, remoteIdentity)) {
|
|
31
|
+
throw new Error('identity mismatch');
|
|
32
|
+
}
|
|
33
|
+
return existing;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const [local, localOneTimeBase] = await Promise.all([
|
|
37
|
+
(0, SignalSession_1.requireLocalIdentity)(this.store),
|
|
38
|
+
(0, SignalSession_1.generateSerializedKeyPair)()
|
|
39
|
+
]);
|
|
40
|
+
const session = await (0, SignalSession_1.initiateSessionOutgoing)(local, remoteBundle, localOneTimeBase);
|
|
41
|
+
// Keep writes ordered: a stored session without matching remote identity causes false mismatch checks.
|
|
42
|
+
await this.store.setRemoteIdentity(address, session.remote.pubKey);
|
|
43
|
+
await this.store.setSession(address, session);
|
|
44
|
+
return session;
|
|
45
|
+
});
|
|
34
46
|
}
|
|
35
47
|
async encryptMessage(address, plaintext, expectedIdentity) {
|
|
36
48
|
const [encrypted] = await this.encryptMessagesBatch([
|
|
@@ -38,77 +50,140 @@ class SignalProtocol {
|
|
|
38
50
|
]);
|
|
39
51
|
return encrypted;
|
|
40
52
|
}
|
|
41
|
-
async encryptMessagesBatch(requests) {
|
|
53
|
+
async encryptMessagesBatch(requests, prefetchedSessions) {
|
|
42
54
|
if (requests.length === 0) {
|
|
43
55
|
return [];
|
|
44
56
|
}
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
const lockKeySet = new Set();
|
|
58
|
+
for (let i = 0; i < requests.length; i += 1)
|
|
59
|
+
lockKeySet.add(signalAddressLockKey(requests[i].address));
|
|
60
|
+
const lockKeys = [...lockKeySet];
|
|
61
|
+
return this.sessionMutationLock.runMany(lockKeys, async () => {
|
|
62
|
+
const prefetchedByAddress = new Map();
|
|
63
|
+
if (prefetchedSessions && prefetchedSessions.length > 0) {
|
|
64
|
+
for (let index = 0; index < prefetchedSessions.length; index += 1) {
|
|
65
|
+
const entry = prefetchedSessions[index];
|
|
66
|
+
prefetchedByAddress.set(signalAddressMapKey(entry.address), entry.session);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const uniqueAddressKeys = new Array(requests.length);
|
|
70
|
+
const uniqueAddresses = new Array(requests.length);
|
|
71
|
+
let uniqueAddressCount = 0;
|
|
72
|
+
for (let index = 0; index < requests.length; index += 1) {
|
|
73
|
+
const address = requests[index].address;
|
|
74
|
+
const addressKey = signalAddressMapKey(address);
|
|
75
|
+
let isDuplicate = false;
|
|
76
|
+
for (let dedupIndex = 0; dedupIndex < uniqueAddressCount; dedupIndex += 1) {
|
|
77
|
+
if (uniqueAddressKeys[dedupIndex] === addressKey) {
|
|
78
|
+
isDuplicate = true;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (isDuplicate) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
uniqueAddressKeys[uniqueAddressCount] = addressKey;
|
|
86
|
+
uniqueAddresses[uniqueAddressCount] = address;
|
|
87
|
+
uniqueAddressCount += 1;
|
|
58
88
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
89
|
+
uniqueAddressKeys.length = uniqueAddressCount;
|
|
90
|
+
uniqueAddresses.length = uniqueAddressCount;
|
|
91
|
+
const currentSessions = await this.store.getSessionsBatch(uniqueAddresses);
|
|
92
|
+
const latestSessionByAddress = new Map();
|
|
93
|
+
for (let index = 0; index < uniqueAddressCount; index += 1) {
|
|
94
|
+
const addressKey = uniqueAddressKeys[index];
|
|
95
|
+
const current = currentSessions[index];
|
|
96
|
+
if (current) {
|
|
97
|
+
latestSessionByAddress.set(addressKey, current);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const prefetched = prefetchedByAddress.get(addressKey);
|
|
101
|
+
if (prefetched) {
|
|
102
|
+
latestSessionByAddress.set(addressKey, prefetched);
|
|
103
|
+
}
|
|
62
104
|
}
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
105
|
+
const sessionUpdatesByAddress = new Map();
|
|
106
|
+
const identityUpdatesByAddress = new Map();
|
|
107
|
+
const results = new Array(requests.length);
|
|
108
|
+
for (let index = 0; index < requests.length; index += 1) {
|
|
109
|
+
const request = requests[index];
|
|
110
|
+
const address = request.address;
|
|
111
|
+
const addressKey = signalAddressMapKey(address);
|
|
112
|
+
const session = latestSessionByAddress.get(addressKey);
|
|
113
|
+
if (!session) {
|
|
114
|
+
throw new Error('signal session not found');
|
|
115
|
+
}
|
|
116
|
+
if (request.expectedIdentity &&
|
|
117
|
+
!(0, bytes_1.uint8Equal)((0, _crypto_1.toSerializedPubKey)(request.expectedIdentity), session.remote.pubKey)) {
|
|
118
|
+
throw new Error('identity mismatch');
|
|
119
|
+
}
|
|
120
|
+
const [updatedSession, encrypted] = await (0, SignalRatchet_1.encryptMsg)(session, request.plaintext);
|
|
121
|
+
latestSessionByAddress.set(addressKey, updatedSession);
|
|
122
|
+
sessionUpdatesByAddress.set(addressKey, {
|
|
71
123
|
address,
|
|
72
|
-
|
|
124
|
+
session: updatedSession
|
|
73
125
|
});
|
|
126
|
+
if (!(0, bytes_1.uint8Equal)(updatedSession.remote.pubKey, session.remote.pubKey)) {
|
|
127
|
+
identityUpdatesByAddress.set(addressKey, {
|
|
128
|
+
address,
|
|
129
|
+
identityKey: updatedSession.remote.pubKey
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
results[index] = {
|
|
133
|
+
...encrypted,
|
|
134
|
+
baseKey: updatedSession.aliceBaseKey
|
|
135
|
+
};
|
|
74
136
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
137
|
+
// Persist remote identities first when needed so session writes never commit ahead of identity data.
|
|
138
|
+
if (identityUpdatesByAddress.size > 0) {
|
|
139
|
+
const identityUpdates = new Array(identityUpdatesByAddress.size);
|
|
140
|
+
let identityIndex = 0;
|
|
141
|
+
for (const update of identityUpdatesByAddress.values()) {
|
|
142
|
+
identityUpdates[identityIndex] = update;
|
|
143
|
+
identityIndex += 1;
|
|
144
|
+
}
|
|
145
|
+
await this.store.setRemoteIdentities(identityUpdates);
|
|
146
|
+
}
|
|
147
|
+
const sessionUpdates = new Array(sessionUpdatesByAddress.size);
|
|
148
|
+
let sessionIndex = 0;
|
|
149
|
+
for (const update of sessionUpdatesByAddress.values()) {
|
|
150
|
+
sessionUpdates[sessionIndex] = update;
|
|
151
|
+
sessionIndex += 1;
|
|
152
|
+
}
|
|
153
|
+
await this.store.setSessionsBatch(sessionUpdates);
|
|
154
|
+
return results;
|
|
155
|
+
});
|
|
85
156
|
}
|
|
86
157
|
async decryptMessage(address, envelope) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
158
|
+
return this.runWithAddressLock(address, async () => {
|
|
159
|
+
const currentSession = await this.store.getSession(address);
|
|
160
|
+
let outcome;
|
|
161
|
+
if (envelope.type === 'pkmsg') {
|
|
162
|
+
const parsedPk = (0, SignalSerializer_1.deserializePkMsg)(envelope.ciphertext);
|
|
163
|
+
outcome = await this.decryptPkMsg(currentSession, parsedPk);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
const parsed = (0, SignalSerializer_1.deserializeMsg)(envelope.ciphertext);
|
|
167
|
+
outcome = await (0, SignalRatchet_1.decryptMsg)(currentSession, parsed, (error, previousSessionIndex) => {
|
|
168
|
+
this.logger.debug('signal decrypt fallback session failed', {
|
|
169
|
+
previousSessionIndex,
|
|
170
|
+
message: error.message
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
const nextRemoteIdentity = outcome.newSessionInfo?.newIdentity ?? outcome.updatedSession.remote.pubKey;
|
|
175
|
+
const identityChanged = !currentSession || !(0, bytes_1.uint8Equal)(currentSession.remote.pubKey, nextRemoteIdentity);
|
|
176
|
+
// Keep writes ordered for consistency with resolver identity checks.
|
|
177
|
+
if (identityChanged) {
|
|
178
|
+
await this.store.setRemoteIdentity(address, nextRemoteIdentity);
|
|
179
|
+
}
|
|
180
|
+
await this.store.setSession(address, outcome.updatedSession);
|
|
181
|
+
return outcome.plaintext;
|
|
110
182
|
});
|
|
111
183
|
}
|
|
184
|
+
runWithAddressLock(address, task) {
|
|
185
|
+
return this.sessionMutationLock.run(signalAddressLockKey(address), task);
|
|
186
|
+
}
|
|
112
187
|
async decryptPkMsg(currentSession, parsed) {
|
|
113
188
|
const matchingSession = (0, SignalSession_1.findMatchingSession)(currentSession, parsed.sessionBaseKey);
|
|
114
189
|
if (matchingSession) {
|
|
@@ -144,6 +219,7 @@ class SignalProtocol {
|
|
|
144
219
|
}
|
|
145
220
|
: incoming;
|
|
146
221
|
const [updatedSession, plaintext] = await (0, SignalRatchet_1.decryptMsgFromSession)(baseSession, parsed);
|
|
222
|
+
// Only consume one-time prekeys after successful decrypt/session materialization.
|
|
147
223
|
if (parsed.localOneTimeKeyId !== null && parsed.localOneTimeKeyId !== undefined) {
|
|
148
224
|
await this.store.consumePreKeyById(parsed.localOneTimeKeyId);
|
|
149
225
|
}
|
|
@@ -2,32 +2,43 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createSignalSessionResolver = createSignalSessionResolver;
|
|
4
4
|
const keys_1 = require("../../crypto/core/keys");
|
|
5
|
+
const PromiseDedup_1 = require("../../infra/perf/PromiseDedup");
|
|
5
6
|
const jid_1 = require("../../protocol/jid");
|
|
6
7
|
const bytes_1 = require("../../util/bytes");
|
|
7
8
|
const primitives_1 = require("../../util/primitives");
|
|
8
9
|
function createSignalSessionResolver(options) {
|
|
9
10
|
const { signalProtocol, signalStore, signalIdentitySync, signalSessionSync, logger } = options;
|
|
10
|
-
const
|
|
11
|
+
const dedup = new PromiseDedup_1.PromiseDedup();
|
|
12
|
+
const ensureSessionInternal = async (address, jid, expectedIdentity, reasonIdentity = false, prefetchedBundle) => {
|
|
11
13
|
const expectedSerializedIdentity = expectedIdentity
|
|
12
14
|
? (0, keys_1.toSerializedPubKey)(expectedIdentity)
|
|
13
15
|
: null;
|
|
14
16
|
if (reasonIdentity) {
|
|
15
17
|
await signalIdentitySync.syncIdentityKeys([jid]);
|
|
16
18
|
}
|
|
17
|
-
if (await
|
|
19
|
+
if (await signalStore.hasSession(address)) {
|
|
18
20
|
if (expectedSerializedIdentity) {
|
|
19
21
|
const storedIdentity = await signalStore.getRemoteIdentity(address);
|
|
20
22
|
if (!storedIdentity || !(0, bytes_1.uint8Equal)(storedIdentity, expectedSerializedIdentity)) {
|
|
21
23
|
throw new Error('identity mismatch');
|
|
22
24
|
}
|
|
23
25
|
}
|
|
24
|
-
return;
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
let fetched;
|
|
29
|
+
if (prefetchedBundle) {
|
|
30
|
+
fetched = {
|
|
31
|
+
jid,
|
|
32
|
+
bundle: prefetchedBundle
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
logger.info('signal session missing, fetching remote key bundle', { jid });
|
|
37
|
+
fetched = await signalSessionSync.fetchKeyBundle({
|
|
38
|
+
jid,
|
|
39
|
+
reasonIdentity
|
|
40
|
+
});
|
|
25
41
|
}
|
|
26
|
-
logger.info('signal session missing, fetching remote key bundle', { jid });
|
|
27
|
-
const fetched = await signalSessionSync.fetchKeyBundle({
|
|
28
|
-
jid,
|
|
29
|
-
reasonIdentity
|
|
30
|
-
});
|
|
31
42
|
const remoteIdentity = (0, keys_1.toSerializedPubKey)(fetched.bundle.identity);
|
|
32
43
|
if (reasonIdentity) {
|
|
33
44
|
const storedIdentity = await signalStore.getRemoteIdentity(address);
|
|
@@ -38,35 +49,49 @@ function createSignalSessionResolver(options) {
|
|
|
38
49
|
if (expectedSerializedIdentity && !(0, bytes_1.uint8Equal)(remoteIdentity, expectedSerializedIdentity)) {
|
|
39
50
|
throw new Error('identity mismatch');
|
|
40
51
|
}
|
|
41
|
-
await signalProtocol.establishOutgoingSession(address, fetched.bundle
|
|
52
|
+
const session = await signalProtocol.establishOutgoingSession(address, fetched.bundle, {
|
|
53
|
+
reuseExisting: true
|
|
54
|
+
});
|
|
42
55
|
logger.info('signal session synchronized', {
|
|
43
56
|
jid,
|
|
44
57
|
regId: fetched.bundle.regId,
|
|
45
58
|
hasOneTimeKey: fetched.bundle.oneTimeKey !== undefined
|
|
46
59
|
});
|
|
60
|
+
return session;
|
|
61
|
+
};
|
|
62
|
+
const ensureSessionWithDedup = (address, jid, expectedIdentity, reasonIdentity = false, prefetchedBundle) => {
|
|
63
|
+
const expectedIdentityKey = expectedIdentity ? (0, bytes_1.bytesToHex)(expectedIdentity) : 'none';
|
|
64
|
+
const dedupKey = `signalSession:${(0, jid_1.signalAddressKey)(address)}:${reasonIdentity ? '1' : '0'}:${expectedIdentityKey}`;
|
|
65
|
+
return dedup.run(dedupKey, () => ensureSessionInternal(address, jid, expectedIdentity, reasonIdentity, prefetchedBundle));
|
|
47
66
|
};
|
|
67
|
+
const ensureSession = (address, jid, expectedIdentity, reasonIdentity = false) => ensureSessionWithDedup(address, jid, expectedIdentity, reasonIdentity).then(() => { });
|
|
48
68
|
const ensureSessionsBatch = async (targetJids, expectedIdentityByJid) => {
|
|
49
69
|
const seenTargetJids = new Set();
|
|
50
|
-
const normalizedTargetJids =
|
|
51
|
-
const normalizedTargetAddresses =
|
|
70
|
+
const normalizedTargetJids = new Array(targetJids.length);
|
|
71
|
+
const normalizedTargetAddresses = new Array(targetJids.length);
|
|
72
|
+
let normalizedTargetCount = 0;
|
|
52
73
|
for (let index = 0; index < targetJids.length; index += 1) {
|
|
53
74
|
const jid = (0, jid_1.normalizeDeviceJid)(targetJids[index]);
|
|
54
75
|
if (seenTargetJids.has(jid)) {
|
|
55
76
|
continue;
|
|
56
77
|
}
|
|
57
78
|
seenTargetJids.add(jid);
|
|
58
|
-
normalizedTargetJids
|
|
59
|
-
normalizedTargetAddresses
|
|
79
|
+
normalizedTargetJids[normalizedTargetCount] = jid;
|
|
80
|
+
normalizedTargetAddresses[normalizedTargetCount] = (0, jid_1.parseSignalAddressFromJid)(jid);
|
|
81
|
+
normalizedTargetCount += 1;
|
|
60
82
|
}
|
|
61
|
-
if (
|
|
62
|
-
return;
|
|
83
|
+
if (normalizedTargetCount === 0) {
|
|
84
|
+
return [];
|
|
63
85
|
}
|
|
86
|
+
normalizedTargetJids.length = normalizedTargetCount;
|
|
87
|
+
normalizedTargetAddresses.length = normalizedTargetCount;
|
|
64
88
|
const normalizedExpectedIdentityByJid = expectedIdentityByJid && expectedIdentityByJid.size > 0
|
|
65
89
|
? new Map()
|
|
66
90
|
: undefined;
|
|
67
91
|
if (normalizedExpectedIdentityByJid && expectedIdentityByJid) {
|
|
68
92
|
for (const [jid, identity] of expectedIdentityByJid.entries()) {
|
|
69
93
|
try {
|
|
94
|
+
(0, keys_1.toSerializedPubKey)(identity);
|
|
70
95
|
normalizedExpectedIdentityByJid.set((0, jid_1.normalizeDeviceJid)(jid), identity);
|
|
71
96
|
}
|
|
72
97
|
catch (error) {
|
|
@@ -74,113 +99,123 @@ function createSignalSessionResolver(options) {
|
|
|
74
99
|
}
|
|
75
100
|
}
|
|
76
101
|
}
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
102
|
+
const resolvedByIndex = (await signalStore.getSessionsBatch(normalizedTargetAddresses));
|
|
103
|
+
const collectResolvedTargets = () => {
|
|
104
|
+
const resolvedTargets = new Array(normalizedTargetJids.length);
|
|
105
|
+
let resolvedTargetCount = 0;
|
|
81
106
|
for (let index = 0; index < normalizedTargetJids.length; index += 1) {
|
|
82
|
-
|
|
107
|
+
const session = resolvedByIndex[index];
|
|
108
|
+
if (!session) {
|
|
83
109
|
continue;
|
|
84
110
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
111
|
+
resolvedTargets[resolvedTargetCount] = {
|
|
112
|
+
jid: normalizedTargetJids[index],
|
|
113
|
+
address: normalizedTargetAddresses[index],
|
|
114
|
+
session
|
|
115
|
+
};
|
|
116
|
+
resolvedTargetCount += 1;
|
|
91
117
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
118
|
+
resolvedTargets.length = resolvedTargetCount;
|
|
119
|
+
return resolvedTargets;
|
|
120
|
+
};
|
|
121
|
+
const missingIndices = [];
|
|
122
|
+
for (let index = 0; index < normalizedTargetJids.length; index += 1) {
|
|
123
|
+
const session = resolvedByIndex[index];
|
|
124
|
+
const expectedIdentity = normalizedExpectedIdentityByJid?.get(normalizedTargetJids[index]);
|
|
125
|
+
if (session && expectedIdentity) {
|
|
126
|
+
if (!(0, bytes_1.uint8Equal)(session.remote.pubKey, (0, keys_1.toSerializedPubKey)(expectedIdentity))) {
|
|
97
127
|
throw new Error('identity mismatch');
|
|
98
128
|
}
|
|
99
129
|
}
|
|
100
|
-
|
|
101
|
-
const missingIndices = [];
|
|
102
|
-
for (let index = 0; index < normalizedTargetJids.length; index += 1) {
|
|
103
|
-
if (!hasSessions[index]) {
|
|
130
|
+
if (!session) {
|
|
104
131
|
missingIndices.push(index);
|
|
105
132
|
}
|
|
106
133
|
}
|
|
107
134
|
if (missingIndices.length === 0) {
|
|
108
|
-
return;
|
|
135
|
+
return collectResolvedTargets();
|
|
136
|
+
}
|
|
137
|
+
const batchRequest = new Array(missingIndices.length);
|
|
138
|
+
for (let index = 0; index < missingIndices.length; index += 1) {
|
|
139
|
+
batchRequest[index] = { jid: normalizedTargetJids[missingIndices[index]] };
|
|
109
140
|
}
|
|
141
|
+
let batchResults;
|
|
110
142
|
try {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
establishedIndices.push(targetIndex);
|
|
134
|
-
establishPromises.push(signalProtocol
|
|
135
|
-
.establishOutgoingSession(normalizedTargetAddresses[targetIndex], result.bundle)
|
|
136
|
-
.then(() => {
|
|
137
|
-
logger.debug('signal session synchronized from batch key fetch', {
|
|
138
|
-
jid: targetJid,
|
|
139
|
-
regId: result.bundle.regId,
|
|
140
|
-
hasOneTimeKey: result.bundle.oneTimeKey !== undefined
|
|
141
|
-
});
|
|
142
|
-
}));
|
|
143
|
+
batchResults = await signalSessionSync.fetchKeyBundles(batchRequest);
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
logger.warn('signal batch key fetch failed', {
|
|
147
|
+
requested: missingIndices.length,
|
|
148
|
+
message: (0, primitives_1.toError)(error).message
|
|
149
|
+
});
|
|
150
|
+
return collectResolvedTargets();
|
|
151
|
+
}
|
|
152
|
+
const ensuredTargetIndices = new Array(missingIndices.length);
|
|
153
|
+
const ensurePromises = new Array(missingIndices.length);
|
|
154
|
+
let ensureCount = 0;
|
|
155
|
+
for (let index = 0; index < missingIndices.length; index += 1) {
|
|
156
|
+
const targetIndex = missingIndices[index];
|
|
157
|
+
const targetJid = normalizedTargetJids[targetIndex];
|
|
158
|
+
const batchResult = batchResults[index];
|
|
159
|
+
if (!batchResult?.bundle) {
|
|
160
|
+
logger.warn('signal batch key fetch returned target without bundle', {
|
|
161
|
+
jid: targetJid,
|
|
162
|
+
message: batchResult?.errorText ?? 'missing key bundle user in response'
|
|
163
|
+
});
|
|
164
|
+
continue;
|
|
143
165
|
}
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
166
|
+
const expectedIdentity = normalizedExpectedIdentityByJid?.get(targetJid);
|
|
167
|
+
ensuredTargetIndices[ensureCount] = targetIndex;
|
|
168
|
+
ensurePromises[ensureCount] = ensureSessionWithDedup(normalizedTargetAddresses[targetIndex], targetJid, expectedIdentity, false, batchResult.bundle);
|
|
169
|
+
ensureCount += 1;
|
|
170
|
+
}
|
|
171
|
+
if (ensureCount === 0) {
|
|
172
|
+
return collectResolvedTargets();
|
|
173
|
+
}
|
|
174
|
+
ensuredTargetIndices.length = ensureCount;
|
|
175
|
+
ensurePromises.length = ensureCount;
|
|
176
|
+
const ensureResults = await Promise.allSettled(ensurePromises);
|
|
177
|
+
const fallbackIndices = [];
|
|
178
|
+
for (let index = 0; index < ensuredTargetIndices.length; index += 1) {
|
|
179
|
+
const targetIndex = ensuredTargetIndices[index];
|
|
180
|
+
const ensureResult = ensureResults[index];
|
|
181
|
+
if (ensureResult.status === 'rejected') {
|
|
182
|
+
const normalized = (0, primitives_1.toError)(ensureResult.reason);
|
|
183
|
+
if (normalized.message === 'identity mismatch') {
|
|
184
|
+
throw normalized;
|
|
153
185
|
}
|
|
154
|
-
|
|
186
|
+
logger.warn('signal session ensure failed during batch resolution', {
|
|
187
|
+
jid: normalizedTargetJids[targetIndex],
|
|
188
|
+
message: normalized.message
|
|
189
|
+
});
|
|
190
|
+
continue;
|
|
155
191
|
}
|
|
156
|
-
|
|
157
|
-
|
|
192
|
+
const session = ensureResult.value;
|
|
193
|
+
if (session) {
|
|
194
|
+
resolvedByIndex[targetIndex] = session;
|
|
158
195
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
fallbackTargets: fallbackIndices.length
|
|
162
|
-
});
|
|
163
|
-
for (let index = 0; index < fallbackIndices.length; index += 1) {
|
|
164
|
-
const targetIndex = fallbackIndices[index];
|
|
165
|
-
const jid = normalizedTargetJids[targetIndex];
|
|
166
|
-
await ensureSession(normalizedTargetAddresses[targetIndex], jid, normalizedExpectedIdentityByJid?.get(jid));
|
|
196
|
+
else {
|
|
197
|
+
fallbackIndices.push(targetIndex);
|
|
167
198
|
}
|
|
168
199
|
}
|
|
169
|
-
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
200
|
+
if (fallbackIndices.length > 0) {
|
|
201
|
+
const fallbackAddresses = new Array(fallbackIndices.length);
|
|
202
|
+
for (let i = 0; i < fallbackIndices.length; i++) {
|
|
203
|
+
fallbackAddresses[i] = normalizedTargetAddresses[fallbackIndices[i]];
|
|
173
204
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
205
|
+
const fallbackSessions = await signalStore.getSessionsBatch(fallbackAddresses);
|
|
206
|
+
for (let i = 0; i < fallbackIndices.length; i++) {
|
|
207
|
+
const session = fallbackSessions[i];
|
|
208
|
+
if (session) {
|
|
209
|
+
resolvedByIndex[fallbackIndices[i]] = session;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
logger.warn('signal session ensure completed without persisted session', {
|
|
213
|
+
jid: normalizedTargetJids[fallbackIndices[i]]
|
|
214
|
+
});
|
|
215
|
+
}
|
|
182
216
|
}
|
|
183
217
|
}
|
|
218
|
+
return collectResolvedTargets();
|
|
184
219
|
};
|
|
185
220
|
return {
|
|
186
221
|
ensureSession,
|