zapo-js 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -3
- package/dist/appstate/WaAppStateCrypto.js +49 -41
- package/dist/appstate/WaAppStateSyncClient.js +79 -42
- package/dist/appstate/index.js +2 -2
- package/dist/auth/WaAuthClient.js +20 -11
- package/dist/auth/{flow/WaAuthCredentialsFlow.js → credentials-flow.js} +83 -18
- package/dist/auth/pairing/WaPairingFlow.js +26 -29
- package/dist/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +29 -13
- package/dist/client/WaClient.js +115 -75
- package/dist/client/WaClientFactory.js +113 -30
- package/dist/client/connection/WaConnectionManager.js +4 -1
- package/dist/client/coordinators/WaAbPropsCoordinator.js +141 -0
- package/dist/client/coordinators/WaBusinessCoordinator.js +3 -12
- package/dist/client/coordinators/WaEmailCoordinator.js +63 -0
- package/dist/client/coordinators/WaIncomingNodeCoordinator.js +33 -8
- package/dist/client/coordinators/WaMessageDispatchCoordinator.js +55 -25
- package/dist/client/coordinators/WaOfflineResumeCoordinator.js +114 -0
- package/dist/client/coordinators/WaPassiveTasksCoordinator.js +38 -20
- package/dist/client/coordinators/WaProfileCoordinator.js +3 -1
- package/dist/client/coordinators/WaRetryCoordinator.js +11 -9
- package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +22 -4
- package/dist/client/dirty.js +1 -1
- package/dist/client/events/abprops.js +43 -0
- package/dist/client/events/privacy-token.js +1 -2
- package/dist/client/events/registration.js +42 -0
- package/dist/client/incoming.js +37 -0
- package/dist/client/mailbox.js +17 -1
- package/dist/client/media.js +243 -0
- package/dist/client/messages.js +163 -86
- package/dist/crypto/core/index.js +4 -1
- package/dist/crypto/core/random.js +3 -9
- package/dist/crypto/core/xeddsa.js +57 -0
- package/dist/crypto/curves/X25519.js +18 -0
- package/dist/crypto/curves/constants.js +2 -1
- package/dist/esm/appstate/WaAppStateCrypto.js +39 -31
- package/dist/esm/appstate/WaAppStateSyncClient.js +68 -31
- package/dist/esm/appstate/index.js +1 -1
- package/dist/esm/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +1 -1
- package/dist/esm/auth/WaAuthClient.js +17 -8
- package/dist/esm/auth/{flow/WaAuthCredentialsFlow.js → credentials-flow.js} +83 -18
- package/dist/esm/auth/pairing/WaPairingFlow.js +25 -28
- package/dist/esm/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +20 -6
- package/dist/esm/client/WaClient.js +116 -76
- package/dist/esm/client/WaClientFactory.js +114 -31
- package/dist/esm/client/connection/WaConnectionManager.js +4 -1
- package/dist/esm/client/coordinators/WaAbPropsCoordinator.js +137 -0
- package/dist/esm/client/coordinators/WaBusinessCoordinator.js +4 -13
- package/dist/esm/client/coordinators/WaEmailCoordinator.js +60 -0
- package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +35 -10
- package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +47 -17
- package/dist/esm/client/coordinators/WaOfflineResumeCoordinator.js +110 -0
- package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +38 -20
- package/dist/esm/client/coordinators/WaProfileCoordinator.js +3 -1
- package/dist/esm/client/coordinators/WaRetryCoordinator.js +11 -9
- package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +24 -6
- package/dist/esm/client/dirty.js +1 -1
- package/dist/esm/client/events/abprops.js +40 -0
- package/dist/esm/client/events/privacy-token.js +1 -2
- package/dist/esm/client/events/registration.js +39 -0
- package/dist/esm/client/incoming.js +36 -0
- package/dist/esm/client/mailbox.js +17 -1
- package/dist/esm/client/media.js +234 -0
- package/dist/esm/client/messages.js +162 -85
- package/dist/esm/crypto/core/index.js +1 -0
- package/dist/esm/crypto/core/random.js +2 -7
- package/dist/esm/crypto/core/xeddsa.js +53 -0
- package/dist/esm/crypto/curves/X25519.js +20 -2
- package/dist/esm/crypto/curves/constants.js +1 -0
- package/dist/esm/infra/perf/StoreLock.js +7 -4
- package/dist/esm/media/WaMediaCrypto.js +257 -62
- package/dist/esm/media/WaMediaTransferClient.js +47 -190
- package/dist/esm/media/constants.js +2 -0
- package/dist/esm/media/processor.js +1 -0
- package/dist/esm/message/addon-crypto.js +130 -3
- package/dist/esm/message/content.js +12 -6
- package/dist/esm/message/icdc.js +8 -8
- package/dist/esm/message/incoming.js +14 -12
- package/dist/esm/message/phash.js +32 -12
- package/dist/esm/message/reporting-token.js +3 -3
- package/dist/esm/message/use-case-secret.js +1 -1
- package/dist/esm/protocol/abprops.js +159 -0
- package/dist/esm/protocol/browser.js +14 -0
- package/dist/esm/protocol/constants.js +3 -1
- package/dist/esm/protocol/email.js +30 -0
- package/dist/esm/protocol/jid.js +44 -10
- package/dist/esm/protocol/nodes.js +6 -2
- package/dist/esm/protocol/notification.js +7 -1
- package/dist/esm/retry/reason.js +1 -1
- package/dist/esm/signal/api/SignalDeviceSyncApi.js +5 -2
- package/dist/esm/signal/api/SignalDigestSyncApi.js +8 -6
- package/dist/esm/signal/api/SignalIdentitySyncApi.js +4 -4
- package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +1 -1
- package/dist/esm/signal/api/SignalSessionSyncApi.js +1 -1
- package/dist/esm/signal/crypto/WaAdvSignature.js +5 -51
- package/dist/esm/signal/crypto/constants.js +0 -4
- package/dist/esm/signal/encoding.js +11 -54
- package/dist/esm/signal/group/SenderKeyChain.js +3 -3
- package/dist/esm/signal/group/SenderKeyCodec.js +5 -6
- package/dist/esm/signal/group/SenderKeyManager.js +13 -10
- package/dist/esm/signal/registration/keygen.js +2 -3
- package/dist/esm/signal/registration/utils.js +2 -2
- package/dist/esm/signal/session/SignalProtocol.js +18 -17
- package/dist/esm/signal/session/SignalRatchet.js +21 -10
- package/dist/esm/signal/session/SignalSerializer.js +5 -6
- package/dist/esm/signal/session/SignalSession.js +11 -9
- package/dist/esm/signal/session/resolver.js +6 -6
- package/dist/esm/store/contracts/identity.store.js +1 -0
- package/dist/esm/store/contracts/message-secret.store.js +1 -0
- package/dist/esm/store/contracts/pre-key.store.js +1 -0
- package/dist/esm/store/contracts/session.store.js +1 -0
- package/dist/esm/store/createStore.js +48 -12
- package/dist/esm/store/index.js +4 -0
- package/dist/esm/store/locks/identity.lock.js +16 -0
- package/dist/esm/store/locks/message-secret.lock.js +17 -0
- package/dist/esm/store/locks/pre-key.lock.js +27 -0
- package/dist/esm/store/locks/session.lock.js +19 -0
- package/dist/esm/store/locks/signal.lock.js +0 -24
- package/dist/esm/store/noop.store.js +20 -0
- package/dist/esm/store/providers/memory/device-list.store.js +3 -0
- package/dist/esm/store/providers/memory/identity.store.js +31 -0
- package/dist/esm/store/providers/memory/message-secret.store.js +81 -0
- package/dist/esm/store/providers/memory/participants.store.js +3 -0
- package/dist/esm/store/providers/memory/pre-key.store.js +97 -0
- package/dist/esm/store/providers/memory/retry.store.js +25 -11
- package/dist/esm/store/providers/memory/session.store.js +45 -0
- package/dist/esm/store/providers/memory/signal.store.js +1 -164
- package/dist/esm/transport/WaComms.js +4 -3
- package/dist/esm/transport/WaWebSocket.js +9 -1
- package/dist/esm/transport/index.js +6 -0
- package/dist/esm/transport/keepalive/WaKeepAlive.js +17 -8
- package/dist/esm/transport/node/WaMobileTcpSocket.js +114 -0
- package/dist/esm/transport/node/WaNodeOrchestrator.js +17 -8
- package/dist/esm/transport/node/builders/abprops.js +20 -0
- package/dist/esm/transport/node/builders/device.js +11 -0
- package/dist/esm/transport/node/builders/email.js +65 -0
- package/dist/esm/transport/node/builders/offline.js +14 -0
- package/dist/esm/transport/node/builders/prekeys.js +37 -40
- package/dist/esm/transport/node/builders/presence.js +13 -0
- package/dist/esm/transport/node/builders/privacy-token.js +19 -23
- package/dist/esm/transport/node/builders/retry.js +1 -1
- package/dist/esm/transport/node/helpers.js +24 -0
- package/dist/esm/transport/node/mex/argo-decoder.js +152 -0
- package/dist/esm/transport/node/mex/client.js +83 -0
- package/dist/esm/transport/node/mex/persist-ids.js +10 -0
- package/dist/esm/transport/noise/WaClientPayload.js +15 -10
- package/dist/esm/transport/noise/WaFrameCodec.js +2 -2
- package/dist/esm/transport/noise/WaMobileClientPayload.js +53 -0
- package/dist/esm/transport/noise/WaNoiseCert.js +9 -27
- package/dist/esm/transport/noise/WaNoiseSession.js +12 -11
- package/dist/infra/perf/StoreLock.js +7 -4
- package/dist/media/WaMediaCrypto.js +253 -58
- package/dist/media/WaMediaTransferClient.js +50 -223
- package/dist/media/constants.js +3 -1
- package/dist/media/processor.js +2 -0
- package/dist/message/addon-crypto.js +131 -0
- package/dist/message/content.js +13 -5
- package/dist/message/icdc.js +8 -8
- package/dist/message/incoming.js +14 -12
- package/dist/message/phash.js +32 -12
- package/dist/message/reporting-token.js +2 -2
- package/dist/message/use-case-secret.js +1 -1
- package/dist/protocol/abprops.js +163 -0
- package/dist/protocol/browser.js +15 -0
- package/dist/protocol/constants.js +14 -2
- package/dist/protocol/email.js +33 -0
- package/dist/protocol/jid.js +45 -10
- package/dist/protocol/nodes.js +6 -2
- package/dist/protocol/notification.js +8 -2
- package/dist/retry/reason.js +1 -1
- package/dist/signal/api/SignalDeviceSyncApi.js +5 -2
- package/dist/signal/api/SignalDigestSyncApi.js +8 -6
- package/dist/signal/api/SignalIdentitySyncApi.js +4 -4
- package/dist/signal/crypto/WaAdvSignature.js +2 -50
- package/dist/signal/crypto/constants.js +1 -5
- package/dist/signal/encoding.js +11 -49
- package/dist/signal/group/SenderKeyChain.js +2 -2
- package/dist/signal/group/SenderKeyCodec.js +4 -5
- package/dist/signal/group/SenderKeyManager.js +12 -9
- package/dist/signal/registration/keygen.js +1 -2
- package/dist/signal/registration/utils.js +2 -2
- package/dist/signal/session/SignalProtocol.js +18 -17
- package/dist/signal/session/SignalRatchet.js +19 -8
- package/dist/signal/session/SignalSerializer.js +5 -6
- package/dist/signal/session/SignalSession.js +11 -9
- package/dist/signal/session/resolver.js +6 -6
- package/dist/store/contracts/identity.store.js +2 -0
- package/dist/store/contracts/message-secret.store.js +2 -0
- package/dist/store/contracts/pre-key.store.js +2 -0
- package/dist/store/contracts/session.store.js +2 -0
- package/dist/store/createStore.js +47 -11
- package/dist/store/index.js +9 -1
- package/dist/store/locks/identity.lock.js +19 -0
- package/dist/store/locks/message-secret.lock.js +20 -0
- package/dist/store/locks/pre-key.lock.js +30 -0
- package/dist/store/locks/session.lock.js +22 -0
- package/dist/store/locks/signal.lock.js +0 -24
- package/dist/store/noop.store.js +21 -1
- package/dist/store/providers/memory/device-list.store.js +3 -0
- package/dist/store/providers/memory/identity.store.js +35 -0
- package/dist/store/providers/memory/message-secret.store.js +85 -0
- package/dist/store/providers/memory/participants.store.js +3 -0
- package/dist/store/providers/memory/pre-key.store.js +101 -0
- package/dist/store/providers/memory/retry.store.js +24 -10
- package/dist/store/providers/memory/session.store.js +49 -0
- package/dist/store/providers/memory/signal.store.js +1 -164
- package/dist/transport/WaComms.js +4 -3
- package/dist/transport/WaWebSocket.js +9 -1
- package/dist/transport/index.js +17 -1
- package/dist/transport/keepalive/WaKeepAlive.js +17 -8
- package/dist/transport/node/WaMobileTcpSocket.js +118 -0
- package/dist/transport/node/WaNodeOrchestrator.js +16 -7
- package/dist/transport/node/builders/abprops.js +23 -0
- package/dist/transport/node/builders/device.js +14 -0
- package/dist/transport/node/builders/email.js +72 -0
- package/dist/transport/node/builders/offline.js +17 -0
- package/dist/transport/node/builders/prekeys.js +36 -39
- package/dist/transport/node/builders/presence.js +16 -0
- package/dist/transport/node/builders/privacy-token.js +18 -22
- package/dist/transport/node/builders/retry.js +1 -1
- package/dist/transport/node/helpers.js +26 -0
- package/dist/transport/node/mex/argo-decoder.js +189 -0
- package/dist/transport/node/mex/client.js +86 -0
- package/dist/transport/node/mex/persist-ids.js +13 -0
- package/dist/transport/noise/WaClientPayload.js +14 -9
- package/dist/transport/noise/WaFrameCodec.js +1 -1
- package/dist/transport/noise/WaMobileClientPayload.js +56 -0
- package/dist/transport/noise/WaNoiseCert.js +8 -26
- package/dist/transport/noise/WaNoiseSession.js +11 -10
- package/dist/types/appstate/WaAppStateCrypto.d.ts +11 -8
- package/dist/types/appstate/WaAppStateSyncClient.d.ts +6 -2
- package/dist/types/appstate/index.d.ts +1 -1
- package/dist/types/appstate/{WaAppStateSyncResponseParser.d.ts → response-parser.d.ts} +1 -1
- package/dist/types/appstate/types.d.ts +1 -1
- package/dist/types/auth/WaAuthClient.d.ts +9 -3
- package/dist/types/auth/credentials-flow.d.ts +20 -0
- package/dist/types/auth/pairing/WaPairingFlow.d.ts +3 -2
- package/dist/types/auth/pairing/{WaPairingCodeCrypto.d.ts → pairing-code-crypto.d.ts} +6 -1
- package/dist/types/auth/types.d.ts +40 -0
- package/dist/types/client/WaClient.d.ts +19 -8
- package/dist/types/client/WaClientFactory.d.ts +10 -4
- package/dist/types/client/coordinators/WaAbPropsCoordinator.d.ts +26 -0
- package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +1 -1
- package/dist/types/client/coordinators/WaEmailCoordinator.d.ts +24 -0
- package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +6 -1
- package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +15 -2
- package/dist/types/client/coordinators/WaOfflineResumeCoordinator.d.ts +31 -0
- package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +13 -2
- package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +1 -1
- package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +4 -2
- package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +6 -0
- package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +11 -1
- package/dist/types/client/dirty.d.ts +3 -1
- package/dist/types/client/events/abprops.d.ts +14 -0
- package/dist/types/client/events/registration.d.ts +17 -0
- package/dist/types/client/incoming.d.ts +6 -1
- package/dist/types/client/mailbox.d.ts +2 -0
- package/dist/types/client/media.d.ts +31 -0
- package/dist/types/client/messages.d.ts +2 -0
- package/dist/types/client/persistence/WriteBehindPersistence.d.ts +1 -1
- package/dist/types/client/types.d.ts +100 -1
- package/dist/types/crypto/core/index.d.ts +1 -0
- package/dist/types/crypto/core/primitives.d.ts +1 -1
- package/dist/types/crypto/core/random.d.ts +1 -1
- package/dist/types/crypto/core/xeddsa.d.ts +2 -0
- package/dist/types/crypto/curves/constants.d.ts +1 -0
- package/dist/types/crypto/index.d.ts +1 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/infra/log/ConsoleLogger.d.ts +1 -1
- package/dist/types/infra/log/PinoLogger.d.ts +1 -1
- package/dist/types/infra/perf/StoreLock.d.ts +1 -0
- package/dist/types/media/WaMediaCrypto.d.ts +15 -6
- package/dist/types/media/WaMediaTransferClient.d.ts +3 -11
- package/dist/types/media/constants.d.ts +2 -0
- package/dist/types/media/index.d.ts +1 -0
- package/dist/types/media/processor.d.ts +28 -0
- package/dist/types/media/types.d.ts +9 -3
- package/dist/types/message/addon-crypto.d.ts +34 -3
- package/dist/types/message/content.d.ts +3 -1
- package/dist/types/message/icdc.d.ts +4 -4
- package/dist/types/message/types.d.ts +16 -24
- package/dist/types/protocol/abprops.d.ts +142 -0
- package/dist/types/protocol/browser.d.ts +1 -0
- package/dist/types/protocol/constants.d.ts +5 -1
- package/dist/types/protocol/email.d.ts +32 -0
- package/dist/types/protocol/jid.d.ts +1 -0
- package/dist/types/protocol/nodes.d.ts +4 -0
- package/dist/types/protocol/notification.d.ts +6 -0
- package/dist/types/protocol/stream.d.ts +1 -0
- package/dist/types/retry/reason.d.ts +1 -1
- package/dist/types/signal/api/SignalDigestSyncApi.d.ts +3 -0
- package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +3 -3
- package/dist/types/signal/crypto/WaAdvSignature.d.ts +0 -2
- package/dist/types/signal/crypto/constants.d.ts +0 -1
- package/dist/types/signal/encoding.d.ts +7 -1
- package/dist/types/signal/group/SenderKeyChain.d.ts +1 -1
- package/dist/types/signal/group/SenderKeyManager.d.ts +7 -2
- package/dist/types/signal/registration/utils.d.ts +2 -1
- package/dist/types/signal/session/SignalProtocol.d.ts +11 -2
- package/dist/types/signal/session/SignalSerializer.d.ts +2 -1
- package/dist/types/signal/session/resolver.d.ts +4 -2
- package/dist/types/signal/types.d.ts +16 -4
- package/dist/types/store/contracts/identity.store.d.ts +11 -0
- package/dist/types/store/contracts/message-secret.store.d.ts +16 -0
- package/dist/types/store/contracts/pre-key.store.d.ts +13 -0
- package/dist/types/store/contracts/session.store.d.ts +14 -0
- package/dist/types/store/contracts/signal.store.d.ts +1 -34
- package/dist/types/store/index.d.ts +9 -1
- package/dist/types/store/locks/identity.lock.d.ts +3 -0
- package/dist/types/store/locks/message-secret.lock.d.ts +3 -0
- package/dist/types/store/locks/pre-key.lock.d.ts +3 -0
- package/dist/types/store/locks/session.lock.d.ts +3 -0
- package/dist/types/store/noop.store.d.ts +4 -0
- package/dist/types/store/providers/memory/identity.store.d.ts +18 -0
- package/dist/types/store/providers/memory/message-secret.store.d.ts +21 -0
- package/dist/types/store/providers/memory/pre-key.store.d.ts +23 -0
- package/dist/types/store/providers/memory/retry.store.d.ts +7 -1
- package/dist/types/store/providers/memory/session.store.d.ts +21 -0
- package/dist/types/store/providers/memory/signal.store.d.ts +3 -45
- package/dist/types/store/providers/memory/thread.store.d.ts +1 -1
- package/dist/types/store/types.d.ts +21 -1
- package/dist/types/transport/WaWebSocket.d.ts +1 -0
- package/dist/types/transport/index.d.ts +8 -1
- package/dist/types/transport/keepalive/WaKeepAlive.d.ts +4 -1
- package/dist/types/transport/node/WaMobileTcpSocket.d.ts +18 -0
- package/dist/types/transport/node/WaNodeOrchestrator.d.ts +6 -2
- package/dist/types/transport/node/builders/abprops.d.ts +5 -0
- package/dist/types/transport/node/builders/device.d.ts +2 -0
- package/dist/types/transport/node/builders/email.d.ts +11 -0
- package/dist/types/transport/node/builders/offline.d.ts +2 -0
- package/dist/types/transport/node/builders/prekeys.d.ts +4 -3
- package/dist/types/transport/node/builders/presence.d.ts +6 -0
- package/dist/types/transport/node/helpers.d.ts +3 -0
- package/dist/types/transport/node/mex/argo-decoder.d.ts +11 -0
- package/dist/types/transport/node/mex/client.d.ts +18 -0
- package/dist/types/transport/node/mex/persist-ids.d.ts +14 -0
- package/dist/types/transport/noise/WaMobileClientPayload.d.ts +29 -0
- package/dist/types/transport/noise/WaNoiseCert.d.ts +7 -1
- package/dist/types/transport/noise/WaNoiseSession.d.ts +1 -0
- package/dist/types/transport/types.d.ts +8 -0
- package/package.json +6 -4
- package/dist/auth/pairing/constants.js +0 -5
- package/dist/client/connection/WaKeyShareCoordinator.js +0 -63
- package/dist/esm/auth/pairing/constants.js +0 -2
- package/dist/esm/client/connection/WaKeyShareCoordinator.js +0 -59
- package/dist/esm/transport/node/builders/index.js +0 -11
- package/dist/transport/node/builders/index.js +0 -51
- package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +0 -14
- package/dist/types/auth/pairing/constants.d.ts +0 -2
- package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +0 -14
- package/dist/types/transport/node/builders/index.d.ts +0 -11
- /package/dist/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +0 -0
package/README.md
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
<
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src=".github/assets/logo.png" alt="zapo" width="400" />
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
5
|
<p align="center">
|
|
4
6
|
<strong>High-performance TypeScript implementation of the WhatsApp Web protocol.</strong><br />
|
|
@@ -129,12 +131,14 @@ const store = createStore({
|
|
|
129
131
|
providers: {
|
|
130
132
|
auth: 'sqlite',
|
|
131
133
|
signal: 'sqlite',
|
|
134
|
+
preKey: 'sqlite',
|
|
135
|
+
session: 'sqlite',
|
|
136
|
+
identity: 'sqlite',
|
|
132
137
|
senderKey: 'sqlite',
|
|
133
138
|
appState: 'sqlite',
|
|
134
139
|
messages: 'sqlite',
|
|
135
140
|
threads: 'sqlite',
|
|
136
|
-
contacts: 'sqlite'
|
|
137
|
-
privacyToken: 'sqlite'
|
|
141
|
+
contacts: 'sqlite'
|
|
138
142
|
}
|
|
139
143
|
})
|
|
140
144
|
|
|
@@ -8,14 +8,17 @@ const random_1 = require("../crypto/core/random");
|
|
|
8
8
|
const _proto_1 = require("../proto.js");
|
|
9
9
|
const constants_2 = require("../protocol/constants");
|
|
10
10
|
const bytes_1 = require("../util/bytes");
|
|
11
|
-
const bytes_2 = require("../util/bytes");
|
|
12
11
|
const collections_1 = require("../util/collections");
|
|
13
12
|
const primitives_2 = require("../util/primitives");
|
|
14
13
|
const DEFAULT_DERIVED_KEYS_CACHE_MAX_SIZE = 256;
|
|
15
14
|
class WaAppStateCrypto {
|
|
16
|
-
constructor(derivedKeysCacheMaxSize = DEFAULT_DERIVED_KEYS_CACHE_MAX_SIZE) {
|
|
15
|
+
constructor(derivedKeysCacheMaxSize = DEFAULT_DERIVED_KEYS_CACHE_MAX_SIZE, skipMacVerification = false) {
|
|
17
16
|
this.derivedKeysCache = new Map();
|
|
18
17
|
this.derivedKeysCacheMaxSize = (0, primitives_2.normalizeNonNegativeInteger)(derivedKeysCacheMaxSize, DEFAULT_DERIVED_KEYS_CACHE_MAX_SIZE);
|
|
18
|
+
this.skipMacVerification = skipMacVerification;
|
|
19
|
+
}
|
|
20
|
+
get isMacVerificationSkipped() {
|
|
21
|
+
return this.skipMacVerification;
|
|
19
22
|
}
|
|
20
23
|
clearCache() {
|
|
21
24
|
this.derivedKeysCache.clear();
|
|
@@ -28,45 +31,50 @@ class WaAppStateCrypto {
|
|
|
28
31
|
return cached;
|
|
29
32
|
}
|
|
30
33
|
const derived = await (0, hkdf_1.hkdf)(keyData, null, constants_2.WA_APP_STATE_KDF_INFO.MUTATION_KEYS, constants_1.APP_STATE_DERIVED_KEY_LENGTH);
|
|
34
|
+
const [indexHmacKey, valueEncryptionAesKey, valueMacHmacKey, snapshotMacHmacKey, patchMacHmacKey] = await Promise.all([
|
|
35
|
+
(0, primitives_1.importHmacKey)(derived.subarray(0, constants_1.APP_STATE_DERIVED_INDEX_KEY_END)),
|
|
36
|
+
(0, primitives_1.importAesCbcKey)(derived.subarray(constants_1.APP_STATE_DERIVED_INDEX_KEY_END, constants_1.APP_STATE_DERIVED_VALUE_ENCRYPTION_KEY_END)),
|
|
37
|
+
(0, primitives_1.importHmacSha512Key)(derived.subarray(constants_1.APP_STATE_DERIVED_VALUE_ENCRYPTION_KEY_END, constants_1.APP_STATE_DERIVED_VALUE_MAC_KEY_END)),
|
|
38
|
+
(0, primitives_1.importHmacKey)(derived.subarray(constants_1.APP_STATE_DERIVED_VALUE_MAC_KEY_END, constants_1.APP_STATE_DERIVED_SNAPSHOT_MAC_KEY_END)),
|
|
39
|
+
(0, primitives_1.importHmacKey)(derived.subarray(constants_1.APP_STATE_DERIVED_SNAPSHOT_MAC_KEY_END, constants_1.APP_STATE_DERIVED_PATCH_MAC_KEY_END))
|
|
40
|
+
]);
|
|
31
41
|
const keys = {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
indexHmacKey,
|
|
43
|
+
valueEncryptionAesKey,
|
|
44
|
+
valueMacHmacKey,
|
|
45
|
+
snapshotMacHmacKey,
|
|
46
|
+
patchMacHmacKey
|
|
37
47
|
};
|
|
38
48
|
this.touchDerivedKeysCacheEntry(cacheKey, keys);
|
|
39
49
|
return keys;
|
|
40
50
|
}
|
|
41
|
-
async generateIndexMac(
|
|
42
|
-
|
|
43
|
-
return (0, primitives_1.hmacSign)(key, indexBytes);
|
|
51
|
+
async generateIndexMac(indexHmacKey, indexBytes) {
|
|
52
|
+
return (0, primitives_1.hmacSign)(indexHmacKey, indexBytes);
|
|
44
53
|
}
|
|
45
54
|
async encryptMutation(args) {
|
|
46
55
|
const derivedKeys = await this.deriveKeys(args.keyData);
|
|
47
|
-
const indexBytes =
|
|
56
|
+
const indexBytes = bytes_1.TEXT_ENCODER.encode(args.index);
|
|
48
57
|
const encoded = _proto_1.proto.SyncActionData.encode({
|
|
49
58
|
index: indexBytes,
|
|
50
59
|
value: args.value ?? undefined,
|
|
51
|
-
padding:
|
|
60
|
+
padding: bytes_1.EMPTY_BYTES,
|
|
52
61
|
version: args.version
|
|
53
62
|
}).finish();
|
|
54
63
|
const iv = args.iv ?? (await (0, random_1.randomBytesAsync)(constants_1.APP_STATE_IV_LENGTH));
|
|
55
64
|
if (iv.byteLength !== constants_1.APP_STATE_IV_LENGTH) {
|
|
56
65
|
throw new Error(`invalid IV length ${iv.byteLength}`);
|
|
57
66
|
}
|
|
58
|
-
const indexMacPromise = this.generateIndexMac(derivedKeys.
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
const cipherWithIv = (0, bytes_2.concatBytes)([iv, cipherText]);
|
|
67
|
+
const indexMacPromise = this.generateIndexMac(derivedKeys.indexHmacKey, indexBytes);
|
|
68
|
+
const cipherText = await (0, primitives_1.aesCbcEncrypt)(derivedKeys.valueEncryptionAesKey, iv, encoded);
|
|
69
|
+
const cipherWithIv = (0, bytes_1.concatBytes)([iv, cipherText]);
|
|
62
70
|
const associatedData = this.generateAssociatedData(args.operation, args.keyId);
|
|
63
71
|
const [valueMac, indexMac] = await Promise.all([
|
|
64
|
-
this.generateValueMac(derivedKeys.
|
|
72
|
+
this.generateValueMac(derivedKeys.valueMacHmacKey, associatedData, cipherWithIv),
|
|
65
73
|
indexMacPromise
|
|
66
74
|
]);
|
|
67
75
|
return {
|
|
68
76
|
indexMac,
|
|
69
|
-
valueBlob: (0,
|
|
77
|
+
valueBlob: (0, bytes_1.concatBytes)([cipherWithIv, valueMac]),
|
|
70
78
|
valueMac
|
|
71
79
|
};
|
|
72
80
|
}
|
|
@@ -79,13 +87,14 @@ class WaAppStateCrypto {
|
|
|
79
87
|
const mac = args.valueBlob.subarray(args.valueBlob.byteLength - constants_1.APP_STATE_VALUE_MAC_LENGTH);
|
|
80
88
|
const cipherText = args.valueBlob.subarray(constants_1.APP_STATE_IV_LENGTH, args.valueBlob.byteLength - constants_1.APP_STATE_VALUE_MAC_LENGTH);
|
|
81
89
|
const cipherWithIv = args.valueBlob.subarray(0, args.valueBlob.byteLength - constants_1.APP_STATE_VALUE_MAC_LENGTH);
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
90
|
+
if (!this.skipMacVerification) {
|
|
91
|
+
const associatedData = this.generateAssociatedData(args.operation, args.keyId);
|
|
92
|
+
const expectedMac = await this.generateValueMac(derivedKeys.valueMacHmacKey, associatedData, cipherWithIv);
|
|
93
|
+
if (!(0, bytes_1.uint8TimingSafeEqual)(mac, expectedMac)) {
|
|
94
|
+
throw new Error('mutation value MAC mismatch');
|
|
95
|
+
}
|
|
86
96
|
}
|
|
87
|
-
const
|
|
88
|
-
const plaintext = await (0, primitives_1.aesCbcDecrypt)(decryptionKey, iv, cipherText);
|
|
97
|
+
const plaintext = await (0, primitives_1.aesCbcDecrypt)(derivedKeys.valueEncryptionAesKey, iv, cipherText);
|
|
89
98
|
const syncActionData = _proto_1.proto.SyncActionData.decode(plaintext);
|
|
90
99
|
if (!syncActionData.index) {
|
|
91
100
|
throw new Error('missing sync action index');
|
|
@@ -93,12 +102,14 @@ class WaAppStateCrypto {
|
|
|
93
102
|
if (syncActionData.version === null || syncActionData.version === undefined) {
|
|
94
103
|
throw new Error('missing sync action version');
|
|
95
104
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
105
|
+
if (!this.skipMacVerification) {
|
|
106
|
+
const generatedIndexMac = await this.generateIndexMac(derivedKeys.indexHmacKey, syncActionData.index);
|
|
107
|
+
if (!(0, bytes_1.uint8TimingSafeEqual)(generatedIndexMac, args.indexMac)) {
|
|
108
|
+
throw new Error('mutation index MAC mismatch');
|
|
109
|
+
}
|
|
99
110
|
}
|
|
100
111
|
return {
|
|
101
|
-
index:
|
|
112
|
+
index: bytes_1.TEXT_DECODER.decode(syncActionData.index),
|
|
102
113
|
value: syncActionData.value ?? null,
|
|
103
114
|
version: syncActionData.version,
|
|
104
115
|
indexMac: args.indexMac,
|
|
@@ -107,24 +118,22 @@ class WaAppStateCrypto {
|
|
|
107
118
|
}
|
|
108
119
|
async generateSnapshotMac(keyData, ltHash, version, collectionName) {
|
|
109
120
|
const derivedKeys = await this.deriveKeys(keyData);
|
|
110
|
-
const payload = (0,
|
|
121
|
+
const payload = (0, bytes_1.concatBytes)([
|
|
111
122
|
ltHash,
|
|
112
|
-
(0,
|
|
113
|
-
|
|
123
|
+
(0, bytes_1.intToBytes)(8, version),
|
|
124
|
+
bytes_1.TEXT_ENCODER.encode(collectionName)
|
|
114
125
|
]);
|
|
115
|
-
|
|
116
|
-
return (0, primitives_1.hmacSign)(key, payload);
|
|
126
|
+
return (0, primitives_1.hmacSign)(derivedKeys.snapshotMacHmacKey, payload);
|
|
117
127
|
}
|
|
118
128
|
async generatePatchMac(keyData, snapshotMac, valueMacs, version, collectionName) {
|
|
119
129
|
const derivedKeys = await this.deriveKeys(keyData);
|
|
120
|
-
const payload = (0,
|
|
130
|
+
const payload = (0, bytes_1.concatBytes)([
|
|
121
131
|
snapshotMac,
|
|
122
132
|
...valueMacs,
|
|
123
|
-
(0,
|
|
124
|
-
|
|
133
|
+
(0, bytes_1.intToBytes)(8, version),
|
|
134
|
+
bytes_1.TEXT_ENCODER.encode(collectionName)
|
|
125
135
|
]);
|
|
126
|
-
|
|
127
|
-
return (0, primitives_1.hmacSign)(key, payload);
|
|
136
|
+
return (0, primitives_1.hmacSign)(derivedKeys.patchMacHmacKey, payload);
|
|
128
137
|
}
|
|
129
138
|
async ltHashAdd(base, addValues) {
|
|
130
139
|
return this.ltHashApply(base, addValues, (left, right) => left + right);
|
|
@@ -178,11 +187,10 @@ class WaAppStateCrypto {
|
|
|
178
187
|
out.set(keyId, 1);
|
|
179
188
|
return out;
|
|
180
189
|
}
|
|
181
|
-
async generateValueMac(
|
|
190
|
+
async generateValueMac(valueMacHmacKey, associatedData, cipherWithIv) {
|
|
182
191
|
const octetLength = new Uint8Array(constants_1.APP_STATE_MAC_OCTET_LENGTH);
|
|
183
192
|
octetLength[octetLength.length - 1] = associatedData.byteLength & 0xff;
|
|
184
|
-
const
|
|
185
|
-
const full = await (0, primitives_1.hmacSign)(key, (0, bytes_2.concatBytes)([associatedData, cipherWithIv, octetLength]));
|
|
193
|
+
const full = await (0, primitives_1.hmacSign)(valueMacHmacKey, (0, bytes_1.concatBytes)([associatedData, cipherWithIv, octetLength]));
|
|
186
194
|
return full.subarray(0, constants_1.APP_STATE_VALUE_MAC_LENGTH);
|
|
187
195
|
}
|
|
188
196
|
touchDerivedKeysCacheEntry(cacheKey, keys) {
|
|
@@ -2,14 +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 response_parser_1 = require("./response-parser");
|
|
5
6
|
const WaAppStateCrypto_1 = require("./WaAppStateCrypto");
|
|
6
|
-
const
|
|
7
|
+
const _crypto_1 = require("../crypto/index.js");
|
|
7
8
|
const _proto_1 = require("../proto.js");
|
|
8
9
|
const constants_2 = require("../protocol/constants");
|
|
9
10
|
const jid_1 = require("../protocol/jid");
|
|
10
11
|
const query_1 = require("../transport/node/query");
|
|
11
12
|
const bytes_1 = require("../util/bytes");
|
|
12
|
-
const bytes_2 = require("../util/bytes");
|
|
13
13
|
const primitives_1 = require("../util/primitives");
|
|
14
14
|
class WaAppStateMissingKeyError extends Error {
|
|
15
15
|
constructor(message, keyId, collection) {
|
|
@@ -29,7 +29,8 @@ class WaAppStateSyncClient {
|
|
|
29
29
|
this.hostDomain = options.hostDomain ?? constants_2.WA_DEFAULTS.HOST_DOMAIN;
|
|
30
30
|
this.defaultTimeoutMs = options.defaultTimeoutMs ?? constants_2.WA_DEFAULTS.APP_STATE_SYNC_TIMEOUT_MS;
|
|
31
31
|
this.onMissingKeys = options.onMissingKeys;
|
|
32
|
-
this.crypto = new WaAppStateCrypto_1.WaAppStateCrypto();
|
|
32
|
+
this.crypto = new WaAppStateCrypto_1.WaAppStateCrypto(undefined, options.skipMacVerification === true);
|
|
33
|
+
this.mobilePrimary = options.mobilePrimary ?? false;
|
|
33
34
|
this.syncContext = null;
|
|
34
35
|
this.syncPromise = null;
|
|
35
36
|
}
|
|
@@ -37,6 +38,28 @@ class WaAppStateSyncClient {
|
|
|
37
38
|
this.logger.trace('app-state export requested');
|
|
38
39
|
return this.store.exportData();
|
|
39
40
|
}
|
|
41
|
+
async ensureInitialSyncKey() {
|
|
42
|
+
const existing = await this.store.getActiveSyncKey();
|
|
43
|
+
if (existing) {
|
|
44
|
+
return existing;
|
|
45
|
+
}
|
|
46
|
+
const keyIdBytes = await (0, _crypto_1.randomBytesAsync)(2);
|
|
47
|
+
const keyData = await (0, _crypto_1.randomBytesAsync)(32);
|
|
48
|
+
const rawId = await (0, _crypto_1.randomIntAsync)(0, 4294967295);
|
|
49
|
+
const key = {
|
|
50
|
+
keyId: keyIdBytes,
|
|
51
|
+
keyData,
|
|
52
|
+
timestamp: Date.now(),
|
|
53
|
+
fingerprint: { rawId, currentIndex: 0, deviceIndexes: [0] }
|
|
54
|
+
};
|
|
55
|
+
await this.store.upsertSyncKeys([key]);
|
|
56
|
+
this.crypto.clearCache();
|
|
57
|
+
this.logger.info('app-state initial sync key generated (mobile primary)', {
|
|
58
|
+
keyId: (0, bytes_1.bytesToHex)(keyIdBytes),
|
|
59
|
+
rawId
|
|
60
|
+
});
|
|
61
|
+
return key;
|
|
62
|
+
}
|
|
40
63
|
async importSyncKeys(keys) {
|
|
41
64
|
this.logger.debug('app-state importing sync keys', { count: keys.length });
|
|
42
65
|
const inserted = await this.store.upsertSyncKeys(keys);
|
|
@@ -52,7 +75,7 @@ class WaAppStateSyncClient {
|
|
|
52
75
|
const keyId = (0, bytes_1.decodeProtoBytes)(item.keyId?.keyId, 'appStateSyncKeyShare.keys[].keyId.keyId');
|
|
53
76
|
if (!item.keyData?.keyData) {
|
|
54
77
|
this.logger.debug('app-state sync key share entry missing key data', {
|
|
55
|
-
keyId: (0,
|
|
78
|
+
keyId: (0, bytes_1.bytesToHex)(keyId)
|
|
56
79
|
});
|
|
57
80
|
continue;
|
|
58
81
|
}
|
|
@@ -220,7 +243,7 @@ class WaAppStateSyncClient {
|
|
|
220
243
|
blockedCollections.push(entry.collection);
|
|
221
244
|
}
|
|
222
245
|
if (entry.missingKeyId) {
|
|
223
|
-
const keyHex = (0,
|
|
246
|
+
const keyHex = (0, bytes_1.bytesToHex)(entry.missingKeyId);
|
|
224
247
|
if (!missingKeyIdHexes.has(keyHex)) {
|
|
225
248
|
missingKeyIdHexes.add(keyHex);
|
|
226
249
|
missingKeyIds.push(entry.missingKeyId);
|
|
@@ -287,7 +310,7 @@ class WaAppStateSyncClient {
|
|
|
287
310
|
content: [
|
|
288
311
|
{
|
|
289
312
|
tag: constants_2.WA_NODE_TAGS.SYNC,
|
|
290
|
-
attrs: {},
|
|
313
|
+
attrs: this.mobilePrimary ? { data_namespace: '3' } : {},
|
|
291
314
|
content: collectionNodes
|
|
292
315
|
}
|
|
293
316
|
]
|
|
@@ -300,7 +323,7 @@ class WaAppStateSyncClient {
|
|
|
300
323
|
type: responseNode.attrs.type
|
|
301
324
|
});
|
|
302
325
|
(0, query_1.assertIqResult)(responseNode, 'app-state sync');
|
|
303
|
-
const payloads = (0,
|
|
326
|
+
const payloads = (0, response_parser_1.parseSyncResponse)(responseNode);
|
|
304
327
|
this.logger.debug('app-state sync payloads parsed', { count: payloads.length });
|
|
305
328
|
const payloadByCollection = new Map();
|
|
306
329
|
for (const payload of payloads) {
|
|
@@ -417,7 +440,7 @@ class WaAppStateSyncClient {
|
|
|
417
440
|
if (keyIds.length === 0 || collections.length === 0) {
|
|
418
441
|
return;
|
|
419
442
|
}
|
|
420
|
-
const keyIdsHex = keyIds.map((keyId) => (0,
|
|
443
|
+
const keyIdsHex = keyIds.map((keyId) => (0, bytes_1.bytesToHex)(keyId));
|
|
421
444
|
this.logger.info('app-state requesting missing sync keys', {
|
|
422
445
|
keys: keyIdsHex.length,
|
|
423
446
|
keyIds: keyIdsHex.join(','),
|
|
@@ -466,11 +489,13 @@ class WaAppStateSyncClient {
|
|
|
466
489
|
if (!snapshot.version?.version) {
|
|
467
490
|
throw new Error(`snapshot for ${collection} is missing version`);
|
|
468
491
|
}
|
|
469
|
-
if (!
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
492
|
+
if (!this.crypto.isMacVerificationSkipped) {
|
|
493
|
+
if (!snapshot.mac) {
|
|
494
|
+
throw new Error(`snapshot for ${collection} is missing mac`);
|
|
495
|
+
}
|
|
496
|
+
if (!snapshot.keyId?.id) {
|
|
497
|
+
throw new Error(`snapshot for ${collection} is missing keyId`);
|
|
498
|
+
}
|
|
474
499
|
}
|
|
475
500
|
return snapshot;
|
|
476
501
|
}
|
|
@@ -485,14 +510,16 @@ class WaAppStateSyncClient {
|
|
|
485
510
|
if (!patch.version?.version) {
|
|
486
511
|
throw new Error(`patch for ${collection} is missing version`);
|
|
487
512
|
}
|
|
488
|
-
if (!
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
513
|
+
if (!this.crypto.isMacVerificationSkipped) {
|
|
514
|
+
if (!patch.snapshotMac) {
|
|
515
|
+
throw new Error(`patch for ${collection} is missing snapshotMac`);
|
|
516
|
+
}
|
|
517
|
+
if (!patch.patchMac) {
|
|
518
|
+
throw new Error(`patch for ${collection} is missing patchMac`);
|
|
519
|
+
}
|
|
520
|
+
if (!patch.keyId?.id) {
|
|
521
|
+
throw new Error(`patch for ${collection} is missing keyId`);
|
|
522
|
+
}
|
|
496
523
|
}
|
|
497
524
|
if (patch.mutations && patch.mutations.length > 0 && patch.externalMutations) {
|
|
498
525
|
throw new Error(`patch for ${collection} has inline and external mutations together`);
|
|
@@ -506,16 +533,19 @@ class WaAppStateSyncClient {
|
|
|
506
533
|
}
|
|
507
534
|
async applySnapshot(collection, snapshot) {
|
|
508
535
|
const version = this.normalizeProtoLong(snapshot.version?.version, `snapshot.version.version (${collection})`);
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
536
|
+
let keyData = null;
|
|
537
|
+
if (!this.crypto.isMacVerificationSkipped) {
|
|
538
|
+
const keyId = (0, bytes_1.decodeProtoBytes)(snapshot.keyId?.id, `snapshot.keyId.id (${collection})`);
|
|
539
|
+
keyData = await this.getKeyData(keyId);
|
|
540
|
+
if (!keyData) {
|
|
541
|
+
throw new WaAppStateMissingKeyError(`missing snapshot key ${(0, bytes_1.bytesToHex)(keyId)} for ${collection}`, keyId, collection);
|
|
542
|
+
}
|
|
513
543
|
}
|
|
514
544
|
const indexValueMap = new Map();
|
|
515
545
|
const mutations = [];
|
|
516
546
|
const decryptedRecords = await this.decryptSnapshotRecords(collection, snapshot);
|
|
517
547
|
for (const { decrypted, recordKeyId } of decryptedRecords) {
|
|
518
|
-
const indexMacHex = (0,
|
|
548
|
+
const indexMacHex = (0, bytes_1.bytesToHex)(decrypted.indexMac);
|
|
519
549
|
indexValueMap.set(indexMacHex, decrypted.valueMac);
|
|
520
550
|
mutations.push({
|
|
521
551
|
collection,
|
|
@@ -537,9 +567,11 @@ class WaAppStateSyncClient {
|
|
|
537
567
|
ltHashInputIndex += 1;
|
|
538
568
|
}
|
|
539
569
|
const ltHash = await this.crypto.ltHashAdd(constants_1.APP_STATE_EMPTY_LT_HASH, ltHashInput);
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
570
|
+
if (keyData !== null) {
|
|
571
|
+
const expectedSnapshotMac = await this.crypto.generateSnapshotMac(keyData, ltHash, version, collection);
|
|
572
|
+
if (!(0, bytes_1.uint8Equal)(expectedSnapshotMac, snapshot.mac)) {
|
|
573
|
+
throw new Error(`snapshot MAC mismatch for ${collection}`);
|
|
574
|
+
}
|
|
543
575
|
}
|
|
544
576
|
this.setCollectionState(collection, version, ltHash, indexValueMap);
|
|
545
577
|
return mutations;
|
|
@@ -550,10 +582,13 @@ class WaAppStateSyncClient {
|
|
|
550
582
|
if (current.version !== patchVersion - 1) {
|
|
551
583
|
throw new Error(`patch version mismatch for ${collection}: local=${current.version}, incoming=${patchVersion}`);
|
|
552
584
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
585
|
+
let patchKeyData = null;
|
|
586
|
+
if (!this.crypto.isMacVerificationSkipped) {
|
|
587
|
+
const patchKeyId = (0, bytes_1.decodeProtoBytes)(patch.keyId?.id, `patch.keyId.id (${collection})`);
|
|
588
|
+
patchKeyData = await this.getKeyData(patchKeyId);
|
|
589
|
+
if (!patchKeyData) {
|
|
590
|
+
throw new WaAppStateMissingKeyError(`missing patch key ${(0, bytes_1.bytesToHex)(patchKeyId)} for ${collection}`, patchKeyId, collection);
|
|
591
|
+
}
|
|
557
592
|
}
|
|
558
593
|
const decryptedMutations = await this.decryptPatchMutations(collection, patch);
|
|
559
594
|
const macMutations = new Array(decryptedMutations.length);
|
|
@@ -568,7 +603,9 @@ class WaAppStateSyncClient {
|
|
|
568
603
|
};
|
|
569
604
|
}
|
|
570
605
|
const nextState = await this.computeNextCollectionState(current.hash, current.indexValueMap, macMutations, collection);
|
|
571
|
-
|
|
606
|
+
if (patchKeyData !== null) {
|
|
607
|
+
await this.assertPatchMacsMatch(patch, collection, patchKeyData, patchVersion, nextState.hash, valueMacs);
|
|
608
|
+
}
|
|
572
609
|
this.setCollectionState(collection, patchVersion, nextState.hash, nextState.indexValueMap);
|
|
573
610
|
return decryptedMutations;
|
|
574
611
|
}
|
|
@@ -593,7 +630,7 @@ class WaAppStateSyncClient {
|
|
|
593
630
|
decryptTasks[i] = (async () => {
|
|
594
631
|
const recordKeyData = await this.getKeyData(recordKeyId);
|
|
595
632
|
if (!recordKeyData) {
|
|
596
|
-
throw new WaAppStateMissingKeyError(`missing snapshot mutation key ${(0,
|
|
633
|
+
throw new WaAppStateMissingKeyError(`missing snapshot mutation key ${(0, bytes_1.bytesToHex)(recordKeyId)} for ${collection}`, recordKeyId, collection);
|
|
597
634
|
}
|
|
598
635
|
const decrypted = await this.crypto.decryptMutation({
|
|
599
636
|
operation: _proto_1.proto.SyncdMutation.SyncdOperation.SET,
|
|
@@ -640,7 +677,7 @@ class WaAppStateSyncClient {
|
|
|
640
677
|
decryptTasks[i] = (async () => {
|
|
641
678
|
const recordKeyData = await this.getKeyData(recordKeyId);
|
|
642
679
|
if (!recordKeyData) {
|
|
643
|
-
throw new WaAppStateMissingKeyError(`missing mutation key ${(0,
|
|
680
|
+
throw new WaAppStateMissingKeyError(`missing mutation key ${(0, bytes_1.bytesToHex)(recordKeyId)} for ${collection}`, recordKeyId, collection);
|
|
644
681
|
}
|
|
645
682
|
const decrypted = await this.crypto.decryptMutation({
|
|
646
683
|
operation: operationCode,
|
|
@@ -671,12 +708,12 @@ class WaAppStateSyncClient {
|
|
|
671
708
|
async assertPatchMacsMatch(patch, collection, patchKeyData, patchVersion, nextHash, valueMacs) {
|
|
672
709
|
const snapshotMac = (0, bytes_1.decodeProtoBytes)(patch.snapshotMac, `patch.snapshotMac (${collection})`);
|
|
673
710
|
const expectedSnapshotMac = await this.crypto.generateSnapshotMac(patchKeyData, nextHash, patchVersion, collection);
|
|
674
|
-
if (!(0,
|
|
711
|
+
if (!(0, bytes_1.uint8Equal)(expectedSnapshotMac, snapshotMac)) {
|
|
675
712
|
throw new Error(`patch snapshot MAC mismatch for ${collection}`);
|
|
676
713
|
}
|
|
677
714
|
const patchMac = (0, bytes_1.decodeProtoBytes)(patch.patchMac, `patch.patchMac (${collection})`);
|
|
678
715
|
const expectedPatchMac = await this.crypto.generatePatchMac(patchKeyData, snapshotMac, valueMacs, patchVersion, collection);
|
|
679
|
-
if (!(0,
|
|
716
|
+
if (!(0, bytes_1.uint8Equal)(expectedPatchMac, patchMac)) {
|
|
680
717
|
throw new Error(`patch MAC mismatch for ${collection}`);
|
|
681
718
|
}
|
|
682
719
|
}
|
|
@@ -771,7 +808,7 @@ class WaAppStateSyncClient {
|
|
|
771
808
|
const removeValues = [];
|
|
772
809
|
let missingRemoveCount = 0;
|
|
773
810
|
for (const mutation of mutations) {
|
|
774
|
-
const indexMacHex = (0,
|
|
811
|
+
const indexMacHex = (0, bytes_1.bytesToHex)(mutation.indexMac);
|
|
775
812
|
const existing = indexValueMap.get(indexMacHex);
|
|
776
813
|
if (mutation.operation === _proto_1.proto.SyncdMutation.SyncdOperation.REMOVE) {
|
|
777
814
|
if (!existing) {
|
|
@@ -845,7 +882,7 @@ class WaAppStateSyncClient {
|
|
|
845
882
|
const missingKeyHexes = new Set();
|
|
846
883
|
for (let index = 0; index < keyIds.length; index += 1) {
|
|
847
884
|
const keyId = keyIds[index];
|
|
848
|
-
const keyHex = (0,
|
|
885
|
+
const keyHex = (0, bytes_1.bytesToHex)(keyId);
|
|
849
886
|
if (context.keys.has(keyHex) || missingKeyHexes.has(keyHex)) {
|
|
850
887
|
continue;
|
|
851
888
|
}
|
|
@@ -857,12 +894,12 @@ class WaAppStateSyncClient {
|
|
|
857
894
|
}
|
|
858
895
|
const loadedKeyData = await this.store.getSyncKeyDataBatch(missingKeyIds);
|
|
859
896
|
for (let index = 0; index < missingKeyIds.length; index += 1) {
|
|
860
|
-
context.keys.set((0,
|
|
897
|
+
context.keys.set((0, bytes_1.bytesToHex)(missingKeyIds[index]), loadedKeyData[index] ?? null);
|
|
861
898
|
}
|
|
862
899
|
}
|
|
863
900
|
async getKeyData(keyId) {
|
|
864
901
|
const context = this.requireSyncContext();
|
|
865
|
-
const keyHex = (0,
|
|
902
|
+
const keyHex = (0, bytes_1.bytesToHex)(keyId);
|
|
866
903
|
if (context.keys.has(keyHex)) {
|
|
867
904
|
return context.keys.get(keyHex) ?? null;
|
|
868
905
|
}
|
package/dist/appstate/index.js
CHANGED
|
@@ -24,7 +24,7 @@ Object.defineProperty(exports, "decodeAppStateSyncKeys", { enumerable: true, get
|
|
|
24
24
|
__exportStar(require("./utils"), exports);
|
|
25
25
|
var WaAppStateCrypto_1 = require("./WaAppStateCrypto");
|
|
26
26
|
Object.defineProperty(exports, "WaAppStateCrypto", { enumerable: true, get: function () { return WaAppStateCrypto_1.WaAppStateCrypto; } });
|
|
27
|
-
var
|
|
28
|
-
Object.defineProperty(exports, "parseSyncResponse", { enumerable: true, get: function () { return
|
|
27
|
+
var response_parser_1 = require("./response-parser");
|
|
28
|
+
Object.defineProperty(exports, "parseSyncResponse", { enumerable: true, get: function () { return response_parser_1.parseSyncResponse; } });
|
|
29
29
|
var WaAppStateSyncClient_1 = require("./WaAppStateSyncClient");
|
|
30
30
|
Object.defineProperty(exports, "WaAppStateSyncClient", { enumerable: true, get: function () { return WaAppStateSyncClient_1.WaAppStateSyncClient; } });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WaAuthClient = void 0;
|
|
4
|
-
const
|
|
4
|
+
const credentials_flow_1 = require("./credentials-flow");
|
|
5
5
|
const WaPairingFlow_1 = require("./pairing/WaPairingFlow");
|
|
6
6
|
const WaQrFlow_1 = require("./pairing/WaQrFlow");
|
|
7
7
|
const constants_1 = require("../protocol/constants");
|
|
@@ -27,6 +27,7 @@ class WaAuthClient {
|
|
|
27
27
|
this.callbacks = deps.callbacks ?? {};
|
|
28
28
|
this.authStore = deps.authStore;
|
|
29
29
|
this.signalStore = deps.signalStore;
|
|
30
|
+
this.preKeyStore = deps.preKeyStore;
|
|
30
31
|
this.credentials = null;
|
|
31
32
|
this.qrFlow = new WaQrFlow_1.WaQrFlow({
|
|
32
33
|
logger: this.logger,
|
|
@@ -47,7 +48,8 @@ class WaAuthClient {
|
|
|
47
48
|
emitPairingCode: (code) => this.callbacks.onPairingCode?.(code),
|
|
48
49
|
emitPairingRefresh: (forceManual) => this.callbacks.onPairingRefresh?.(forceManual),
|
|
49
50
|
emitPaired: (credentials) => this.callbacks.onPaired?.(credentials)
|
|
50
|
-
}
|
|
51
|
+
},
|
|
52
|
+
dangerous: options.dangerous
|
|
51
53
|
});
|
|
52
54
|
}
|
|
53
55
|
getState(connected = false) {
|
|
@@ -64,10 +66,12 @@ class WaAuthClient {
|
|
|
64
66
|
async loadOrCreateCredentials() {
|
|
65
67
|
return this.runHandled(async () => {
|
|
66
68
|
this.logger.debug('auth client loadOrCreateCredentials start');
|
|
67
|
-
this.credentials = await (0,
|
|
69
|
+
this.credentials = await (0, credentials_flow_1.loadOrCreateCredentials)({
|
|
68
70
|
logger: this.logger,
|
|
69
71
|
authStore: this.authStore,
|
|
70
|
-
signalStore: this.signalStore
|
|
72
|
+
signalStore: this.signalStore,
|
|
73
|
+
preKeyStore: this.preKeyStore,
|
|
74
|
+
skipSignedPreKeySignatureVerification: this.options.dangerous?.disableSignedPreKeySignatureVerification
|
|
71
75
|
});
|
|
72
76
|
this.logger.info('auth client credentials ready', {
|
|
73
77
|
registered: this.credentials?.meJid !== null && this.credentials?.meJid !== undefined
|
|
@@ -75,13 +79,17 @@ class WaAuthClient {
|
|
|
75
79
|
return this.credentials;
|
|
76
80
|
});
|
|
77
81
|
}
|
|
78
|
-
buildCommsConfig(socketOptions) {
|
|
82
|
+
buildCommsConfig(socketOptions, overrides = {}) {
|
|
79
83
|
this.logger.trace('auth client building comms config');
|
|
80
|
-
return (0,
|
|
84
|
+
return (0, credentials_flow_1.buildCommsConfig)(this.logger, this.requireCredentials(), socketOptions, {
|
|
81
85
|
deviceBrowser: this.options.deviceBrowser,
|
|
82
86
|
deviceOsDisplayName: this.options.deviceOsDisplayName,
|
|
83
87
|
requireFullSync: this.options.requireFullSync,
|
|
84
|
-
version: this.options.version
|
|
88
|
+
version: this.options.version,
|
|
89
|
+
mobileTransport: this.options.mobileTransport,
|
|
90
|
+
noiseTrustedRootCa: overrides.noiseTrustedRootCa,
|
|
91
|
+
disableNoiseCertificateChainVerification: overrides.disableNoiseCertificateChainVerification ??
|
|
92
|
+
this.options.dangerous?.disableNoiseCertificateChainVerification
|
|
85
93
|
});
|
|
86
94
|
}
|
|
87
95
|
async clearTransientState() {
|
|
@@ -180,10 +188,10 @@ class WaAuthClient {
|
|
|
180
188
|
}
|
|
181
189
|
});
|
|
182
190
|
}
|
|
183
|
-
async requestPairingCode(phoneNumber, shouldShowPushNotification = false) {
|
|
191
|
+
async requestPairingCode(phoneNumber, shouldShowPushNotification = false, customCode) {
|
|
184
192
|
this.requireCredentials();
|
|
185
193
|
this.logger.info('auth client requesting pairing code');
|
|
186
|
-
return this.runHandled(() => this.pairingFlow.requestPairingCode(phoneNumber, shouldShowPushNotification));
|
|
194
|
+
return this.runHandled(() => this.pairingFlow.requestPairingCode(phoneNumber, shouldShowPushNotification, customCode));
|
|
187
195
|
}
|
|
188
196
|
async fetchPairingCountryCodeIso() {
|
|
189
197
|
this.requireCredentials();
|
|
@@ -228,10 +236,11 @@ class WaAuthClient {
|
|
|
228
236
|
registered: credentials?.meJid !== null && credentials?.meJid !== undefined
|
|
229
237
|
});
|
|
230
238
|
this.credentials = credentials;
|
|
231
|
-
await (0,
|
|
239
|
+
await (0, credentials_flow_1.persistCredentials)({
|
|
232
240
|
logger: this.logger,
|
|
233
241
|
authStore: this.authStore,
|
|
234
|
-
signalStore: this.signalStore
|
|
242
|
+
signalStore: this.signalStore,
|
|
243
|
+
preKeyStore: this.preKeyStore
|
|
235
244
|
}, credentials);
|
|
236
245
|
}
|
|
237
246
|
requireCredentials() {
|