zapo-js 0.1.1 → 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 +20 -4
- package/dist/appstate/WaAppStateCrypto.js +19 -26
- package/dist/appstate/WaAppStateSyncClient.js +293 -181
- package/dist/appstate/WaAppStateSyncResponseParser.js +16 -5
- package/dist/appstate/constants.js +4 -3
- package/dist/appstate/{store/sqlite.js → encoding.js} +13 -8
- package/dist/appstate/index.js +8 -6
- package/dist/appstate/utils.js +9 -34
- package/dist/auth/WaAuthClient.js +43 -61
- package/dist/auth/flow/WaAuthCredentialsFlow.js +22 -15
- package/dist/auth/index.js +1 -8
- package/dist/auth/pairing/WaPairingCodeCrypto.js +6 -4
- package/dist/auth/pairing/WaPairingFlow.js +34 -26
- package/dist/auth/pairing/WaQrFlow.js +37 -24
- package/dist/client/WaClient.js +275 -324
- package/dist/client/WaClientFactory.js +500 -133
- package/dist/client/connection/WaConnectionManager.js +301 -0
- package/dist/client/connection/WaKeyShareCoordinator.js +63 -0
- package/dist/client/connection/WaReceiptQueue.js +51 -0
- package/dist/client/coordinators/WaAppStateMutationCoordinator.js +471 -0
- package/dist/client/coordinators/WaBusinessCoordinator.js +241 -0
- package/dist/client/coordinators/WaGroupCoordinator.js +30 -16
- package/dist/client/coordinators/WaIncomingNodeCoordinator.js +21 -27
- package/dist/client/coordinators/WaMessageDispatchCoordinator.js +439 -701
- 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 +242 -57
- package/dist/client/coordinators/WaStreamControlCoordinator.js +18 -11
- package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +166 -0
- package/dist/client/dirty.js +74 -48
- package/dist/client/events/chat.js +4 -3
- package/dist/client/events/devices.js +72 -0
- package/dist/client/events/group.js +62 -47
- package/dist/client/events/identity.js +22 -0
- package/dist/client/events/privacy-token.js +39 -0
- package/dist/client/history-sync.js +94 -63
- package/dist/client/incoming.js +60 -27
- package/dist/client/mailbox.js +24 -23
- package/dist/client/messages.js +107 -31
- package/dist/client/messaging/fanout.js +199 -0
- package/dist/client/messaging/key-protocol.js +130 -0
- package/dist/client/messaging/participants.js +193 -0
- 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/hkdf.js +3 -8
- package/dist/crypto/core/index.js +2 -5
- package/dist/crypto/core/keys.js +6 -7
- package/dist/crypto/core/nonce.js +2 -0
- package/dist/crypto/core/primitives.js +12 -23
- package/dist/crypto/core/random.js +26 -23
- package/dist/crypto/curves/Ed25519.js +7 -8
- package/dist/crypto/curves/X25519.js +38 -22
- package/dist/crypto/index.js +1 -3
- 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 +7 -14
- package/dist/esm/appstate/WaAppStateSyncClient.js +284 -172
- package/dist/esm/appstate/WaAppStateSyncResponseParser.js +17 -6
- package/dist/esm/appstate/constants.js +3 -2
- 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 +8 -30
- package/dist/esm/auth/WaAuthClient.js +43 -61
- package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +22 -15
- package/dist/esm/auth/index.js +0 -3
- package/dist/esm/auth/pairing/WaPairingCodeCrypto.js +6 -4
- package/dist/esm/auth/pairing/WaPairingFlow.js +28 -20
- package/dist/esm/auth/pairing/WaQrFlow.js +37 -24
- package/dist/esm/client/WaClient.js +275 -324
- package/dist/esm/client/WaClientFactory.js +501 -134
- package/dist/esm/client/connection/WaConnectionManager.js +297 -0
- package/dist/esm/client/connection/WaKeyShareCoordinator.js +59 -0
- package/dist/esm/client/connection/WaReceiptQueue.js +47 -0
- package/dist/esm/client/coordinators/WaAppStateMutationCoordinator.js +467 -0
- package/dist/esm/client/coordinators/WaBusinessCoordinator.js +238 -0
- package/dist/esm/client/coordinators/WaGroupCoordinator.js +23 -9
- package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +21 -27
- package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +443 -705
- 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 +244 -59
- package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +19 -12
- package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +162 -0
- package/dist/esm/client/dirty.js +69 -43
- package/dist/esm/client/events/chat.js +4 -3
- package/dist/esm/client/events/devices.js +68 -0
- package/dist/esm/client/events/group.js +53 -39
- 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 +91 -60
- package/dist/esm/client/incoming.js +61 -28
- package/dist/esm/client/mailbox.js +24 -23
- package/dist/esm/client/messages.js +108 -32
- package/dist/esm/client/messaging/fanout.js +196 -0
- package/dist/esm/client/messaging/key-protocol.js +127 -0
- package/dist/esm/client/messaging/participants.js +190 -0
- 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/hkdf.js +3 -8
- package/dist/esm/crypto/core/index.js +2 -3
- package/dist/esm/crypto/core/keys.js +3 -4
- package/dist/esm/crypto/core/nonce.js +2 -0
- package/dist/esm/crypto/core/primitives.js +12 -22
- package/dist/esm/crypto/core/random.js +25 -23
- package/dist/esm/crypto/curves/Ed25519.js +4 -5
- package/dist/esm/crypto/curves/X25519.js +35 -19
- package/dist/esm/crypto/index.js +0 -1
- 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/log/ConsoleLogger.js +18 -17
- package/dist/esm/infra/log/PinoLogger.js +15 -9
- package/dist/esm/infra/log/types.js +11 -1
- package/dist/esm/infra/perf/BackgroundQueue.js +478 -0
- package/dist/esm/infra/perf/BoundedTaskQueue.js +16 -18
- 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 +96 -16
- package/dist/esm/media/WaMediaTransferClient.js +251 -91
- package/dist/esm/media/conn.js +10 -6
- package/dist/esm/media/constants.js +6 -2
- package/dist/esm/message/WaMessageClient.js +30 -32
- package/dist/esm/message/ack.js +6 -6
- package/dist/esm/message/addon-crypto.js +59 -0
- package/dist/esm/message/content.js +195 -9
- package/dist/esm/message/icdc.js +76 -0
- package/dist/esm/message/incoming.js +129 -122
- package/dist/esm/message/index.js +2 -0
- package/dist/esm/message/phash.js +3 -1
- package/dist/esm/message/reporting-token.js +425 -0
- package/dist/esm/message/use-case-secret.js +49 -0
- package/dist/esm/protocol/appstate.js +27 -0
- package/dist/esm/protocol/browser.js +10 -18
- package/dist/esm/protocol/constants.js +6 -3
- package/dist/esm/protocol/defaults.js +6 -0
- package/dist/esm/protocol/index.js +2 -11
- package/dist/esm/protocol/jid.js +133 -52
- package/dist/esm/protocol/media.js +3 -3
- package/dist/esm/protocol/message.js +61 -1
- package/dist/esm/protocol/nodes.js +4 -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/protocol/usync.js +11 -0
- package/dist/esm/retry/codec.js +216 -0
- package/dist/esm/retry/constants.js +1 -1
- package/dist/esm/retry/index.js +3 -2
- package/dist/esm/retry/parse.js +88 -86
- package/dist/esm/retry/replay.js +54 -51
- package/dist/esm/retry/tracker.js +94 -0
- package/dist/esm/signal/api/SignalDeviceSyncApi.js +276 -92
- package/dist/esm/signal/api/SignalDigestSyncApi.js +17 -8
- package/dist/esm/signal/api/SignalIdentitySyncApi.js +67 -37
- package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +86 -67
- package/dist/esm/signal/api/SignalRotateKeyApi.js +4 -2
- package/dist/esm/signal/api/SignalSessionSyncApi.js +36 -34
- 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 +13 -9
- package/dist/esm/signal/{store/sqlite.js → encoding.js} +93 -60
- package/dist/esm/signal/group/SenderKeyChain.js +28 -23
- package/dist/esm/signal/group/SenderKeyCodec.js +5 -6
- package/dist/esm/signal/group/SenderKeyManager.js +144 -115
- package/dist/esm/signal/index.js +2 -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 +164 -53
- package/dist/esm/signal/session/SignalRatchet.js +24 -15
- package/dist/esm/signal/session/SignalSession.js +14 -9
- package/dist/esm/signal/session/resolver.js +221 -0
- package/dist/esm/store/contracts/privacy-token.store.js +1 -0
- package/dist/esm/store/createStore.js +100 -188
- 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 +4 -7
- package/dist/esm/store/providers/memory/appstate.store.js +38 -16
- package/dist/esm/store/providers/memory/contact.store.js +5 -0
- package/dist/esm/store/providers/memory/device-list.store.js +12 -34
- package/dist/esm/store/providers/memory/message.store.js +11 -5
- package/dist/esm/store/providers/memory/participants.store.js +1 -8
- 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 +11 -8
- package/dist/esm/store/providers/memory/signal.store.js +47 -18
- package/dist/esm/store/providers/memory/thread.store.js +5 -0
- package/dist/esm/transport/WaComms.js +28 -24
- package/dist/esm/transport/WaWebSocket.js +115 -18
- package/dist/esm/transport/binary/constants.js +0 -30
- package/dist/esm/transport/binary/decoder.js +8 -8
- package/dist/esm/transport/binary/encoder.js +10 -9
- package/dist/esm/transport/binary/index.js +0 -1
- package/dist/esm/transport/index.js +1 -0
- package/dist/esm/transport/keepalive/WaKeepAlive.js +2 -8
- package/dist/esm/transport/node/WaNodeOrchestrator.js +25 -21
- package/dist/esm/transport/node/WaNodeTransport.js +0 -3
- package/dist/esm/transport/node/builders/{accountSync.js → account-sync.js} +16 -36
- 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 +7 -3
- package/dist/esm/transport/node/builders/message.js +63 -230
- package/dist/esm/transport/node/builders/pairing.js +2 -27
- 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 +45 -0
- package/dist/esm/transport/node/helpers.js +125 -5
- package/dist/esm/transport/node/usync.js +5 -0
- package/dist/esm/transport/node/xml.js +35 -14
- package/dist/esm/transport/noise/WaClientPayload.js +10 -10
- package/dist/esm/transport/noise/WaFrameCodec.js +48 -33
- package/dist/esm/transport/noise/WaNoiseCert.js +4 -7
- package/dist/esm/transport/noise/WaNoiseSession.js +77 -29
- package/dist/esm/transport/noise/WaNoiseSocket.js +8 -4
- package/dist/esm/transport/proxy.js +27 -0
- package/dist/esm/transport/stream/parse.js +17 -48
- package/dist/esm/util/bytes.js +67 -45
- package/dist/esm/util/coercion.js +6 -14
- package/dist/esm/util/index.js +5 -0
- package/dist/esm/util/primitives.js +40 -14
- package/dist/index.js +7 -1
- package/dist/infra/log/ConsoleLogger.js +18 -17
- package/dist/infra/log/PinoLogger.js +15 -9
- package/dist/infra/log/types.js +12 -0
- package/dist/infra/perf/BackgroundQueue.js +482 -0
- package/dist/infra/perf/BoundedTaskQueue.js +16 -18
- 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 +95 -15
- package/dist/media/WaMediaTransferClient.js +284 -91
- package/dist/media/conn.js +10 -6
- package/dist/media/constants.js +6 -2
- package/dist/message/WaMessageClient.js +31 -33
- package/dist/message/ack.js +6 -6
- package/dist/message/addon-crypto.js +65 -0
- package/dist/message/content.js +198 -9
- package/dist/message/icdc.js +81 -0
- package/dist/message/incoming.js +127 -120
- package/dist/message/index.js +2 -0
- package/dist/message/phash.js +3 -1
- package/dist/message/reporting-token.js +429 -0
- package/dist/message/use-case-secret.js +55 -0
- package/dist/protocol/appstate.js +28 -1
- package/dist/protocol/browser.js +10 -18
- package/dist/protocol/constants.js +26 -1
- package/dist/protocol/defaults.js +6 -0
- package/dist/protocol/index.js +23 -42
- package/dist/protocol/jid.js +140 -52
- package/dist/protocol/media.js +3 -3
- package/dist/protocol/message.js +62 -2
- package/dist/protocol/nodes.js +4 -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/protocol/usync.js +14 -0
- package/dist/retry/codec.js +220 -0
- package/dist/retry/constants.js +1 -1
- package/dist/retry/index.js +7 -5
- package/dist/retry/parse.js +88 -85
- package/dist/retry/replay.js +52 -49
- package/dist/retry/tracker.js +97 -0
- package/dist/signal/api/SignalDeviceSyncApi.js +273 -89
- package/dist/signal/api/SignalDigestSyncApi.js +17 -8
- package/dist/signal/api/SignalIdentitySyncApi.js +66 -36
- package/dist/signal/api/SignalMissingPreKeysSyncApi.js +82 -63
- package/dist/signal/api/SignalRotateKeyApi.js +4 -2
- package/dist/signal/api/SignalSessionSyncApi.js +36 -34
- package/dist/signal/api/result-map.js +13 -0
- package/dist/signal/constants.js +1 -5
- package/dist/signal/crypto/WaAdvSignature.js +11 -7
- package/dist/signal/{store/sqlite.js → encoding.js} +94 -61
- package/dist/signal/group/SenderKeyChain.js +27 -22
- package/dist/signal/group/SenderKeyCodec.js +5 -6
- package/dist/signal/group/SenderKeyManager.js +144 -115
- package/dist/signal/index.js +15 -1
- package/dist/signal/registration/keygen.js +6 -2
- package/dist/signal/registration/utils.js +1 -0
- package/dist/signal/session/SignalProtocol.js +164 -53
- package/dist/signal/session/SignalRatchet.js +24 -15
- package/dist/signal/session/SignalSession.js +14 -9
- package/dist/signal/session/resolver.js +224 -0
- package/dist/store/contracts/privacy-token.store.js +2 -0
- package/dist/store/createStore.js +100 -188
- 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 +4 -7
- package/dist/store/providers/memory/appstate.store.js +36 -14
- package/dist/store/providers/memory/contact.store.js +5 -0
- package/dist/store/providers/memory/device-list.store.js +12 -34
- package/dist/store/providers/memory/message.store.js +11 -5
- package/dist/store/providers/memory/participants.store.js +1 -8
- 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 +14 -11
- package/dist/store/providers/memory/signal.store.js +54 -25
- package/dist/store/providers/memory/thread.store.js +5 -0
- package/dist/transport/WaComms.js +30 -26
- package/dist/transport/WaWebSocket.js +148 -18
- package/dist/transport/binary/constants.js +1 -31
- package/dist/transport/binary/decoder.js +8 -8
- package/dist/transport/binary/encoder.js +10 -9
- package/dist/transport/binary/index.js +0 -4
- package/dist/transport/index.js +7 -1
- package/dist/transport/keepalive/WaKeepAlive.js +1 -7
- package/dist/transport/node/WaNodeOrchestrator.js +25 -21
- package/dist/transport/node/WaNodeTransport.js +0 -3
- package/dist/transport/node/builders/{accountSync.js → account-sync.js} +15 -35
- 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 +29 -17
- package/dist/transport/node/builders/message.js +64 -236
- package/dist/transport/node/builders/pairing.js +2 -29
- 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 +49 -0
- package/dist/transport/node/helpers.js +131 -4
- package/dist/transport/node/usync.js +8 -0
- package/dist/transport/node/xml.js +35 -14
- package/dist/transport/noise/WaClientPayload.js +13 -13
- package/dist/transport/noise/WaFrameCodec.js +47 -32
- package/dist/transport/noise/WaNoiseCert.js +5 -8
- package/dist/transport/noise/WaNoiseSession.js +77 -29
- package/dist/transport/noise/WaNoiseSocket.js +8 -4
- package/dist/transport/proxy.js +34 -0
- package/dist/transport/stream/parse.js +20 -52
- package/dist/types/appstate/WaAppStateCrypto.d.ts +0 -1
- package/dist/types/appstate/WaAppStateSyncClient.d.ts +5 -2
- package/dist/types/appstate/constants.d.ts +1 -0
- 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 -3
- package/dist/types/auth/WaAuthClient.d.ts +10 -12
- package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +1 -1
- package/dist/types/auth/index.d.ts +0 -4
- package/dist/types/auth/pairing/WaQrFlow.d.ts +1 -1
- package/dist/types/auth/types.d.ts +7 -9
- package/dist/types/client/WaClient.d.ts +42 -25
- package/dist/types/client/WaClientFactory.d.ts +33 -26
- package/dist/types/client/connection/WaConnectionManager.d.ts +66 -0
- package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +14 -0
- package/dist/types/client/connection/WaReceiptQueue.d.ts +13 -0
- package/dist/types/client/coordinators/WaAppStateMutationCoordinator.d.ts +46 -0
- package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +57 -0
- package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +3 -2
- package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +29 -38
- 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 +8 -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/dirty.d.ts +1 -0
- package/dist/types/client/events/devices.d.ts +20 -0
- package/dist/types/client/events/group.d.ts +2 -1
- 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/messaging/fanout.d.ts +14 -0
- package/dist/types/client/messaging/key-protocol.d.ts +18 -0
- package/dist/types/client/messaging/participants.d.ts +13 -0
- 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 +75 -4
- package/dist/types/crypto/core/hkdf.d.ts +0 -6
- package/dist/types/crypto/core/index.d.ts +2 -3
- 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 +2 -7
- package/dist/types/crypto/index.d.ts +0 -1
- 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/log/ConsoleLogger.d.ts +2 -1
- package/dist/types/infra/log/PinoLogger.d.ts +1 -1
- package/dist/types/infra/log/types.d.ts +1 -0
- package/dist/types/infra/perf/BackgroundQueue.d.ts +58 -0
- package/dist/types/infra/perf/BoundedTaskQueue.d.ts +1 -1
- 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 +16 -15
- 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 +15 -2
- package/dist/types/message/addon-crypto.d.ts +25 -0
- package/dist/types/message/content.d.ts +8 -0
- package/dist/types/message/icdc.d.ts +13 -0
- package/dist/types/message/index.d.ts +2 -0
- package/dist/types/message/reporting-token.d.ts +18 -0
- package/dist/types/message/types.d.ts +45 -6
- package/dist/types/message/use-case-secret.d.ts +20 -0
- package/dist/types/protocol/appstate.d.ts +47 -0
- package/dist/types/protocol/constants.d.ts +8 -3
- package/dist/types/protocol/defaults.d.ts +6 -0
- package/dist/types/protocol/index.d.ts +2 -11
- package/dist/types/protocol/jid.d.ts +22 -5
- package/dist/types/protocol/message.d.ts +60 -0
- package/dist/types/protocol/nodes.d.ts +4 -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/protocol/usync.d.ts +11 -0
- package/dist/types/retry/codec.d.ts +3 -0
- package/dist/types/retry/index.d.ts +4 -3
- package/dist/types/retry/parse.d.ts +5 -2
- package/dist/types/retry/replay.d.ts +0 -4
- package/dist/types/retry/tracker.d.ts +20 -0
- package/dist/types/retry/types.d.ts +10 -4
- package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +15 -2
- 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/SenderKeyCodec.d.ts +4 -6
- package/dist/types/signal/group/SenderKeyManager.d.ts +10 -5
- package/dist/types/signal/index.d.ts +3 -0
- package/dist/types/signal/session/SignalProtocol.d.ts +19 -4
- package/dist/types/signal/session/resolver.d.ts +22 -0
- package/dist/types/store/contracts/appstate.store.d.ts +4 -1
- package/dist/types/store/contracts/contact.store.d.ts +1 -0
- package/dist/types/store/contracts/device-list.store.d.ts +0 -3
- package/dist/types/store/contracts/message.store.d.ts +1 -0
- package/dist/types/store/contracts/participants.store.d.ts +0 -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/sender-key.store.d.ts +0 -1
- package/dist/types/store/contracts/signal.store.d.ts +13 -0
- package/dist/types/store/contracts/thread.store.d.ts +1 -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 +3 -1
- package/dist/types/store/providers/memory/contact.store.d.ts +1 -0
- package/dist/types/store/providers/memory/device-list.store.d.ts +0 -3
- package/dist/types/store/providers/memory/message.store.d.ts +1 -0
- package/dist/types/store/providers/memory/participants.store.d.ts +0 -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/sender-key.store.d.ts +0 -1
- package/dist/types/store/providers/memory/signal.store.d.ts +8 -1
- package/dist/types/store/providers/memory/thread.store.d.ts +1 -0
- package/dist/types/store/types.d.ts +49 -58
- package/dist/types/transport/WaWebSocket.d.ts +3 -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/index.d.ts +2 -1
- package/dist/types/transport/keepalive/WaKeepAlive.d.ts +0 -1
- package/dist/types/transport/node/WaNodeOrchestrator.d.ts +3 -4
- package/dist/types/transport/node/WaNodeTransport.d.ts +0 -9
- 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/group.d.ts +4 -6
- package/dist/types/transport/node/builders/index.d.ts +7 -3
- package/dist/types/transport/node/builders/message.d.ts +20 -30
- 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 +2 -5
- package/dist/types/transport/node/builders/usync.d.ts +21 -0
- package/dist/types/transport/node/helpers.d.ts +13 -0
- package/dist/types/transport/node/usync.d.ts +2 -0
- package/dist/types/transport/noise/WaFrameCodec.d.ts +3 -0
- package/dist/types/transport/noise/WaNoiseSession.d.ts +4 -2
- package/dist/types/transport/noise/WaNoiseSocket.d.ts +4 -2
- package/dist/types/transport/proxy.d.ts +6 -0
- package/dist/types/transport/stream/parse.d.ts +0 -1
- package/dist/types/transport/types.d.ts +18 -1
- package/dist/types/util/bytes.d.ts +5 -0
- package/dist/types/util/index.d.ts +5 -0
- package/dist/types/util/primitives.d.ts +2 -0
- package/dist/util/bytes.js +72 -46
- package/dist/util/coercion.js +6 -14
- package/dist/util/index.js +23 -0
- package/dist/util/primitives.js +42 -14
- package/package.json +52 -9
- package/proto/index.js +1 -1
- package/dist/crypto/core/constants.js +0 -4
- package/dist/crypto/core/encoding.js +0 -29
- package/dist/esm/crypto/core/constants.js +0 -1
- package/dist/esm/crypto/core/encoding.js +0 -25
- package/dist/esm/retry/outbound.js +0 -83
- package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +0 -37
- package/dist/esm/store/providers/sqlite/appstate.store.js +0 -169
- package/dist/esm/store/providers/sqlite/auth.store.js +0 -176
- package/dist/esm/store/providers/sqlite/connection.js +0 -240
- package/dist/esm/store/providers/sqlite/contact.store.js +0 -61
- package/dist/esm/store/providers/sqlite/device-list.store.js +0 -155
- package/dist/esm/store/providers/sqlite/message.store.js +0 -119
- package/dist/esm/store/providers/sqlite/migrations.js +0 -347
- package/dist/esm/store/providers/sqlite/participants.store.js +0 -85
- package/dist/esm/store/providers/sqlite/retry.store.js +0 -144
- package/dist/esm/store/providers/sqlite/sender-key.store.js +0 -203
- package/dist/esm/store/providers/sqlite/signal.store.js +0 -353
- package/dist/esm/store/providers/sqlite/thread.store.js +0 -72
- package/dist/esm/util/base64.js +0 -18
- package/dist/esm/util/signal-address.js +0 -5
- package/dist/retry/outbound.js +0 -88
- package/dist/store/providers/sqlite/BaseSqliteStore.js +0 -41
- package/dist/store/providers/sqlite/appstate.store.js +0 -173
- package/dist/store/providers/sqlite/auth.store.js +0 -180
- package/dist/store/providers/sqlite/connection.js +0 -276
- package/dist/store/providers/sqlite/contact.store.js +0 -65
- package/dist/store/providers/sqlite/device-list.store.js +0 -159
- package/dist/store/providers/sqlite/message.store.js +0 -123
- package/dist/store/providers/sqlite/migrations.js +0 -350
- package/dist/store/providers/sqlite/participants.store.js +0 -89
- package/dist/store/providers/sqlite/retry.store.js +0 -148
- package/dist/store/providers/sqlite/sender-key.store.js +0 -207
- package/dist/store/providers/sqlite/signal.store.js +0 -357
- package/dist/store/providers/sqlite/thread.store.js +0 -76
- package/dist/types/appstate/store/sqlite.d.ts +0 -21
- package/dist/types/crypto/core/constants.d.ts +0 -1
- package/dist/types/crypto/core/encoding.d.ts +0 -11
- 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 -15
- 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 -10
- package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -18
- package/dist/types/store/providers/sqlite/message.store.d.ts +0 -11
- package/dist/types/store/providers/sqlite/migrations.d.ts +0 -3
- package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -13
- package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -16
- package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -25
- package/dist/types/store/providers/sqlite/signal.store.d.ts +0 -46
- package/dist/types/store/providers/sqlite/thread.store.d.ts +0 -11
- package/dist/types/util/base64.d.ts +0 -4
- package/dist/types/util/signal-address.d.ts +0 -2
- package/dist/util/base64.js +0 -24
- package/dist/util/signal-address.js +0 -8
- /package/dist/types/transport/node/builders/{accountSync.d.ts → account-sync.d.ts} +0 -0
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WaAppStateSyncClient = exports.WaAppStateMissingKeyError = void 0;
|
|
4
4
|
const constants_1 = require("./constants");
|
|
5
|
-
const utils_1 = require("./utils");
|
|
6
5
|
const WaAppStateCrypto_1 = require("./WaAppStateCrypto");
|
|
7
6
|
const WaAppStateSyncResponseParser_1 = require("./WaAppStateSyncResponseParser");
|
|
8
7
|
const _proto_1 = require("../proto.js");
|
|
9
8
|
const constants_2 = require("../protocol/constants");
|
|
10
|
-
const
|
|
9
|
+
const jid_1 = require("../protocol/jid");
|
|
10
|
+
const query_1 = require("../transport/node/query");
|
|
11
11
|
const bytes_1 = require("../util/bytes");
|
|
12
|
+
const bytes_2 = require("../util/bytes");
|
|
12
13
|
const primitives_1 = require("../util/primitives");
|
|
13
14
|
class WaAppStateMissingKeyError extends Error {
|
|
14
15
|
constructor(message, keyId, collection) {
|
|
@@ -24,6 +25,7 @@ class WaAppStateSyncClient {
|
|
|
24
25
|
this.logger = options.logger;
|
|
25
26
|
this.query = options.query;
|
|
26
27
|
this.store = options.store;
|
|
28
|
+
this.getCurrentMeJid = options.getCurrentMeJid;
|
|
27
29
|
this.hostDomain = options.hostDomain ?? constants_2.WA_DEFAULTS.HOST_DOMAIN;
|
|
28
30
|
this.defaultTimeoutMs = options.defaultTimeoutMs ?? constants_2.WA_DEFAULTS.APP_STATE_SYNC_TIMEOUT_MS;
|
|
29
31
|
this.onMissingKeys = options.onMissingKeys;
|
|
@@ -47,14 +49,14 @@ class WaAppStateSyncClient {
|
|
|
47
49
|
async importSyncKeyShare(share) {
|
|
48
50
|
const keys = [];
|
|
49
51
|
for (const item of share.keys ?? []) {
|
|
50
|
-
const keyId = (0,
|
|
52
|
+
const keyId = (0, bytes_1.decodeProtoBytes)(item.keyId?.keyId, 'appStateSyncKeyShare.keys[].keyId.keyId');
|
|
51
53
|
if (!item.keyData?.keyData) {
|
|
52
54
|
this.logger.debug('app-state sync key share entry missing key data', {
|
|
53
|
-
keyId: (0,
|
|
55
|
+
keyId: (0, bytes_2.bytesToHex)(keyId)
|
|
54
56
|
});
|
|
55
57
|
continue;
|
|
56
58
|
}
|
|
57
|
-
const keyData = (0,
|
|
59
|
+
const keyData = (0, bytes_1.decodeProtoBytes)(item.keyData?.keyData, 'appStateSyncKeyShare.keys[].keyData.keyData');
|
|
58
60
|
keys.push({
|
|
59
61
|
keyId,
|
|
60
62
|
keyData,
|
|
@@ -93,6 +95,10 @@ class WaAppStateSyncClient {
|
|
|
93
95
|
...new Set(options.collections ?? constants_1.APP_STATE_DEFAULT_COLLECTIONS)
|
|
94
96
|
];
|
|
95
97
|
try {
|
|
98
|
+
const initialCollectionStates = await this.store.getCollectionStates(collections);
|
|
99
|
+
for (let index = 0; index < collections.length; index += 1) {
|
|
100
|
+
context.collections.set(collections[index], initialCollectionStates[index]);
|
|
101
|
+
}
|
|
96
102
|
this.logger.info('app-state sync start', {
|
|
97
103
|
collections: collections.length,
|
|
98
104
|
pendingMutations: options.pendingMutations?.length ?? 0
|
|
@@ -162,36 +168,18 @@ class WaAppStateSyncClient {
|
|
|
162
168
|
}
|
|
163
169
|
}
|
|
164
170
|
async syncCollectionsRound(collections, pendingByCollection, options) {
|
|
165
|
-
const
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
options,
|
|
173
|
-
outgoingContexts: prepared.outgoingContexts,
|
|
174
|
-
skippedUploadCollections: prepared.skippedUploadCollections
|
|
175
|
-
})));
|
|
176
|
-
return {
|
|
177
|
-
results: collectionOutcomes.map((entry) => entry.result),
|
|
178
|
-
collectionsToRefetch: collectionOutcomes
|
|
179
|
-
.filter((entry) => entry.shouldRefetch)
|
|
180
|
-
.map((entry) => entry.collection),
|
|
181
|
-
stateChanged: collectionOutcomes.some((entry) => entry.stateChanged),
|
|
182
|
-
missingKeyIds: this.collectDistinctMissingKeyIds(collectionOutcomes
|
|
183
|
-
.map((entry) => entry.missingKeyId)
|
|
184
|
-
.filter((value) => value !== null)),
|
|
185
|
-
blockedCollections: collectionOutcomes
|
|
186
|
-
.filter((entry) => entry.result.state === constants_2.WA_APP_STATE_COLLECTION_STATES.BLOCKED)
|
|
187
|
-
.map((entry) => entry.collection)
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
async prepareSyncRoundRequest(collections, pendingByCollection) {
|
|
191
|
-
const requests = await Promise.all(collections.map((collection) => this.buildCollectionSyncRequest(collection, pendingByCollection)));
|
|
171
|
+
const activeSyncKey = await this.store.getActiveSyncKey();
|
|
172
|
+
const requestPromises = new Array(collections.length);
|
|
173
|
+
for (let index = 0; index < collections.length; index += 1) {
|
|
174
|
+
requestPromises[index] = this.buildCollectionSyncRequest(collections[index], pendingByCollection, activeSyncKey);
|
|
175
|
+
}
|
|
176
|
+
const requests = await Promise.all(requestPromises);
|
|
177
|
+
const collectionNodes = new Array(requests.length);
|
|
192
178
|
const outgoingContexts = new Map();
|
|
193
179
|
const skippedUploadCollections = new Set();
|
|
194
|
-
for (
|
|
180
|
+
for (let index = 0; index < requests.length; index += 1) {
|
|
181
|
+
const request = requests[index];
|
|
182
|
+
collectionNodes[index] = request.node;
|
|
195
183
|
if (request.outgoingContext) {
|
|
196
184
|
outgoingContexts.set(request.collection, request.outgoingContext);
|
|
197
185
|
}
|
|
@@ -199,26 +187,62 @@ class WaAppStateSyncClient {
|
|
|
199
187
|
skippedUploadCollections.add(request.collection);
|
|
200
188
|
}
|
|
201
189
|
}
|
|
190
|
+
const iqNode = this.buildSyncIqNode(collectionNodes);
|
|
191
|
+
const payloadByCollection = await this.fetchSyncPayloadByCollection(iqNode, options.timeoutMs ?? this.defaultTimeoutMs);
|
|
192
|
+
const collectionOutcomePromises = new Array(collections.length);
|
|
193
|
+
for (let index = 0; index < collections.length; index += 1) {
|
|
194
|
+
collectionOutcomePromises[index] = this.processCollectionRound({
|
|
195
|
+
collection: collections[index],
|
|
196
|
+
payloadByCollection,
|
|
197
|
+
pendingByCollection,
|
|
198
|
+
options,
|
|
199
|
+
outgoingContexts,
|
|
200
|
+
skippedUploadCollections
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
const collectionOutcomes = await Promise.all(collectionOutcomePromises);
|
|
204
|
+
const results = [];
|
|
205
|
+
const collectionsToRefetch = [];
|
|
206
|
+
const blockedCollections = [];
|
|
207
|
+
const missingKeyIds = [];
|
|
208
|
+
const missingKeyIdHexes = new Set();
|
|
209
|
+
let stateChanged = false;
|
|
210
|
+
for (let index = 0; index < collectionOutcomes.length; index += 1) {
|
|
211
|
+
const entry = collectionOutcomes[index];
|
|
212
|
+
results.push(entry.result);
|
|
213
|
+
if (entry.shouldRefetch) {
|
|
214
|
+
collectionsToRefetch.push(entry.collection);
|
|
215
|
+
}
|
|
216
|
+
if (entry.stateChanged) {
|
|
217
|
+
stateChanged = true;
|
|
218
|
+
}
|
|
219
|
+
if (entry.result.state === constants_2.WA_APP_STATE_COLLECTION_STATES.BLOCKED) {
|
|
220
|
+
blockedCollections.push(entry.collection);
|
|
221
|
+
}
|
|
222
|
+
if (entry.missingKeyId) {
|
|
223
|
+
const keyHex = (0, bytes_2.bytesToHex)(entry.missingKeyId);
|
|
224
|
+
if (!missingKeyIdHexes.has(keyHex)) {
|
|
225
|
+
missingKeyIdHexes.add(keyHex);
|
|
226
|
+
missingKeyIds.push(entry.missingKeyId);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
202
230
|
return {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
231
|
+
results,
|
|
232
|
+
collectionsToRefetch,
|
|
233
|
+
stateChanged,
|
|
234
|
+
missingKeyIds,
|
|
235
|
+
blockedCollections
|
|
206
236
|
};
|
|
207
237
|
}
|
|
208
|
-
async buildCollectionSyncRequest(collection, pendingByCollection) {
|
|
238
|
+
async buildCollectionSyncRequest(collection, pendingByCollection, activeSyncKey) {
|
|
209
239
|
const collectionState = await this.getCollectionState(collection);
|
|
210
|
-
const hasPersistedState = collectionState.
|
|
211
|
-
collectionState.indexValueMap.size > 0 ||
|
|
212
|
-
!(0, bytes_1.uint8Equal)(collectionState.hash, constants_1.APP_STATE_EMPTY_LT_HASH);
|
|
240
|
+
const hasPersistedState = collectionState.initialized;
|
|
213
241
|
const attrs = {
|
|
214
|
-
name: collection
|
|
242
|
+
name: collection,
|
|
243
|
+
version: String(hasPersistedState ? collectionState.version : constants_1.APP_STATE_DEFAULT_COLLECTION_VERSION),
|
|
244
|
+
return_snapshot: hasPersistedState ? 'false' : 'true'
|
|
215
245
|
};
|
|
216
|
-
if (hasPersistedState) {
|
|
217
|
-
attrs.version = String(collectionState.version);
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
attrs.return_snapshot = 'true';
|
|
221
|
-
}
|
|
222
246
|
const children = [];
|
|
223
247
|
const pendingMutations = pendingByCollection.get(collection) ?? [];
|
|
224
248
|
let outgoingContext;
|
|
@@ -232,7 +256,7 @@ class WaAppStateSyncClient {
|
|
|
232
256
|
});
|
|
233
257
|
}
|
|
234
258
|
else {
|
|
235
|
-
const outgoing = await this.buildOutgoingPatch(collection, collectionState, pendingMutations);
|
|
259
|
+
const outgoing = await this.buildOutgoingPatch(collection, collectionState, pendingMutations, activeSyncKey);
|
|
236
260
|
outgoingContext = outgoing.context;
|
|
237
261
|
children.push({
|
|
238
262
|
tag: constants_2.WA_NODE_TAGS.PATCH,
|
|
@@ -275,6 +299,7 @@ class WaAppStateSyncClient {
|
|
|
275
299
|
tag: responseNode.tag,
|
|
276
300
|
type: responseNode.attrs.type
|
|
277
301
|
});
|
|
302
|
+
(0, query_1.assertIqResult)(responseNode, 'app-state sync');
|
|
278
303
|
const payloads = (0, WaAppStateSyncResponseParser_1.parseSyncResponse)(responseNode);
|
|
279
304
|
this.logger.debug('app-state sync payloads parsed', { count: payloads.length });
|
|
280
305
|
const payloadByCollection = new Map();
|
|
@@ -296,20 +321,16 @@ class WaAppStateSyncClient {
|
|
|
296
321
|
return this.createCollectionOutcome(collection, payload.state, payload.version);
|
|
297
322
|
}
|
|
298
323
|
const pendingMutationsCount = pendingByCollection.get(collection)?.length ?? 0;
|
|
299
|
-
if (payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
: constants_2.WA_APP_STATE_COLLECTION_STATES.SUCCESS, payload.version, shouldRefetch);
|
|
310
|
-
}
|
|
311
|
-
if (payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.CONFLICT_HAS_MORE) {
|
|
312
|
-
return this.createCollectionOutcome(collection, payload.state, payload.version, shouldRefetch);
|
|
324
|
+
if (payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.CONFLICT ||
|
|
325
|
+
payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.CONFLICT_HAS_MORE) {
|
|
326
|
+
shouldRefetch =
|
|
327
|
+
payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.CONFLICT_HAS_MORE ||
|
|
328
|
+
pendingMutationsCount > 0;
|
|
329
|
+
return this.createCollectionOutcome(collection, payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.CONFLICT
|
|
330
|
+
? pendingMutationsCount > 0
|
|
331
|
+
? constants_2.WA_APP_STATE_COLLECTION_STATES.CONFLICT
|
|
332
|
+
: constants_2.WA_APP_STATE_COLLECTION_STATES.SUCCESS
|
|
333
|
+
: payload.state, payload.version, shouldRefetch);
|
|
313
334
|
}
|
|
314
335
|
try {
|
|
315
336
|
let appliedMutations = [];
|
|
@@ -321,14 +342,14 @@ class WaAppStateSyncClient {
|
|
|
321
342
|
const snapshotBytes = await downloader(payload.collection, 'snapshot', payload.snapshotReference);
|
|
322
343
|
const snapshot = this.validateSnapshot(payload.collection, _proto_1.proto.SyncdSnapshot.decode(snapshotBytes));
|
|
323
344
|
const snapshotMutations = await this.applySnapshot(payload.collection, snapshot);
|
|
324
|
-
appliedMutations
|
|
345
|
+
appliedMutations.push(...snapshotMutations);
|
|
325
346
|
collectionStateChanged = true;
|
|
326
347
|
}
|
|
327
348
|
if (payload.patches.length > 0) {
|
|
328
349
|
const readyPatches = await this.resolveReadyPatches(payload, options);
|
|
329
350
|
for (const readyPatch of readyPatches) {
|
|
330
351
|
const patchMutations = await this.applyPatch(payload.collection, readyPatch);
|
|
331
|
-
appliedMutations
|
|
352
|
+
appliedMutations.push(...patchMutations);
|
|
332
353
|
collectionStateChanged = true;
|
|
333
354
|
}
|
|
334
355
|
}
|
|
@@ -341,13 +362,17 @@ class WaAppStateSyncClient {
|
|
|
341
362
|
collectionStateChanged = true;
|
|
342
363
|
}
|
|
343
364
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
shouldRefetch = true;
|
|
365
|
+
const currentCollectionState = await this.getCollectionState(collection);
|
|
366
|
+
if (!currentCollectionState.initialized &&
|
|
367
|
+
payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.SUCCESS) {
|
|
368
|
+
this.setCollectionState(collection, payload.version ?? currentCollectionState.version, currentCollectionState.hash, currentCollectionState.indexValueMap);
|
|
369
|
+
collectionStateChanged = true;
|
|
350
370
|
}
|
|
371
|
+
shouldRefetch =
|
|
372
|
+
shouldRefetch ||
|
|
373
|
+
payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.SUCCESS_HAS_MORE ||
|
|
374
|
+
(payload.state === constants_2.WA_APP_STATE_COLLECTION_STATES.SUCCESS &&
|
|
375
|
+
skippedUploadCollections.has(collection));
|
|
351
376
|
this.logger.debug('app-state collection processed', {
|
|
352
377
|
collection: payload.collection,
|
|
353
378
|
state: payload.state,
|
|
@@ -386,24 +411,13 @@ class WaAppStateSyncClient {
|
|
|
386
411
|
}
|
|
387
412
|
};
|
|
388
413
|
}
|
|
389
|
-
collectDistinctMissingKeyIds(keyIds) {
|
|
390
|
-
const byHex = new Map();
|
|
391
|
-
for (const keyId of keyIds) {
|
|
392
|
-
const keyHex = (0, utils_1.keyIdToHex)(keyId);
|
|
393
|
-
if (byHex.has(keyHex)) {
|
|
394
|
-
continue;
|
|
395
|
-
}
|
|
396
|
-
byHex.set(keyHex, keyId);
|
|
397
|
-
}
|
|
398
|
-
return [...byHex.values()];
|
|
399
|
-
}
|
|
400
414
|
async notifyMissingKeys(input) {
|
|
401
|
-
const keyIds =
|
|
402
|
-
const collections =
|
|
415
|
+
const keyIds = input.keyIds;
|
|
416
|
+
const collections = input.collections;
|
|
403
417
|
if (keyIds.length === 0 || collections.length === 0) {
|
|
404
418
|
return;
|
|
405
419
|
}
|
|
406
|
-
const keyIdsHex = keyIds.map((keyId) => (0,
|
|
420
|
+
const keyIdsHex = keyIds.map((keyId) => (0, bytes_2.bytesToHex)(keyId));
|
|
407
421
|
this.logger.info('app-state requesting missing sync keys', {
|
|
408
422
|
keys: keyIdsHex.length,
|
|
409
423
|
keyIds: keyIdsHex.join(','),
|
|
@@ -424,13 +438,12 @@ class WaAppStateSyncClient {
|
|
|
424
438
|
}
|
|
425
439
|
}
|
|
426
440
|
async resolveReadyPatches(payload, options) {
|
|
427
|
-
const sortedPatches = payload.patches
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
.map((entry) => entry.patch);
|
|
441
|
+
const sortedPatches = payload.patches.slice();
|
|
442
|
+
const sortVersions = new Map();
|
|
443
|
+
for (const patch of sortedPatches) {
|
|
444
|
+
sortVersions.set(patch, this.parseCollectionPatchVersion(payload.collection, patch));
|
|
445
|
+
}
|
|
446
|
+
sortedPatches.sort((left, right) => sortVersions.get(left) - sortVersions.get(right));
|
|
434
447
|
return Promise.all(sortedPatches.map(async (patch) => {
|
|
435
448
|
let readyPatch = patch;
|
|
436
449
|
if ((!readyPatch.mutations || readyPatch.mutations.length === 0) &&
|
|
@@ -493,16 +506,16 @@ class WaAppStateSyncClient {
|
|
|
493
506
|
}
|
|
494
507
|
async applySnapshot(collection, snapshot) {
|
|
495
508
|
const version = this.normalizeProtoLong(snapshot.version?.version, `snapshot.version.version (${collection})`);
|
|
496
|
-
const keyId = (0,
|
|
509
|
+
const keyId = (0, bytes_1.decodeProtoBytes)(snapshot.keyId?.id, `snapshot.keyId.id (${collection})`);
|
|
497
510
|
const keyData = await this.getKeyData(keyId);
|
|
498
511
|
if (!keyData) {
|
|
499
|
-
throw new WaAppStateMissingKeyError(`missing snapshot key ${(0,
|
|
512
|
+
throw new WaAppStateMissingKeyError(`missing snapshot key ${(0, bytes_2.bytesToHex)(keyId)} for ${collection}`, keyId, collection);
|
|
500
513
|
}
|
|
501
514
|
const indexValueMap = new Map();
|
|
502
515
|
const mutations = [];
|
|
503
516
|
const decryptedRecords = await this.decryptSnapshotRecords(collection, snapshot);
|
|
504
517
|
for (const { decrypted, recordKeyId } of decryptedRecords) {
|
|
505
|
-
const indexMacHex = (0,
|
|
518
|
+
const indexMacHex = (0, bytes_2.bytesToHex)(decrypted.indexMac);
|
|
506
519
|
indexValueMap.set(indexMacHex, decrypted.valueMac);
|
|
507
520
|
mutations.push({
|
|
508
521
|
collection,
|
|
@@ -517,9 +530,15 @@ class WaAppStateSyncClient {
|
|
|
517
530
|
timestamp: this.normalizeProtoLong(decrypted.value?.timestamp, `snapshot.record.value.timestamp (${collection})`)
|
|
518
531
|
});
|
|
519
532
|
}
|
|
520
|
-
const
|
|
533
|
+
const ltHashInput = new Array(indexValueMap.size);
|
|
534
|
+
let ltHashInputIndex = 0;
|
|
535
|
+
for (const valueMac of indexValueMap.values()) {
|
|
536
|
+
ltHashInput[ltHashInputIndex] = valueMac;
|
|
537
|
+
ltHashInputIndex += 1;
|
|
538
|
+
}
|
|
539
|
+
const ltHash = await this.crypto.ltHashAdd(constants_1.APP_STATE_EMPTY_LT_HASH, ltHashInput);
|
|
521
540
|
const expectedSnapshotMac = await this.crypto.generateSnapshotMac(keyData, ltHash, version, collection);
|
|
522
|
-
if (!(0,
|
|
541
|
+
if (!(0, bytes_2.uint8Equal)(expectedSnapshotMac, snapshot.mac)) {
|
|
523
542
|
throw new Error(`snapshot MAC mismatch for ${collection}`);
|
|
524
543
|
}
|
|
525
544
|
this.setCollectionState(collection, version, ltHash, indexValueMap);
|
|
@@ -531,48 +550,72 @@ class WaAppStateSyncClient {
|
|
|
531
550
|
if (current.version !== patchVersion - 1) {
|
|
532
551
|
throw new Error(`patch version mismatch for ${collection}: local=${current.version}, incoming=${patchVersion}`);
|
|
533
552
|
}
|
|
534
|
-
const patchKeyId = (0,
|
|
553
|
+
const patchKeyId = (0, bytes_1.decodeProtoBytes)(patch.keyId?.id, `patch.keyId.id (${collection})`);
|
|
535
554
|
const patchKeyData = await this.getKeyData(patchKeyId);
|
|
536
555
|
if (!patchKeyData) {
|
|
537
|
-
throw new WaAppStateMissingKeyError(`missing patch key ${(0,
|
|
556
|
+
throw new WaAppStateMissingKeyError(`missing patch key ${(0, bytes_2.bytesToHex)(patchKeyId)} for ${collection}`, patchKeyId, collection);
|
|
538
557
|
}
|
|
539
558
|
const decryptedMutations = await this.decryptPatchMutations(collection, patch);
|
|
540
|
-
const
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
559
|
+
const macMutations = new Array(decryptedMutations.length);
|
|
560
|
+
const valueMacs = new Array(decryptedMutations.length);
|
|
561
|
+
for (let index = 0; index < decryptedMutations.length; index += 1) {
|
|
562
|
+
const mutation = decryptedMutations[index];
|
|
563
|
+
valueMacs[index] = mutation.valueMac;
|
|
564
|
+
macMutations[index] = {
|
|
565
|
+
operation: mutation.operationCode,
|
|
566
|
+
indexMac: mutation.indexMac,
|
|
567
|
+
valueMac: mutation.valueMac
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
const nextState = await this.computeNextCollectionState(current.hash, current.indexValueMap, macMutations, collection);
|
|
571
|
+
await this.assertPatchMacsMatch(patch, collection, patchKeyData, patchVersion, nextState.hash, valueMacs);
|
|
546
572
|
this.setCollectionState(collection, patchVersion, nextState.hash, nextState.indexValueMap);
|
|
547
|
-
return decryptedMutations
|
|
548
|
-
void operationCode;
|
|
549
|
-
return mutation;
|
|
550
|
-
});
|
|
573
|
+
return decryptedMutations;
|
|
551
574
|
}
|
|
552
575
|
async decryptSnapshotRecords(collection, snapshot) {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
const
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
operation: _proto_1.proto.SyncdMutation.SyncdOperation.SET,
|
|
563
|
-
keyId: recordKeyId,
|
|
564
|
-
keyData: recordKeyData,
|
|
565
|
-
indexMac,
|
|
566
|
-
valueBlob
|
|
567
|
-
});
|
|
568
|
-
return {
|
|
569
|
-
decrypted,
|
|
576
|
+
const rawRecords = snapshot.records ?? [];
|
|
577
|
+
const records = new Array(rawRecords.length);
|
|
578
|
+
const recordKeyIds = new Array(rawRecords.length);
|
|
579
|
+
for (let i = 0; i < rawRecords.length; i += 1) {
|
|
580
|
+
const record = rawRecords[i];
|
|
581
|
+
const recordKeyId = (0, bytes_1.decodeProtoBytes)(record.keyId?.id, `snapshot.record.keyId.id (${collection})`);
|
|
582
|
+
records[i] = {
|
|
583
|
+
indexMac: (0, bytes_1.decodeProtoBytes)(record.index?.blob, `snapshot.record.index.blob (${collection})`),
|
|
584
|
+
valueBlob: (0, bytes_1.decodeProtoBytes)(record.value?.blob, `snapshot.record.value.blob (${collection})`),
|
|
570
585
|
recordKeyId
|
|
571
586
|
};
|
|
572
|
-
|
|
587
|
+
recordKeyIds[i] = recordKeyId;
|
|
588
|
+
}
|
|
589
|
+
await this.preloadKeyData(recordKeyIds);
|
|
590
|
+
const decryptTasks = new Array(records.length);
|
|
591
|
+
for (let i = 0; i < records.length; i += 1) {
|
|
592
|
+
const { indexMac, valueBlob, recordKeyId } = records[i];
|
|
593
|
+
decryptTasks[i] = (async () => {
|
|
594
|
+
const recordKeyData = await this.getKeyData(recordKeyId);
|
|
595
|
+
if (!recordKeyData) {
|
|
596
|
+
throw new WaAppStateMissingKeyError(`missing snapshot mutation key ${(0, bytes_2.bytesToHex)(recordKeyId)} for ${collection}`, recordKeyId, collection);
|
|
597
|
+
}
|
|
598
|
+
const decrypted = await this.crypto.decryptMutation({
|
|
599
|
+
operation: _proto_1.proto.SyncdMutation.SyncdOperation.SET,
|
|
600
|
+
keyId: recordKeyId,
|
|
601
|
+
keyData: recordKeyData,
|
|
602
|
+
indexMac,
|
|
603
|
+
valueBlob
|
|
604
|
+
});
|
|
605
|
+
return {
|
|
606
|
+
decrypted,
|
|
607
|
+
recordKeyId
|
|
608
|
+
};
|
|
609
|
+
})();
|
|
610
|
+
}
|
|
611
|
+
return Promise.all(decryptTasks);
|
|
573
612
|
}
|
|
574
613
|
async decryptPatchMutations(collection, patch) {
|
|
575
|
-
|
|
614
|
+
const rawMutations = patch.mutations ?? [];
|
|
615
|
+
const parsedMutations = new Array(rawMutations.length);
|
|
616
|
+
const mutationKeyIds = new Array(rawMutations.length);
|
|
617
|
+
for (let i = 0; i < rawMutations.length; i += 1) {
|
|
618
|
+
const mutation = rawMutations[i];
|
|
576
619
|
const operationCode = mutation.operation;
|
|
577
620
|
if (operationCode === null || operationCode === undefined) {
|
|
578
621
|
throw new Error(`patch mutation is missing operation (${collection})`);
|
|
@@ -581,51 +624,63 @@ class WaAppStateSyncClient {
|
|
|
581
624
|
if (!record) {
|
|
582
625
|
throw new Error(`patch mutation is missing record (${collection})`);
|
|
583
626
|
}
|
|
584
|
-
const
|
|
585
|
-
|
|
586
|
-
const recordKeyId = (0, base64_1.decodeProtoBytes)(record.keyId?.id, `patch.record.keyId.id (${collection})`);
|
|
587
|
-
const recordKeyData = await this.getKeyData(recordKeyId);
|
|
588
|
-
if (!recordKeyData) {
|
|
589
|
-
throw new WaAppStateMissingKeyError(`missing mutation key ${(0, utils_1.keyIdToHex)(recordKeyId)} for ${collection}`, recordKeyId, collection);
|
|
590
|
-
}
|
|
591
|
-
const decrypted = await this.crypto.decryptMutation({
|
|
592
|
-
operation: operationCode,
|
|
593
|
-
keyId: recordKeyId,
|
|
594
|
-
keyData: recordKeyData,
|
|
595
|
-
indexMac,
|
|
596
|
-
valueBlob
|
|
597
|
-
});
|
|
598
|
-
return {
|
|
599
|
-
collection,
|
|
600
|
-
operation: operationCode === _proto_1.proto.SyncdMutation.SyncdOperation.REMOVE
|
|
601
|
-
? 'remove'
|
|
602
|
-
: 'set',
|
|
603
|
-
source: 'patch',
|
|
627
|
+
const recordKeyId = (0, bytes_1.decodeProtoBytes)(record.keyId?.id, `patch.record.keyId.id (${collection})`);
|
|
628
|
+
parsedMutations[i] = {
|
|
604
629
|
operationCode,
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
indexMac: decrypted.indexMac,
|
|
609
|
-
valueMac: decrypted.valueMac,
|
|
610
|
-
keyId: recordKeyId,
|
|
611
|
-
timestamp: this.normalizeProtoLong(decrypted.value?.timestamp, `patch.record.value.timestamp (${collection})`)
|
|
630
|
+
indexMac: (0, bytes_1.decodeProtoBytes)(record.index?.blob, `patch.record.index.blob (${collection})`),
|
|
631
|
+
valueBlob: (0, bytes_1.decodeProtoBytes)(record.value?.blob, `patch.record.value.blob (${collection})`),
|
|
632
|
+
recordKeyId
|
|
612
633
|
};
|
|
613
|
-
|
|
634
|
+
mutationKeyIds[i] = recordKeyId;
|
|
635
|
+
}
|
|
636
|
+
await this.preloadKeyData(mutationKeyIds);
|
|
637
|
+
const decryptTasks = new Array(parsedMutations.length);
|
|
638
|
+
for (let i = 0; i < parsedMutations.length; i += 1) {
|
|
639
|
+
const { operationCode, indexMac, valueBlob, recordKeyId } = parsedMutations[i];
|
|
640
|
+
decryptTasks[i] = (async () => {
|
|
641
|
+
const recordKeyData = await this.getKeyData(recordKeyId);
|
|
642
|
+
if (!recordKeyData) {
|
|
643
|
+
throw new WaAppStateMissingKeyError(`missing mutation key ${(0, bytes_2.bytesToHex)(recordKeyId)} for ${collection}`, recordKeyId, collection);
|
|
644
|
+
}
|
|
645
|
+
const decrypted = await this.crypto.decryptMutation({
|
|
646
|
+
operation: operationCode,
|
|
647
|
+
keyId: recordKeyId,
|
|
648
|
+
keyData: recordKeyData,
|
|
649
|
+
indexMac,
|
|
650
|
+
valueBlob
|
|
651
|
+
});
|
|
652
|
+
return {
|
|
653
|
+
collection,
|
|
654
|
+
operation: operationCode === _proto_1.proto.SyncdMutation.SyncdOperation.REMOVE
|
|
655
|
+
? 'remove'
|
|
656
|
+
: 'set',
|
|
657
|
+
source: 'patch',
|
|
658
|
+
operationCode,
|
|
659
|
+
index: decrypted.index,
|
|
660
|
+
value: decrypted.value,
|
|
661
|
+
version: decrypted.version,
|
|
662
|
+
indexMac: decrypted.indexMac,
|
|
663
|
+
valueMac: decrypted.valueMac,
|
|
664
|
+
keyId: recordKeyId,
|
|
665
|
+
timestamp: this.normalizeProtoLong(decrypted.value?.timestamp, `patch.record.value.timestamp (${collection})`)
|
|
666
|
+
};
|
|
667
|
+
})();
|
|
668
|
+
}
|
|
669
|
+
return Promise.all(decryptTasks);
|
|
614
670
|
}
|
|
615
|
-
async assertPatchMacsMatch(patch, collection, patchKeyData, patchVersion, nextHash,
|
|
616
|
-
const snapshotMac = (0,
|
|
671
|
+
async assertPatchMacsMatch(patch, collection, patchKeyData, patchVersion, nextHash, valueMacs) {
|
|
672
|
+
const snapshotMac = (0, bytes_1.decodeProtoBytes)(patch.snapshotMac, `patch.snapshotMac (${collection})`);
|
|
617
673
|
const expectedSnapshotMac = await this.crypto.generateSnapshotMac(patchKeyData, nextHash, patchVersion, collection);
|
|
618
|
-
if (!(0,
|
|
674
|
+
if (!(0, bytes_2.uint8Equal)(expectedSnapshotMac, snapshotMac)) {
|
|
619
675
|
throw new Error(`patch snapshot MAC mismatch for ${collection}`);
|
|
620
676
|
}
|
|
621
|
-
const patchMac = (0,
|
|
622
|
-
const expectedPatchMac = await this.crypto.generatePatchMac(patchKeyData, snapshotMac,
|
|
623
|
-
if (!(0,
|
|
677
|
+
const patchMac = (0, bytes_1.decodeProtoBytes)(patch.patchMac, `patch.patchMac (${collection})`);
|
|
678
|
+
const expectedPatchMac = await this.crypto.generatePatchMac(patchKeyData, snapshotMac, valueMacs, patchVersion, collection);
|
|
679
|
+
if (!(0, bytes_2.uint8Equal)(expectedPatchMac, patchMac)) {
|
|
624
680
|
throw new Error(`patch MAC mismatch for ${collection}`);
|
|
625
681
|
}
|
|
626
682
|
}
|
|
627
|
-
async buildOutgoingPatch(collection, snapshot, pendingMutations) {
|
|
628
|
-
const activeKey = await this.store.getActiveSyncKey();
|
|
683
|
+
async buildOutgoingPatch(collection, snapshot, pendingMutations, activeKey) {
|
|
629
684
|
if (!activeKey) {
|
|
630
685
|
throw new WaAppStateMissingKeyError(`no sync key available to upload ${collection}`, null, collection);
|
|
631
686
|
}
|
|
@@ -644,29 +699,39 @@ class WaAppStateSyncClient {
|
|
|
644
699
|
});
|
|
645
700
|
return { operationCode, encrypted };
|
|
646
701
|
}));
|
|
647
|
-
const encryptedMutations = encryptedResults.
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
702
|
+
const encryptedMutations = new Array(encryptedResults.length);
|
|
703
|
+
const macMutations = new Array(encryptedResults.length);
|
|
704
|
+
const valueMacs = new Array(encryptedResults.length);
|
|
705
|
+
for (let i = 0; i < encryptedResults.length; i += 1) {
|
|
706
|
+
const { operationCode, encrypted } = encryptedResults[i];
|
|
707
|
+
encryptedMutations[i] = {
|
|
708
|
+
operation: operationCode,
|
|
709
|
+
record: {
|
|
710
|
+
keyId: { id: activeKey.keyId },
|
|
711
|
+
index: { blob: encrypted.indexMac },
|
|
712
|
+
value: { blob: encrypted.valueBlob }
|
|
713
|
+
}
|
|
714
|
+
};
|
|
715
|
+
macMutations[i] = {
|
|
716
|
+
operation: operationCode,
|
|
717
|
+
indexMac: encrypted.indexMac,
|
|
718
|
+
valueMac: encrypted.valueMac
|
|
719
|
+
};
|
|
720
|
+
valueMacs[i] = encrypted.valueMac;
|
|
721
|
+
}
|
|
660
722
|
const nextState = await this.computeNextCollectionState(snapshot.hash, snapshot.indexValueMap, macMutations, collection);
|
|
661
723
|
const patchVersion = snapshot.version + 1;
|
|
662
724
|
const snapshotMac = await this.crypto.generateSnapshotMac(activeKey.keyData, nextState.hash, patchVersion, collection);
|
|
663
|
-
const patchMac = await this.crypto.generatePatchMac(activeKey.keyData, snapshotMac,
|
|
725
|
+
const patchMac = await this.crypto.generatePatchMac(activeKey.keyData, snapshotMac, valueMacs, patchVersion, collection);
|
|
726
|
+
const deviceIndex = this.resolveDeviceIndex();
|
|
727
|
+
const clientDebugData = this.buildPatchClientDebugData();
|
|
664
728
|
const encodedPatch = _proto_1.proto.SyncdPatch.encode({
|
|
665
|
-
version: { version: patchVersion },
|
|
666
729
|
mutations: encryptedMutations,
|
|
667
730
|
snapshotMac,
|
|
668
731
|
patchMac,
|
|
669
|
-
keyId: { id: activeKey.keyId }
|
|
732
|
+
keyId: { id: activeKey.keyId },
|
|
733
|
+
...(deviceIndex === undefined ? {} : { deviceIndex }),
|
|
734
|
+
clientDebugData
|
|
670
735
|
}).finish();
|
|
671
736
|
return {
|
|
672
737
|
encodedPatch,
|
|
@@ -678,13 +743,35 @@ class WaAppStateSyncClient {
|
|
|
678
743
|
}
|
|
679
744
|
};
|
|
680
745
|
}
|
|
746
|
+
resolveDeviceIndex() {
|
|
747
|
+
const meJid = this.getCurrentMeJid?.();
|
|
748
|
+
if (!meJid) {
|
|
749
|
+
return undefined;
|
|
750
|
+
}
|
|
751
|
+
try {
|
|
752
|
+
return (0, jid_1.parseSignalAddressFromJid)(meJid).device;
|
|
753
|
+
}
|
|
754
|
+
catch (error) {
|
|
755
|
+
this.logger.debug('app-state could not parse device index from me jid', {
|
|
756
|
+
meJid
|
|
757
|
+
});
|
|
758
|
+
void error;
|
|
759
|
+
return undefined;
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
buildPatchClientDebugData() {
|
|
763
|
+
return _proto_1.proto.PatchDebugData.encode({
|
|
764
|
+
isSenderPrimary: false,
|
|
765
|
+
senderPlatform: _proto_1.proto.PatchDebugData.Platform.WEB
|
|
766
|
+
}).finish();
|
|
767
|
+
}
|
|
681
768
|
async computeNextCollectionState(baseHash, baseMap, mutations, collection) {
|
|
682
769
|
const indexValueMap = new Map(baseMap);
|
|
683
770
|
const addValues = [];
|
|
684
771
|
const removeValues = [];
|
|
685
772
|
let missingRemoveCount = 0;
|
|
686
773
|
for (const mutation of mutations) {
|
|
687
|
-
const indexMacHex = (0,
|
|
774
|
+
const indexMacHex = (0, bytes_2.bytesToHex)(mutation.indexMac);
|
|
688
775
|
const existing = indexValueMap.get(indexMacHex);
|
|
689
776
|
if (mutation.operation === _proto_1.proto.SyncdMutation.SyncdOperation.REMOVE) {
|
|
690
777
|
if (!existing) {
|
|
@@ -749,9 +836,33 @@ class WaAppStateSyncClient {
|
|
|
749
836
|
}
|
|
750
837
|
return compacted;
|
|
751
838
|
}
|
|
839
|
+
async preloadKeyData(keyIds) {
|
|
840
|
+
if (keyIds.length === 0) {
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
const context = this.requireSyncContext();
|
|
844
|
+
const missingKeyIds = [];
|
|
845
|
+
const missingKeyHexes = new Set();
|
|
846
|
+
for (let index = 0; index < keyIds.length; index += 1) {
|
|
847
|
+
const keyId = keyIds[index];
|
|
848
|
+
const keyHex = (0, bytes_2.bytesToHex)(keyId);
|
|
849
|
+
if (context.keys.has(keyHex) || missingKeyHexes.has(keyHex)) {
|
|
850
|
+
continue;
|
|
851
|
+
}
|
|
852
|
+
missingKeyHexes.add(keyHex);
|
|
853
|
+
missingKeyIds.push(keyId);
|
|
854
|
+
}
|
|
855
|
+
if (missingKeyIds.length === 0) {
|
|
856
|
+
return;
|
|
857
|
+
}
|
|
858
|
+
const loadedKeyData = await this.store.getSyncKeyDataBatch(missingKeyIds);
|
|
859
|
+
for (let index = 0; index < missingKeyIds.length; index += 1) {
|
|
860
|
+
context.keys.set((0, bytes_2.bytesToHex)(missingKeyIds[index]), loadedKeyData[index] ?? null);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
752
863
|
async getKeyData(keyId) {
|
|
753
864
|
const context = this.requireSyncContext();
|
|
754
|
-
const keyHex = (0,
|
|
865
|
+
const keyHex = (0, bytes_2.bytesToHex)(keyId);
|
|
755
866
|
if (context.keys.has(keyHex)) {
|
|
756
867
|
return context.keys.get(keyHex) ?? null;
|
|
757
868
|
}
|
|
@@ -772,6 +883,7 @@ class WaAppStateSyncClient {
|
|
|
772
883
|
setCollectionState(collection, version, hash, indexValueMap) {
|
|
773
884
|
const context = this.requireSyncContext();
|
|
774
885
|
context.collections.set(collection, {
|
|
886
|
+
initialized: true,
|
|
775
887
|
version,
|
|
776
888
|
hash,
|
|
777
889
|
indexValueMap
|