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
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { APP_STATE_DEFAULT_COLLECTIONS, APP_STATE_EMPTY_LT_HASH } from './constants.js';
|
|
2
|
-
import { keyIdToHex } from './utils.js';
|
|
1
|
+
import { APP_STATE_DEFAULT_COLLECTIONS, APP_STATE_DEFAULT_COLLECTION_VERSION, APP_STATE_EMPTY_LT_HASH } from './constants.js';
|
|
3
2
|
import { WaAppStateCrypto } from './WaAppStateCrypto.js';
|
|
4
3
|
import { parseSyncResponse } from './WaAppStateSyncResponseParser.js';
|
|
5
4
|
import { proto } from '../proto.js';
|
|
6
5
|
import { WA_APP_STATE_COLLECTION_STATES, WA_DEFAULTS, WA_IQ_TYPES, WA_NODE_TAGS, WA_XMLNS } from '../protocol/constants.js';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
6
|
+
import { parseSignalAddressFromJid } from '../protocol/jid.js';
|
|
7
|
+
import { assertIqResult } from '../transport/node/query.js';
|
|
8
|
+
import { decodeProtoBytes } from '../util/bytes.js';
|
|
9
|
+
import { bytesToHex, uint8Equal } from '../util/bytes.js';
|
|
9
10
|
import { longToNumber } from '../util/primitives.js';
|
|
10
11
|
export class WaAppStateMissingKeyError extends Error {
|
|
11
12
|
constructor(message, keyId, collection) {
|
|
@@ -20,6 +21,7 @@ export class WaAppStateSyncClient {
|
|
|
20
21
|
this.logger = options.logger;
|
|
21
22
|
this.query = options.query;
|
|
22
23
|
this.store = options.store;
|
|
24
|
+
this.getCurrentMeJid = options.getCurrentMeJid;
|
|
23
25
|
this.hostDomain = options.hostDomain ?? WA_DEFAULTS.HOST_DOMAIN;
|
|
24
26
|
this.defaultTimeoutMs = options.defaultTimeoutMs ?? WA_DEFAULTS.APP_STATE_SYNC_TIMEOUT_MS;
|
|
25
27
|
this.onMissingKeys = options.onMissingKeys;
|
|
@@ -46,7 +48,7 @@ export class WaAppStateSyncClient {
|
|
|
46
48
|
const keyId = decodeProtoBytes(item.keyId?.keyId, 'appStateSyncKeyShare.keys[].keyId.keyId');
|
|
47
49
|
if (!item.keyData?.keyData) {
|
|
48
50
|
this.logger.debug('app-state sync key share entry missing key data', {
|
|
49
|
-
keyId:
|
|
51
|
+
keyId: bytesToHex(keyId)
|
|
50
52
|
});
|
|
51
53
|
continue;
|
|
52
54
|
}
|
|
@@ -89,6 +91,10 @@ export class WaAppStateSyncClient {
|
|
|
89
91
|
...new Set(options.collections ?? APP_STATE_DEFAULT_COLLECTIONS)
|
|
90
92
|
];
|
|
91
93
|
try {
|
|
94
|
+
const initialCollectionStates = await this.store.getCollectionStates(collections);
|
|
95
|
+
for (let index = 0; index < collections.length; index += 1) {
|
|
96
|
+
context.collections.set(collections[index], initialCollectionStates[index]);
|
|
97
|
+
}
|
|
92
98
|
this.logger.info('app-state sync start', {
|
|
93
99
|
collections: collections.length,
|
|
94
100
|
pendingMutations: options.pendingMutations?.length ?? 0
|
|
@@ -158,36 +164,18 @@ export class WaAppStateSyncClient {
|
|
|
158
164
|
}
|
|
159
165
|
}
|
|
160
166
|
async syncCollectionsRound(collections, pendingByCollection, options) {
|
|
161
|
-
const
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
options,
|
|
169
|
-
outgoingContexts: prepared.outgoingContexts,
|
|
170
|
-
skippedUploadCollections: prepared.skippedUploadCollections
|
|
171
|
-
})));
|
|
172
|
-
return {
|
|
173
|
-
results: collectionOutcomes.map((entry) => entry.result),
|
|
174
|
-
collectionsToRefetch: collectionOutcomes
|
|
175
|
-
.filter((entry) => entry.shouldRefetch)
|
|
176
|
-
.map((entry) => entry.collection),
|
|
177
|
-
stateChanged: collectionOutcomes.some((entry) => entry.stateChanged),
|
|
178
|
-
missingKeyIds: this.collectDistinctMissingKeyIds(collectionOutcomes
|
|
179
|
-
.map((entry) => entry.missingKeyId)
|
|
180
|
-
.filter((value) => value !== null)),
|
|
181
|
-
blockedCollections: collectionOutcomes
|
|
182
|
-
.filter((entry) => entry.result.state === WA_APP_STATE_COLLECTION_STATES.BLOCKED)
|
|
183
|
-
.map((entry) => entry.collection)
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
async prepareSyncRoundRequest(collections, pendingByCollection) {
|
|
187
|
-
const requests = await Promise.all(collections.map((collection) => this.buildCollectionSyncRequest(collection, pendingByCollection)));
|
|
167
|
+
const activeSyncKey = await this.store.getActiveSyncKey();
|
|
168
|
+
const requestPromises = new Array(collections.length);
|
|
169
|
+
for (let index = 0; index < collections.length; index += 1) {
|
|
170
|
+
requestPromises[index] = this.buildCollectionSyncRequest(collections[index], pendingByCollection, activeSyncKey);
|
|
171
|
+
}
|
|
172
|
+
const requests = await Promise.all(requestPromises);
|
|
173
|
+
const collectionNodes = new Array(requests.length);
|
|
188
174
|
const outgoingContexts = new Map();
|
|
189
175
|
const skippedUploadCollections = new Set();
|
|
190
|
-
for (
|
|
176
|
+
for (let index = 0; index < requests.length; index += 1) {
|
|
177
|
+
const request = requests[index];
|
|
178
|
+
collectionNodes[index] = request.node;
|
|
191
179
|
if (request.outgoingContext) {
|
|
192
180
|
outgoingContexts.set(request.collection, request.outgoingContext);
|
|
193
181
|
}
|
|
@@ -195,26 +183,62 @@ export class WaAppStateSyncClient {
|
|
|
195
183
|
skippedUploadCollections.add(request.collection);
|
|
196
184
|
}
|
|
197
185
|
}
|
|
186
|
+
const iqNode = this.buildSyncIqNode(collectionNodes);
|
|
187
|
+
const payloadByCollection = await this.fetchSyncPayloadByCollection(iqNode, options.timeoutMs ?? this.defaultTimeoutMs);
|
|
188
|
+
const collectionOutcomePromises = new Array(collections.length);
|
|
189
|
+
for (let index = 0; index < collections.length; index += 1) {
|
|
190
|
+
collectionOutcomePromises[index] = this.processCollectionRound({
|
|
191
|
+
collection: collections[index],
|
|
192
|
+
payloadByCollection,
|
|
193
|
+
pendingByCollection,
|
|
194
|
+
options,
|
|
195
|
+
outgoingContexts,
|
|
196
|
+
skippedUploadCollections
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
const collectionOutcomes = await Promise.all(collectionOutcomePromises);
|
|
200
|
+
const results = [];
|
|
201
|
+
const collectionsToRefetch = [];
|
|
202
|
+
const blockedCollections = [];
|
|
203
|
+
const missingKeyIds = [];
|
|
204
|
+
const missingKeyIdHexes = new Set();
|
|
205
|
+
let stateChanged = false;
|
|
206
|
+
for (let index = 0; index < collectionOutcomes.length; index += 1) {
|
|
207
|
+
const entry = collectionOutcomes[index];
|
|
208
|
+
results.push(entry.result);
|
|
209
|
+
if (entry.shouldRefetch) {
|
|
210
|
+
collectionsToRefetch.push(entry.collection);
|
|
211
|
+
}
|
|
212
|
+
if (entry.stateChanged) {
|
|
213
|
+
stateChanged = true;
|
|
214
|
+
}
|
|
215
|
+
if (entry.result.state === WA_APP_STATE_COLLECTION_STATES.BLOCKED) {
|
|
216
|
+
blockedCollections.push(entry.collection);
|
|
217
|
+
}
|
|
218
|
+
if (entry.missingKeyId) {
|
|
219
|
+
const keyHex = bytesToHex(entry.missingKeyId);
|
|
220
|
+
if (!missingKeyIdHexes.has(keyHex)) {
|
|
221
|
+
missingKeyIdHexes.add(keyHex);
|
|
222
|
+
missingKeyIds.push(entry.missingKeyId);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
198
226
|
return {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
227
|
+
results,
|
|
228
|
+
collectionsToRefetch,
|
|
229
|
+
stateChanged,
|
|
230
|
+
missingKeyIds,
|
|
231
|
+
blockedCollections
|
|
202
232
|
};
|
|
203
233
|
}
|
|
204
|
-
async buildCollectionSyncRequest(collection, pendingByCollection) {
|
|
234
|
+
async buildCollectionSyncRequest(collection, pendingByCollection, activeSyncKey) {
|
|
205
235
|
const collectionState = await this.getCollectionState(collection);
|
|
206
|
-
const hasPersistedState = collectionState.
|
|
207
|
-
collectionState.indexValueMap.size > 0 ||
|
|
208
|
-
!uint8Equal(collectionState.hash, APP_STATE_EMPTY_LT_HASH);
|
|
236
|
+
const hasPersistedState = collectionState.initialized;
|
|
209
237
|
const attrs = {
|
|
210
|
-
name: collection
|
|
238
|
+
name: collection,
|
|
239
|
+
version: String(hasPersistedState ? collectionState.version : APP_STATE_DEFAULT_COLLECTION_VERSION),
|
|
240
|
+
return_snapshot: hasPersistedState ? 'false' : 'true'
|
|
211
241
|
};
|
|
212
|
-
if (hasPersistedState) {
|
|
213
|
-
attrs.version = String(collectionState.version);
|
|
214
|
-
}
|
|
215
|
-
else {
|
|
216
|
-
attrs.return_snapshot = 'true';
|
|
217
|
-
}
|
|
218
242
|
const children = [];
|
|
219
243
|
const pendingMutations = pendingByCollection.get(collection) ?? [];
|
|
220
244
|
let outgoingContext;
|
|
@@ -228,7 +252,7 @@ export class WaAppStateSyncClient {
|
|
|
228
252
|
});
|
|
229
253
|
}
|
|
230
254
|
else {
|
|
231
|
-
const outgoing = await this.buildOutgoingPatch(collection, collectionState, pendingMutations);
|
|
255
|
+
const outgoing = await this.buildOutgoingPatch(collection, collectionState, pendingMutations, activeSyncKey);
|
|
232
256
|
outgoingContext = outgoing.context;
|
|
233
257
|
children.push({
|
|
234
258
|
tag: WA_NODE_TAGS.PATCH,
|
|
@@ -271,6 +295,7 @@ export class WaAppStateSyncClient {
|
|
|
271
295
|
tag: responseNode.tag,
|
|
272
296
|
type: responseNode.attrs.type
|
|
273
297
|
});
|
|
298
|
+
assertIqResult(responseNode, 'app-state sync');
|
|
274
299
|
const payloads = parseSyncResponse(responseNode);
|
|
275
300
|
this.logger.debug('app-state sync payloads parsed', { count: payloads.length });
|
|
276
301
|
const payloadByCollection = new Map();
|
|
@@ -292,20 +317,16 @@ export class WaAppStateSyncClient {
|
|
|
292
317
|
return this.createCollectionOutcome(collection, payload.state, payload.version);
|
|
293
318
|
}
|
|
294
319
|
const pendingMutationsCount = pendingByCollection.get(collection)?.length ?? 0;
|
|
295
|
-
if (payload.state === WA_APP_STATE_COLLECTION_STATES.
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
: WA_APP_STATE_COLLECTION_STATES.SUCCESS, payload.version, shouldRefetch);
|
|
306
|
-
}
|
|
307
|
-
if (payload.state === WA_APP_STATE_COLLECTION_STATES.CONFLICT_HAS_MORE) {
|
|
308
|
-
return this.createCollectionOutcome(collection, payload.state, payload.version, shouldRefetch);
|
|
320
|
+
if (payload.state === WA_APP_STATE_COLLECTION_STATES.CONFLICT ||
|
|
321
|
+
payload.state === WA_APP_STATE_COLLECTION_STATES.CONFLICT_HAS_MORE) {
|
|
322
|
+
shouldRefetch =
|
|
323
|
+
payload.state === WA_APP_STATE_COLLECTION_STATES.CONFLICT_HAS_MORE ||
|
|
324
|
+
pendingMutationsCount > 0;
|
|
325
|
+
return this.createCollectionOutcome(collection, payload.state === WA_APP_STATE_COLLECTION_STATES.CONFLICT
|
|
326
|
+
? pendingMutationsCount > 0
|
|
327
|
+
? WA_APP_STATE_COLLECTION_STATES.CONFLICT
|
|
328
|
+
: WA_APP_STATE_COLLECTION_STATES.SUCCESS
|
|
329
|
+
: payload.state, payload.version, shouldRefetch);
|
|
309
330
|
}
|
|
310
331
|
try {
|
|
311
332
|
let appliedMutations = [];
|
|
@@ -317,14 +338,14 @@ export class WaAppStateSyncClient {
|
|
|
317
338
|
const snapshotBytes = await downloader(payload.collection, 'snapshot', payload.snapshotReference);
|
|
318
339
|
const snapshot = this.validateSnapshot(payload.collection, proto.SyncdSnapshot.decode(snapshotBytes));
|
|
319
340
|
const snapshotMutations = await this.applySnapshot(payload.collection, snapshot);
|
|
320
|
-
appliedMutations
|
|
341
|
+
appliedMutations.push(...snapshotMutations);
|
|
321
342
|
collectionStateChanged = true;
|
|
322
343
|
}
|
|
323
344
|
if (payload.patches.length > 0) {
|
|
324
345
|
const readyPatches = await this.resolveReadyPatches(payload, options);
|
|
325
346
|
for (const readyPatch of readyPatches) {
|
|
326
347
|
const patchMutations = await this.applyPatch(payload.collection, readyPatch);
|
|
327
|
-
appliedMutations
|
|
348
|
+
appliedMutations.push(...patchMutations);
|
|
328
349
|
collectionStateChanged = true;
|
|
329
350
|
}
|
|
330
351
|
}
|
|
@@ -337,13 +358,17 @@ export class WaAppStateSyncClient {
|
|
|
337
358
|
collectionStateChanged = true;
|
|
338
359
|
}
|
|
339
360
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
shouldRefetch = true;
|
|
361
|
+
const currentCollectionState = await this.getCollectionState(collection);
|
|
362
|
+
if (!currentCollectionState.initialized &&
|
|
363
|
+
payload.state === WA_APP_STATE_COLLECTION_STATES.SUCCESS) {
|
|
364
|
+
this.setCollectionState(collection, payload.version ?? currentCollectionState.version, currentCollectionState.hash, currentCollectionState.indexValueMap);
|
|
365
|
+
collectionStateChanged = true;
|
|
346
366
|
}
|
|
367
|
+
shouldRefetch =
|
|
368
|
+
shouldRefetch ||
|
|
369
|
+
payload.state === WA_APP_STATE_COLLECTION_STATES.SUCCESS_HAS_MORE ||
|
|
370
|
+
(payload.state === WA_APP_STATE_COLLECTION_STATES.SUCCESS &&
|
|
371
|
+
skippedUploadCollections.has(collection));
|
|
347
372
|
this.logger.debug('app-state collection processed', {
|
|
348
373
|
collection: payload.collection,
|
|
349
374
|
state: payload.state,
|
|
@@ -382,24 +407,13 @@ export class WaAppStateSyncClient {
|
|
|
382
407
|
}
|
|
383
408
|
};
|
|
384
409
|
}
|
|
385
|
-
collectDistinctMissingKeyIds(keyIds) {
|
|
386
|
-
const byHex = new Map();
|
|
387
|
-
for (const keyId of keyIds) {
|
|
388
|
-
const keyHex = keyIdToHex(keyId);
|
|
389
|
-
if (byHex.has(keyHex)) {
|
|
390
|
-
continue;
|
|
391
|
-
}
|
|
392
|
-
byHex.set(keyHex, keyId);
|
|
393
|
-
}
|
|
394
|
-
return [...byHex.values()];
|
|
395
|
-
}
|
|
396
410
|
async notifyMissingKeys(input) {
|
|
397
|
-
const keyIds =
|
|
398
|
-
const collections =
|
|
411
|
+
const keyIds = input.keyIds;
|
|
412
|
+
const collections = input.collections;
|
|
399
413
|
if (keyIds.length === 0 || collections.length === 0) {
|
|
400
414
|
return;
|
|
401
415
|
}
|
|
402
|
-
const keyIdsHex = keyIds.map((keyId) =>
|
|
416
|
+
const keyIdsHex = keyIds.map((keyId) => bytesToHex(keyId));
|
|
403
417
|
this.logger.info('app-state requesting missing sync keys', {
|
|
404
418
|
keys: keyIdsHex.length,
|
|
405
419
|
keyIds: keyIdsHex.join(','),
|
|
@@ -420,13 +434,12 @@ export class WaAppStateSyncClient {
|
|
|
420
434
|
}
|
|
421
435
|
}
|
|
422
436
|
async resolveReadyPatches(payload, options) {
|
|
423
|
-
const sortedPatches = payload.patches
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
.map((entry) => entry.patch);
|
|
437
|
+
const sortedPatches = payload.patches.slice();
|
|
438
|
+
const sortVersions = new Map();
|
|
439
|
+
for (const patch of sortedPatches) {
|
|
440
|
+
sortVersions.set(patch, this.parseCollectionPatchVersion(payload.collection, patch));
|
|
441
|
+
}
|
|
442
|
+
sortedPatches.sort((left, right) => sortVersions.get(left) - sortVersions.get(right));
|
|
430
443
|
return Promise.all(sortedPatches.map(async (patch) => {
|
|
431
444
|
let readyPatch = patch;
|
|
432
445
|
if ((!readyPatch.mutations || readyPatch.mutations.length === 0) &&
|
|
@@ -492,13 +505,13 @@ export class WaAppStateSyncClient {
|
|
|
492
505
|
const keyId = decodeProtoBytes(snapshot.keyId?.id, `snapshot.keyId.id (${collection})`);
|
|
493
506
|
const keyData = await this.getKeyData(keyId);
|
|
494
507
|
if (!keyData) {
|
|
495
|
-
throw new WaAppStateMissingKeyError(`missing snapshot key ${
|
|
508
|
+
throw new WaAppStateMissingKeyError(`missing snapshot key ${bytesToHex(keyId)} for ${collection}`, keyId, collection);
|
|
496
509
|
}
|
|
497
510
|
const indexValueMap = new Map();
|
|
498
511
|
const mutations = [];
|
|
499
512
|
const decryptedRecords = await this.decryptSnapshotRecords(collection, snapshot);
|
|
500
513
|
for (const { decrypted, recordKeyId } of decryptedRecords) {
|
|
501
|
-
const indexMacHex =
|
|
514
|
+
const indexMacHex = bytesToHex(decrypted.indexMac);
|
|
502
515
|
indexValueMap.set(indexMacHex, decrypted.valueMac);
|
|
503
516
|
mutations.push({
|
|
504
517
|
collection,
|
|
@@ -513,7 +526,13 @@ export class WaAppStateSyncClient {
|
|
|
513
526
|
timestamp: this.normalizeProtoLong(decrypted.value?.timestamp, `snapshot.record.value.timestamp (${collection})`)
|
|
514
527
|
});
|
|
515
528
|
}
|
|
516
|
-
const
|
|
529
|
+
const ltHashInput = new Array(indexValueMap.size);
|
|
530
|
+
let ltHashInputIndex = 0;
|
|
531
|
+
for (const valueMac of indexValueMap.values()) {
|
|
532
|
+
ltHashInput[ltHashInputIndex] = valueMac;
|
|
533
|
+
ltHashInputIndex += 1;
|
|
534
|
+
}
|
|
535
|
+
const ltHash = await this.crypto.ltHashAdd(APP_STATE_EMPTY_LT_HASH, ltHashInput);
|
|
517
536
|
const expectedSnapshotMac = await this.crypto.generateSnapshotMac(keyData, ltHash, version, collection);
|
|
518
537
|
if (!uint8Equal(expectedSnapshotMac, snapshot.mac)) {
|
|
519
538
|
throw new Error(`snapshot MAC mismatch for ${collection}`);
|
|
@@ -530,45 +549,69 @@ export class WaAppStateSyncClient {
|
|
|
530
549
|
const patchKeyId = decodeProtoBytes(patch.keyId?.id, `patch.keyId.id (${collection})`);
|
|
531
550
|
const patchKeyData = await this.getKeyData(patchKeyId);
|
|
532
551
|
if (!patchKeyData) {
|
|
533
|
-
throw new WaAppStateMissingKeyError(`missing patch key ${
|
|
552
|
+
throw new WaAppStateMissingKeyError(`missing patch key ${bytesToHex(patchKeyId)} for ${collection}`, patchKeyId, collection);
|
|
534
553
|
}
|
|
535
554
|
const decryptedMutations = await this.decryptPatchMutations(collection, patch);
|
|
536
|
-
const
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
555
|
+
const macMutations = new Array(decryptedMutations.length);
|
|
556
|
+
const valueMacs = new Array(decryptedMutations.length);
|
|
557
|
+
for (let index = 0; index < decryptedMutations.length; index += 1) {
|
|
558
|
+
const mutation = decryptedMutations[index];
|
|
559
|
+
valueMacs[index] = mutation.valueMac;
|
|
560
|
+
macMutations[index] = {
|
|
561
|
+
operation: mutation.operationCode,
|
|
562
|
+
indexMac: mutation.indexMac,
|
|
563
|
+
valueMac: mutation.valueMac
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
const nextState = await this.computeNextCollectionState(current.hash, current.indexValueMap, macMutations, collection);
|
|
567
|
+
await this.assertPatchMacsMatch(patch, collection, patchKeyData, patchVersion, nextState.hash, valueMacs);
|
|
542
568
|
this.setCollectionState(collection, patchVersion, nextState.hash, nextState.indexValueMap);
|
|
543
|
-
return decryptedMutations
|
|
544
|
-
void operationCode;
|
|
545
|
-
return mutation;
|
|
546
|
-
});
|
|
569
|
+
return decryptedMutations;
|
|
547
570
|
}
|
|
548
571
|
async decryptSnapshotRecords(collection, snapshot) {
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
572
|
+
const rawRecords = snapshot.records ?? [];
|
|
573
|
+
const records = new Array(rawRecords.length);
|
|
574
|
+
const recordKeyIds = new Array(rawRecords.length);
|
|
575
|
+
for (let i = 0; i < rawRecords.length; i += 1) {
|
|
576
|
+
const record = rawRecords[i];
|
|
552
577
|
const recordKeyId = decodeProtoBytes(record.keyId?.id, `snapshot.record.keyId.id (${collection})`);
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
}
|
|
557
|
-
const decrypted = await this.crypto.decryptMutation({
|
|
558
|
-
operation: proto.SyncdMutation.SyncdOperation.SET,
|
|
559
|
-
keyId: recordKeyId,
|
|
560
|
-
keyData: recordKeyData,
|
|
561
|
-
indexMac,
|
|
562
|
-
valueBlob
|
|
563
|
-
});
|
|
564
|
-
return {
|
|
565
|
-
decrypted,
|
|
578
|
+
records[i] = {
|
|
579
|
+
indexMac: decodeProtoBytes(record.index?.blob, `snapshot.record.index.blob (${collection})`),
|
|
580
|
+
valueBlob: decodeProtoBytes(record.value?.blob, `snapshot.record.value.blob (${collection})`),
|
|
566
581
|
recordKeyId
|
|
567
582
|
};
|
|
568
|
-
|
|
583
|
+
recordKeyIds[i] = recordKeyId;
|
|
584
|
+
}
|
|
585
|
+
await this.preloadKeyData(recordKeyIds);
|
|
586
|
+
const decryptTasks = new Array(records.length);
|
|
587
|
+
for (let i = 0; i < records.length; i += 1) {
|
|
588
|
+
const { indexMac, valueBlob, recordKeyId } = records[i];
|
|
589
|
+
decryptTasks[i] = (async () => {
|
|
590
|
+
const recordKeyData = await this.getKeyData(recordKeyId);
|
|
591
|
+
if (!recordKeyData) {
|
|
592
|
+
throw new WaAppStateMissingKeyError(`missing snapshot mutation key ${bytesToHex(recordKeyId)} for ${collection}`, recordKeyId, collection);
|
|
593
|
+
}
|
|
594
|
+
const decrypted = await this.crypto.decryptMutation({
|
|
595
|
+
operation: proto.SyncdMutation.SyncdOperation.SET,
|
|
596
|
+
keyId: recordKeyId,
|
|
597
|
+
keyData: recordKeyData,
|
|
598
|
+
indexMac,
|
|
599
|
+
valueBlob
|
|
600
|
+
});
|
|
601
|
+
return {
|
|
602
|
+
decrypted,
|
|
603
|
+
recordKeyId
|
|
604
|
+
};
|
|
605
|
+
})();
|
|
606
|
+
}
|
|
607
|
+
return Promise.all(decryptTasks);
|
|
569
608
|
}
|
|
570
609
|
async decryptPatchMutations(collection, patch) {
|
|
571
|
-
|
|
610
|
+
const rawMutations = patch.mutations ?? [];
|
|
611
|
+
const parsedMutations = new Array(rawMutations.length);
|
|
612
|
+
const mutationKeyIds = new Array(rawMutations.length);
|
|
613
|
+
for (let i = 0; i < rawMutations.length; i += 1) {
|
|
614
|
+
const mutation = rawMutations[i];
|
|
572
615
|
const operationCode = mutation.operation;
|
|
573
616
|
if (operationCode === null || operationCode === undefined) {
|
|
574
617
|
throw new Error(`patch mutation is missing operation (${collection})`);
|
|
@@ -577,51 +620,63 @@ export class WaAppStateSyncClient {
|
|
|
577
620
|
if (!record) {
|
|
578
621
|
throw new Error(`patch mutation is missing record (${collection})`);
|
|
579
622
|
}
|
|
580
|
-
const indexMac = decodeProtoBytes(record.index?.blob, `patch.record.index.blob (${collection})`);
|
|
581
|
-
const valueBlob = decodeProtoBytes(record.value?.blob, `patch.record.value.blob (${collection})`);
|
|
582
623
|
const recordKeyId = decodeProtoBytes(record.keyId?.id, `patch.record.keyId.id (${collection})`);
|
|
583
|
-
|
|
584
|
-
if (!recordKeyData) {
|
|
585
|
-
throw new WaAppStateMissingKeyError(`missing mutation key ${keyIdToHex(recordKeyId)} for ${collection}`, recordKeyId, collection);
|
|
586
|
-
}
|
|
587
|
-
const decrypted = await this.crypto.decryptMutation({
|
|
588
|
-
operation: operationCode,
|
|
589
|
-
keyId: recordKeyId,
|
|
590
|
-
keyData: recordKeyData,
|
|
591
|
-
indexMac,
|
|
592
|
-
valueBlob
|
|
593
|
-
});
|
|
594
|
-
return {
|
|
595
|
-
collection,
|
|
596
|
-
operation: operationCode === proto.SyncdMutation.SyncdOperation.REMOVE
|
|
597
|
-
? 'remove'
|
|
598
|
-
: 'set',
|
|
599
|
-
source: 'patch',
|
|
624
|
+
parsedMutations[i] = {
|
|
600
625
|
operationCode,
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
indexMac: decrypted.indexMac,
|
|
605
|
-
valueMac: decrypted.valueMac,
|
|
606
|
-
keyId: recordKeyId,
|
|
607
|
-
timestamp: this.normalizeProtoLong(decrypted.value?.timestamp, `patch.record.value.timestamp (${collection})`)
|
|
626
|
+
indexMac: decodeProtoBytes(record.index?.blob, `patch.record.index.blob (${collection})`),
|
|
627
|
+
valueBlob: decodeProtoBytes(record.value?.blob, `patch.record.value.blob (${collection})`),
|
|
628
|
+
recordKeyId
|
|
608
629
|
};
|
|
609
|
-
|
|
630
|
+
mutationKeyIds[i] = recordKeyId;
|
|
631
|
+
}
|
|
632
|
+
await this.preloadKeyData(mutationKeyIds);
|
|
633
|
+
const decryptTasks = new Array(parsedMutations.length);
|
|
634
|
+
for (let i = 0; i < parsedMutations.length; i += 1) {
|
|
635
|
+
const { operationCode, indexMac, valueBlob, recordKeyId } = parsedMutations[i];
|
|
636
|
+
decryptTasks[i] = (async () => {
|
|
637
|
+
const recordKeyData = await this.getKeyData(recordKeyId);
|
|
638
|
+
if (!recordKeyData) {
|
|
639
|
+
throw new WaAppStateMissingKeyError(`missing mutation key ${bytesToHex(recordKeyId)} for ${collection}`, recordKeyId, collection);
|
|
640
|
+
}
|
|
641
|
+
const decrypted = await this.crypto.decryptMutation({
|
|
642
|
+
operation: operationCode,
|
|
643
|
+
keyId: recordKeyId,
|
|
644
|
+
keyData: recordKeyData,
|
|
645
|
+
indexMac,
|
|
646
|
+
valueBlob
|
|
647
|
+
});
|
|
648
|
+
return {
|
|
649
|
+
collection,
|
|
650
|
+
operation: operationCode === proto.SyncdMutation.SyncdOperation.REMOVE
|
|
651
|
+
? 'remove'
|
|
652
|
+
: 'set',
|
|
653
|
+
source: 'patch',
|
|
654
|
+
operationCode,
|
|
655
|
+
index: decrypted.index,
|
|
656
|
+
value: decrypted.value,
|
|
657
|
+
version: decrypted.version,
|
|
658
|
+
indexMac: decrypted.indexMac,
|
|
659
|
+
valueMac: decrypted.valueMac,
|
|
660
|
+
keyId: recordKeyId,
|
|
661
|
+
timestamp: this.normalizeProtoLong(decrypted.value?.timestamp, `patch.record.value.timestamp (${collection})`)
|
|
662
|
+
};
|
|
663
|
+
})();
|
|
664
|
+
}
|
|
665
|
+
return Promise.all(decryptTasks);
|
|
610
666
|
}
|
|
611
|
-
async assertPatchMacsMatch(patch, collection, patchKeyData, patchVersion, nextHash,
|
|
667
|
+
async assertPatchMacsMatch(patch, collection, patchKeyData, patchVersion, nextHash, valueMacs) {
|
|
612
668
|
const snapshotMac = decodeProtoBytes(patch.snapshotMac, `patch.snapshotMac (${collection})`);
|
|
613
669
|
const expectedSnapshotMac = await this.crypto.generateSnapshotMac(patchKeyData, nextHash, patchVersion, collection);
|
|
614
670
|
if (!uint8Equal(expectedSnapshotMac, snapshotMac)) {
|
|
615
671
|
throw new Error(`patch snapshot MAC mismatch for ${collection}`);
|
|
616
672
|
}
|
|
617
673
|
const patchMac = decodeProtoBytes(patch.patchMac, `patch.patchMac (${collection})`);
|
|
618
|
-
const expectedPatchMac = await this.crypto.generatePatchMac(patchKeyData, snapshotMac,
|
|
674
|
+
const expectedPatchMac = await this.crypto.generatePatchMac(patchKeyData, snapshotMac, valueMacs, patchVersion, collection);
|
|
619
675
|
if (!uint8Equal(expectedPatchMac, patchMac)) {
|
|
620
676
|
throw new Error(`patch MAC mismatch for ${collection}`);
|
|
621
677
|
}
|
|
622
678
|
}
|
|
623
|
-
async buildOutgoingPatch(collection, snapshot, pendingMutations) {
|
|
624
|
-
const activeKey = await this.store.getActiveSyncKey();
|
|
679
|
+
async buildOutgoingPatch(collection, snapshot, pendingMutations, activeKey) {
|
|
625
680
|
if (!activeKey) {
|
|
626
681
|
throw new WaAppStateMissingKeyError(`no sync key available to upload ${collection}`, null, collection);
|
|
627
682
|
}
|
|
@@ -640,29 +695,39 @@ export class WaAppStateSyncClient {
|
|
|
640
695
|
});
|
|
641
696
|
return { operationCode, encrypted };
|
|
642
697
|
}));
|
|
643
|
-
const encryptedMutations = encryptedResults.
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
698
|
+
const encryptedMutations = new Array(encryptedResults.length);
|
|
699
|
+
const macMutations = new Array(encryptedResults.length);
|
|
700
|
+
const valueMacs = new Array(encryptedResults.length);
|
|
701
|
+
for (let i = 0; i < encryptedResults.length; i += 1) {
|
|
702
|
+
const { operationCode, encrypted } = encryptedResults[i];
|
|
703
|
+
encryptedMutations[i] = {
|
|
704
|
+
operation: operationCode,
|
|
705
|
+
record: {
|
|
706
|
+
keyId: { id: activeKey.keyId },
|
|
707
|
+
index: { blob: encrypted.indexMac },
|
|
708
|
+
value: { blob: encrypted.valueBlob }
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
macMutations[i] = {
|
|
712
|
+
operation: operationCode,
|
|
713
|
+
indexMac: encrypted.indexMac,
|
|
714
|
+
valueMac: encrypted.valueMac
|
|
715
|
+
};
|
|
716
|
+
valueMacs[i] = encrypted.valueMac;
|
|
717
|
+
}
|
|
656
718
|
const nextState = await this.computeNextCollectionState(snapshot.hash, snapshot.indexValueMap, macMutations, collection);
|
|
657
719
|
const patchVersion = snapshot.version + 1;
|
|
658
720
|
const snapshotMac = await this.crypto.generateSnapshotMac(activeKey.keyData, nextState.hash, patchVersion, collection);
|
|
659
|
-
const patchMac = await this.crypto.generatePatchMac(activeKey.keyData, snapshotMac,
|
|
721
|
+
const patchMac = await this.crypto.generatePatchMac(activeKey.keyData, snapshotMac, valueMacs, patchVersion, collection);
|
|
722
|
+
const deviceIndex = this.resolveDeviceIndex();
|
|
723
|
+
const clientDebugData = this.buildPatchClientDebugData();
|
|
660
724
|
const encodedPatch = proto.SyncdPatch.encode({
|
|
661
|
-
version: { version: patchVersion },
|
|
662
725
|
mutations: encryptedMutations,
|
|
663
726
|
snapshotMac,
|
|
664
727
|
patchMac,
|
|
665
|
-
keyId: { id: activeKey.keyId }
|
|
728
|
+
keyId: { id: activeKey.keyId },
|
|
729
|
+
...(deviceIndex === undefined ? {} : { deviceIndex }),
|
|
730
|
+
clientDebugData
|
|
666
731
|
}).finish();
|
|
667
732
|
return {
|
|
668
733
|
encodedPatch,
|
|
@@ -674,13 +739,35 @@ export class WaAppStateSyncClient {
|
|
|
674
739
|
}
|
|
675
740
|
};
|
|
676
741
|
}
|
|
742
|
+
resolveDeviceIndex() {
|
|
743
|
+
const meJid = this.getCurrentMeJid?.();
|
|
744
|
+
if (!meJid) {
|
|
745
|
+
return undefined;
|
|
746
|
+
}
|
|
747
|
+
try {
|
|
748
|
+
return parseSignalAddressFromJid(meJid).device;
|
|
749
|
+
}
|
|
750
|
+
catch (error) {
|
|
751
|
+
this.logger.debug('app-state could not parse device index from me jid', {
|
|
752
|
+
meJid
|
|
753
|
+
});
|
|
754
|
+
void error;
|
|
755
|
+
return undefined;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
buildPatchClientDebugData() {
|
|
759
|
+
return proto.PatchDebugData.encode({
|
|
760
|
+
isSenderPrimary: false,
|
|
761
|
+
senderPlatform: proto.PatchDebugData.Platform.WEB
|
|
762
|
+
}).finish();
|
|
763
|
+
}
|
|
677
764
|
async computeNextCollectionState(baseHash, baseMap, mutations, collection) {
|
|
678
765
|
const indexValueMap = new Map(baseMap);
|
|
679
766
|
const addValues = [];
|
|
680
767
|
const removeValues = [];
|
|
681
768
|
let missingRemoveCount = 0;
|
|
682
769
|
for (const mutation of mutations) {
|
|
683
|
-
const indexMacHex =
|
|
770
|
+
const indexMacHex = bytesToHex(mutation.indexMac);
|
|
684
771
|
const existing = indexValueMap.get(indexMacHex);
|
|
685
772
|
if (mutation.operation === proto.SyncdMutation.SyncdOperation.REMOVE) {
|
|
686
773
|
if (!existing) {
|
|
@@ -745,9 +832,33 @@ export class WaAppStateSyncClient {
|
|
|
745
832
|
}
|
|
746
833
|
return compacted;
|
|
747
834
|
}
|
|
835
|
+
async preloadKeyData(keyIds) {
|
|
836
|
+
if (keyIds.length === 0) {
|
|
837
|
+
return;
|
|
838
|
+
}
|
|
839
|
+
const context = this.requireSyncContext();
|
|
840
|
+
const missingKeyIds = [];
|
|
841
|
+
const missingKeyHexes = new Set();
|
|
842
|
+
for (let index = 0; index < keyIds.length; index += 1) {
|
|
843
|
+
const keyId = keyIds[index];
|
|
844
|
+
const keyHex = bytesToHex(keyId);
|
|
845
|
+
if (context.keys.has(keyHex) || missingKeyHexes.has(keyHex)) {
|
|
846
|
+
continue;
|
|
847
|
+
}
|
|
848
|
+
missingKeyHexes.add(keyHex);
|
|
849
|
+
missingKeyIds.push(keyId);
|
|
850
|
+
}
|
|
851
|
+
if (missingKeyIds.length === 0) {
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
const loadedKeyData = await this.store.getSyncKeyDataBatch(missingKeyIds);
|
|
855
|
+
for (let index = 0; index < missingKeyIds.length; index += 1) {
|
|
856
|
+
context.keys.set(bytesToHex(missingKeyIds[index]), loadedKeyData[index] ?? null);
|
|
857
|
+
}
|
|
858
|
+
}
|
|
748
859
|
async getKeyData(keyId) {
|
|
749
860
|
const context = this.requireSyncContext();
|
|
750
|
-
const keyHex =
|
|
861
|
+
const keyHex = bytesToHex(keyId);
|
|
751
862
|
if (context.keys.has(keyHex)) {
|
|
752
863
|
return context.keys.get(keyHex) ?? null;
|
|
753
864
|
}
|
|
@@ -768,6 +879,7 @@ export class WaAppStateSyncClient {
|
|
|
768
879
|
setCollectionState(collection, version, hash, indexValueMap) {
|
|
769
880
|
const context = this.requireSyncContext();
|
|
770
881
|
context.collections.set(collection, {
|
|
882
|
+
initialized: true,
|
|
771
883
|
version,
|
|
772
884
|
hash,
|
|
773
885
|
indexValueMap
|