zapo-js 0.1.1 → 0.1.2
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 +8 -0
- package/dist/appstate/WaAppStateCrypto.js +18 -25
- package/dist/appstate/WaAppStateSyncClient.js +181 -114
- package/dist/appstate/WaAppStateSyncResponseParser.js +16 -5
- package/dist/appstate/constants.js +4 -3
- package/dist/appstate/utils.js +10 -30
- package/dist/auth/WaAuthClient.js +48 -55
- package/dist/auth/flow/WaAuthCredentialsFlow.js +21 -14
- package/dist/auth/index.js +1 -3
- package/dist/auth/pairing/WaPairingFlow.js +21 -23
- package/dist/auth/pairing/WaQrFlow.js +37 -24
- package/dist/client/WaClient.js +103 -276
- package/dist/client/WaClientFactory.js +227 -110
- package/dist/client/connection/WaConnectionManager.js +292 -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/WaGroupCoordinator.js +27 -17
- package/dist/client/coordinators/WaIncomingNodeCoordinator.js +20 -27
- package/dist/client/coordinators/WaMessageDispatchCoordinator.js +231 -686
- package/dist/client/coordinators/WaRetryCoordinator.js +70 -37
- package/dist/client/dirty.js +35 -29
- package/dist/client/events/chat.js +4 -3
- package/dist/client/events/group.js +59 -36
- package/dist/client/history-sync.js +53 -63
- package/dist/client/incoming.js +23 -20
- package/dist/client/mailbox.js +8 -8
- package/dist/client/messages.js +4 -4
- package/dist/client/messaging/fanout.js +189 -0
- package/dist/client/messaging/key-protocol.js +130 -0
- package/dist/client/messaging/participants.js +191 -0
- package/dist/crypto/core/hkdf.js +3 -8
- package/dist/crypto/core/index.js +1 -4
- package/dist/crypto/core/keys.js +2 -3
- package/dist/crypto/core/primitives.js +12 -15
- package/dist/crypto/core/random.js +7 -26
- package/dist/crypto/curves/Ed25519.js +7 -8
- package/dist/crypto/curves/X25519.js +13 -16
- package/dist/crypto/index.js +0 -5
- package/dist/esm/appstate/WaAppStateCrypto.js +6 -13
- package/dist/esm/appstate/WaAppStateSyncClient.js +174 -107
- package/dist/esm/appstate/WaAppStateSyncResponseParser.js +17 -6
- package/dist/esm/appstate/constants.js +3 -2
- package/dist/esm/appstate/utils.js +8 -27
- package/dist/esm/auth/WaAuthClient.js +48 -55
- package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +21 -14
- package/dist/esm/auth/index.js +0 -1
- package/dist/esm/auth/pairing/WaPairingFlow.js +14 -16
- package/dist/esm/auth/pairing/WaQrFlow.js +37 -24
- package/dist/esm/client/WaClient.js +103 -276
- package/dist/esm/client/WaClientFactory.js +227 -110
- package/dist/esm/client/connection/WaConnectionManager.js +288 -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/WaGroupCoordinator.js +20 -10
- package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +20 -27
- package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +232 -687
- package/dist/esm/client/coordinators/WaRetryCoordinator.js +71 -38
- package/dist/esm/client/dirty.js +30 -24
- package/dist/esm/client/events/chat.js +4 -3
- package/dist/esm/client/events/group.js +50 -28
- package/dist/esm/client/history-sync.js +50 -60
- package/dist/esm/client/incoming.js +23 -20
- package/dist/esm/client/mailbox.js +8 -8
- package/dist/esm/client/messages.js +1 -1
- package/dist/esm/client/messaging/fanout.js +186 -0
- package/dist/esm/client/messaging/key-protocol.js +127 -0
- package/dist/esm/client/messaging/participants.js +188 -0
- package/dist/esm/crypto/core/hkdf.js +3 -8
- package/dist/esm/crypto/core/index.js +0 -1
- package/dist/esm/crypto/core/keys.js +2 -3
- package/dist/esm/crypto/core/primitives.js +12 -15
- package/dist/esm/crypto/core/random.js +6 -25
- package/dist/esm/crypto/curves/Ed25519.js +4 -5
- package/dist/esm/crypto/curves/X25519.js +10 -13
- package/dist/esm/crypto/index.js +0 -2
- 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/BoundedTaskQueue.js +13 -17
- package/dist/esm/media/WaMediaCrypto.js +2 -4
- package/dist/esm/media/WaMediaTransferClient.js +226 -58
- package/dist/esm/media/conn.js +10 -6
- package/dist/esm/media/constants.js +4 -1
- package/dist/esm/message/WaMessageClient.js +4 -13
- package/dist/esm/message/ack.js +6 -6
- package/dist/esm/message/addon-crypto.js +59 -0
- package/dist/esm/message/incoming.js +106 -111
- package/dist/esm/message/index.js +2 -0
- package/dist/esm/message/reporting-token.js +438 -0
- package/dist/esm/message/use-case-secret.js +49 -0
- package/dist/esm/protocol/appstate.js +58 -0
- package/dist/esm/protocol/constants.js +2 -1
- package/dist/esm/protocol/index.js +2 -10
- package/dist/esm/protocol/jid.js +63 -51
- package/dist/esm/protocol/media.js +3 -3
- package/dist/esm/protocol/nodes.js +2 -0
- package/dist/esm/protocol/usync.js +11 -0
- package/dist/esm/retry/index.js +1 -0
- package/dist/esm/retry/outbound.js +4 -5
- package/dist/esm/retry/parse.js +58 -76
- package/dist/esm/retry/replay.js +48 -49
- package/dist/esm/retry/tracker.js +56 -0
- package/dist/esm/signal/api/SignalDeviceSyncApi.js +249 -82
- package/dist/esm/signal/api/SignalDigestSyncApi.js +6 -1
- package/dist/esm/signal/api/SignalIdentitySyncApi.js +49 -34
- package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +70 -62
- package/dist/esm/signal/api/SignalSessionSyncApi.js +23 -30
- package/dist/esm/signal/crypto/WaAdvSignature.js +3 -5
- package/dist/esm/signal/group/SenderKeyChain.js +28 -23
- package/dist/esm/signal/group/SenderKeyCodec.js +2 -4
- package/dist/esm/signal/group/SenderKeyManager.js +26 -16
- package/dist/esm/signal/index.js +1 -0
- package/dist/esm/signal/session/SignalProtocol.js +49 -14
- 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 +186 -0
- package/dist/esm/signal/store/sqlite.js +16 -37
- package/dist/esm/store/createStore.js +16 -18
- package/dist/esm/store/noop.store.js +3 -6
- package/dist/esm/store/providers/memory/appstate.store.js +30 -6
- package/dist/esm/store/providers/memory/contact.store.js +5 -0
- package/dist/esm/store/providers/memory/device-list.store.js +3 -30
- 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/sender-key.store.js +5 -7
- package/dist/esm/store/providers/memory/signal.store.js +13 -1
- package/dist/esm/store/providers/memory/thread.store.js +5 -0
- package/dist/esm/store/providers/sqlite/appstate.store.js +82 -1
- package/dist/esm/store/providers/sqlite/connection.js +18 -13
- package/dist/esm/store/providers/sqlite/contact.store.js +31 -18
- package/dist/esm/store/providers/sqlite/device-list.store.js +7 -35
- package/dist/esm/store/providers/sqlite/message.store.js +45 -32
- package/dist/esm/store/providers/sqlite/migrations.js +1 -1
- package/dist/esm/store/providers/sqlite/participants.store.js +1 -9
- package/dist/esm/store/providers/sqlite/retry.store.js +8 -11
- package/dist/esm/store/providers/sqlite/sender-key.store.js +25 -30
- package/dist/esm/store/providers/sqlite/signal.store.js +104 -22
- package/dist/esm/store/providers/sqlite/table-names.js +107 -0
- package/dist/esm/store/providers/sqlite/thread.store.js +35 -22
- package/dist/esm/transport/WaComms.js +25 -23
- package/dist/esm/transport/WaWebSocket.js +115 -12
- package/dist/esm/transport/binary/decoder.js +4 -4
- package/dist/esm/transport/binary/encoder.js +12 -4
- package/dist/esm/transport/index.js +1 -0
- package/dist/esm/transport/keepalive/WaKeepAlive.js +2 -8
- package/dist/esm/transport/node/WaNodeOrchestrator.js +2 -4
- 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/index.js +2 -1
- package/dist/esm/transport/node/builders/message.js +9 -0
- package/dist/esm/transport/node/builders/pairing.js +4 -5
- package/dist/esm/transport/node/builders/usync.js +41 -0
- package/dist/esm/transport/node/helpers.js +107 -5
- package/dist/esm/transport/node/usync.js +35 -0
- package/dist/esm/transport/noise/WaFrameCodec.js +48 -33
- package/dist/esm/transport/noise/WaNoiseCert.js +3 -6
- package/dist/esm/transport/noise/WaNoiseSession.js +17 -10
- package/dist/esm/transport/proxy.js +27 -0
- package/dist/esm/transport/stream/parse.js +13 -48
- package/dist/esm/util/bytes.js +50 -32
- package/dist/esm/util/coercion.js +6 -14
- package/dist/esm/util/primitives.js +39 -14
- 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/BoundedTaskQueue.js +13 -17
- package/dist/media/WaMediaCrypto.js +1 -3
- package/dist/media/WaMediaTransferClient.js +259 -58
- package/dist/media/conn.js +10 -6
- package/dist/media/constants.js +4 -1
- package/dist/message/WaMessageClient.js +5 -14
- package/dist/message/ack.js +6 -6
- package/dist/message/addon-crypto.js +65 -0
- package/dist/message/incoming.js +104 -109
- package/dist/message/index.js +2 -0
- package/dist/message/reporting-token.js +443 -0
- package/dist/message/use-case-secret.js +55 -0
- package/dist/protocol/appstate.js +59 -1
- package/dist/protocol/constants.js +7 -1
- package/dist/protocol/index.js +20 -42
- package/dist/protocol/jid.js +64 -51
- package/dist/protocol/media.js +3 -3
- package/dist/protocol/nodes.js +2 -0
- package/dist/protocol/usync.js +14 -0
- package/dist/retry/index.js +3 -1
- package/dist/retry/outbound.js +6 -7
- package/dist/retry/parse.js +57 -75
- package/dist/retry/replay.js +46 -47
- package/dist/retry/tracker.js +59 -0
- package/dist/signal/api/SignalDeviceSyncApi.js +247 -80
- package/dist/signal/api/SignalDigestSyncApi.js +6 -1
- package/dist/signal/api/SignalIdentitySyncApi.js +49 -34
- package/dist/signal/api/SignalMissingPreKeysSyncApi.js +67 -59
- package/dist/signal/api/SignalSessionSyncApi.js +23 -30
- package/dist/signal/crypto/WaAdvSignature.js +2 -4
- package/dist/signal/group/SenderKeyChain.js +27 -22
- package/dist/signal/group/SenderKeyCodec.js +1 -3
- package/dist/signal/group/SenderKeyManager.js +26 -16
- package/dist/signal/index.js +3 -1
- package/dist/signal/session/SignalProtocol.js +49 -14
- package/dist/signal/session/SignalRatchet.js +24 -15
- package/dist/signal/session/SignalSession.js +14 -9
- package/dist/signal/session/resolver.js +189 -0
- package/dist/signal/store/sqlite.js +16 -37
- package/dist/store/createStore.js +16 -18
- package/dist/store/noop.store.js +3 -6
- package/dist/store/providers/memory/appstate.store.js +28 -4
- package/dist/store/providers/memory/contact.store.js +5 -0
- package/dist/store/providers/memory/device-list.store.js +3 -30
- 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/sender-key.store.js +8 -10
- package/dist/store/providers/memory/signal.store.js +21 -9
- package/dist/store/providers/memory/thread.store.js +5 -0
- package/dist/store/providers/sqlite/appstate.store.js +81 -0
- package/dist/store/providers/sqlite/connection.js +18 -13
- package/dist/store/providers/sqlite/contact.store.js +31 -18
- package/dist/store/providers/sqlite/device-list.store.js +7 -35
- package/dist/store/providers/sqlite/message.store.js +45 -32
- package/dist/store/providers/sqlite/migrations.js +1 -1
- package/dist/store/providers/sqlite/participants.store.js +1 -9
- package/dist/store/providers/sqlite/retry.store.js +8 -11
- package/dist/store/providers/sqlite/sender-key.store.js +24 -29
- package/dist/store/providers/sqlite/signal.store.js +105 -23
- package/dist/store/providers/sqlite/table-names.js +113 -0
- package/dist/store/providers/sqlite/thread.store.js +35 -22
- package/dist/transport/WaComms.js +27 -25
- package/dist/transport/WaWebSocket.js +148 -12
- package/dist/transport/binary/decoder.js +4 -4
- package/dist/transport/binary/encoder.js +12 -4
- package/dist/transport/index.js +7 -1
- package/dist/transport/keepalive/WaKeepAlive.js +1 -7
- package/dist/transport/node/WaNodeOrchestrator.js +2 -4
- 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/index.js +12 -9
- package/dist/transport/node/builders/message.js +9 -0
- package/dist/transport/node/builders/pairing.js +4 -5
- package/dist/transport/node/builders/usync.js +45 -0
- package/dist/transport/node/helpers.js +112 -4
- package/dist/transport/node/usync.js +38 -0
- package/dist/transport/noise/WaFrameCodec.js +47 -32
- package/dist/transport/noise/WaNoiseCert.js +5 -8
- package/dist/transport/noise/WaNoiseSession.js +17 -10
- package/dist/transport/proxy.js +34 -0
- package/dist/transport/stream/parse.js +17 -53
- 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/store/sqlite.d.ts +4 -18
- package/dist/types/appstate/utils.d.ts +0 -1
- package/dist/types/auth/WaAuthClient.d.ts +10 -12
- package/dist/types/auth/index.d.ts +0 -2
- package/dist/types/auth/pairing/WaQrFlow.d.ts +1 -1
- package/dist/types/auth/types.d.ts +6 -9
- package/dist/types/client/WaClient.d.ts +27 -25
- package/dist/types/client/WaClientFactory.d.ts +22 -23
- package/dist/types/client/connection/WaConnectionManager.d.ts +64 -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/WaIncomingNodeCoordinator.d.ts +0 -1
- package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +18 -41
- package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +2 -0
- package/dist/types/client/dirty.d.ts +1 -0
- package/dist/types/client/events/group.d.ts +2 -1
- package/dist/types/client/index.d.ts +1 -1
- 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/types.d.ts +24 -1
- package/dist/types/crypto/core/hkdf.d.ts +0 -6
- package/dist/types/crypto/core/index.d.ts +0 -1
- package/dist/types/crypto/core/random.d.ts +1 -7
- package/dist/types/crypto/index.d.ts +0 -2
- package/dist/types/index.d.ts +1 -1
- 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/BoundedTaskQueue.d.ts +1 -1
- package/dist/types/media/WaMediaTransferClient.d.ts +13 -3
- package/dist/types/media/types.d.ts +5 -0
- package/dist/types/message/addon-crypto.d.ts +25 -0
- package/dist/types/message/index.d.ts +2 -0
- package/dist/types/message/reporting-token.d.ts +19 -0
- package/dist/types/message/use-case-secret.d.ts +20 -0
- package/dist/types/protocol/appstate.d.ts +58 -0
- package/dist/types/protocol/constants.d.ts +2 -1
- package/dist/types/protocol/index.d.ts +2 -10
- package/dist/types/protocol/jid.d.ts +3 -3
- package/dist/types/protocol/nodes.d.ts +2 -0
- package/dist/types/protocol/usync.d.ts +11 -0
- package/dist/types/retry/index.d.ts +1 -0
- package/dist/types/retry/replay.d.ts +0 -4
- package/dist/types/retry/tracker.d.ts +19 -0
- package/dist/types/retry/types.d.ts +4 -3
- package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +13 -1
- package/dist/types/signal/group/SenderKeyCodec.d.ts +4 -6
- package/dist/types/signal/index.d.ts +1 -0
- package/dist/types/signal/session/SignalProtocol.d.ts +9 -0
- package/dist/types/signal/session/resolver.d.ts +17 -0
- package/dist/types/store/contracts/appstate.store.d.ts +3 -0
- 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/sender-key.store.d.ts +0 -1
- package/dist/types/store/contracts/signal.store.d.ts +6 -0
- package/dist/types/store/contracts/thread.store.d.ts +1 -0
- package/dist/types/store/index.d.ts +1 -1
- package/dist/types/store/providers/memory/appstate.store.d.ts +2 -0
- 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/sender-key.store.d.ts +0 -1
- package/dist/types/store/providers/memory/signal.store.d.ts +6 -0
- package/dist/types/store/providers/memory/thread.store.d.ts +1 -0
- package/dist/types/store/providers/sqlite/appstate.store.d.ts +2 -0
- package/dist/types/store/providers/sqlite/contact.store.d.ts +2 -0
- package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -3
- package/dist/types/store/providers/sqlite/message.store.d.ts +2 -0
- package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -1
- package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -1
- package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -1
- package/dist/types/store/providers/sqlite/signal.store.d.ts +7 -0
- package/dist/types/store/providers/sqlite/table-names.d.ts +5 -0
- package/dist/types/store/providers/sqlite/thread.store.d.ts +2 -0
- package/dist/types/store/types.d.ts +3 -0
- package/dist/types/transport/WaWebSocket.d.ts +3 -0
- package/dist/types/transport/index.d.ts +2 -1
- package/dist/types/transport/keepalive/WaKeepAlive.d.ts +0 -1
- package/dist/types/transport/node/WaNodeTransport.d.ts +0 -9
- package/dist/types/transport/node/builders/group.d.ts +4 -6
- package/dist/types/transport/node/builders/index.d.ts +2 -1
- package/dist/types/transport/node/builders/message.d.ts +14 -25
- package/dist/types/transport/node/builders/retry.d.ts +2 -4
- package/dist/types/transport/node/builders/usync.d.ts +21 -0
- package/dist/types/transport/node/helpers.d.ts +8 -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 +1 -0
- 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/primitives.d.ts +3 -0
- package/dist/util/bytes.js +55 -33
- package/dist/util/coercion.js +6 -14
- package/dist/util/primitives.js +42 -14
- package/package.json +26 -5
- package/dist/crypto/core/encoding.js +0 -29
- package/dist/esm/crypto/core/encoding.js +0 -25
- package/dist/esm/util/base64.js +0 -18
- package/dist/esm/util/signal-address.js +0 -5
- package/dist/types/crypto/core/encoding.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
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createGroupParticipantsCache = createGroupParticipantsCache;
|
|
4
|
+
const jid_1 = require("../../protocol/jid");
|
|
5
|
+
const primitives_1 = require("../../util/primitives");
|
|
6
|
+
function createGroupParticipantsCache(options) {
|
|
7
|
+
const { participantsStore, queryGroupParticipantJids, logger } = options;
|
|
8
|
+
const sanitizeParticipantUsers = (participants) => {
|
|
9
|
+
const deduped = new Set();
|
|
10
|
+
for (const participant of participants) {
|
|
11
|
+
if (!participant || !participant.includes('@')) {
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
deduped.add((0, jid_1.toUserJid)(participant));
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
logger.trace('ignoring malformed participant jid', {
|
|
19
|
+
participant,
|
|
20
|
+
message: (0, primitives_1.toError)(error).message
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return [...deduped];
|
|
25
|
+
};
|
|
26
|
+
const areParticipantListsEqual = (left, right) => {
|
|
27
|
+
if (left.length !== right.length) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
for (let index = 0; index < left.length; index += 1) {
|
|
31
|
+
if (left[index] !== right[index]) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
36
|
+
};
|
|
37
|
+
const mergeParticipantUsersIntoCache = async (groupJid, cachedParticipants, participantsToAdd) => {
|
|
38
|
+
if (participantsToAdd.length === 0) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const nextParticipants = [...cachedParticipants];
|
|
42
|
+
const existing = new Set(cachedParticipants);
|
|
43
|
+
for (const participant of participantsToAdd) {
|
|
44
|
+
if (existing.has(participant)) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
existing.add(participant);
|
|
48
|
+
nextParticipants.push(participant);
|
|
49
|
+
}
|
|
50
|
+
if (nextParticipants.length === cachedParticipants.length) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
await participantsStore.upsertGroupParticipants({
|
|
54
|
+
groupJid,
|
|
55
|
+
participants: nextParticipants,
|
|
56
|
+
updatedAtMs: Date.now()
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
const removeParticipantUsersFromCache = async (groupJid, cachedParticipants, participantsToRemove) => {
|
|
60
|
+
if (participantsToRemove.length === 0) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const removed = new Set(participantsToRemove);
|
|
64
|
+
const nextParticipants = cachedParticipants.filter((participant) => !removed.has(participant));
|
|
65
|
+
if (nextParticipants.length === cachedParticipants.length) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (nextParticipants.length === 0) {
|
|
69
|
+
await participantsStore.deleteGroupParticipants(groupJid);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
await participantsStore.upsertGroupParticipants({
|
|
73
|
+
groupJid,
|
|
74
|
+
participants: nextParticipants,
|
|
75
|
+
updatedAtMs: Date.now()
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
const replaceParticipantUsersInCache = async (groupJid, cachedParticipants, participantsToReplace, replacementParticipants) => {
|
|
79
|
+
const toReplace = new Set(participantsToReplace);
|
|
80
|
+
const nextParticipants = cachedParticipants.filter((participant) => !toReplace.has(participant));
|
|
81
|
+
const existing = new Set(nextParticipants);
|
|
82
|
+
for (const participant of replacementParticipants) {
|
|
83
|
+
if (existing.has(participant)) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
existing.add(participant);
|
|
87
|
+
nextParticipants.push(participant);
|
|
88
|
+
}
|
|
89
|
+
if (areParticipantListsEqual(cachedParticipants, nextParticipants)) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (nextParticipants.length === 0) {
|
|
93
|
+
await participantsStore.deleteGroupParticipants(groupJid);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
await participantsStore.upsertGroupParticipants({
|
|
97
|
+
groupJid,
|
|
98
|
+
participants: nextParticipants,
|
|
99
|
+
updatedAtMs: Date.now()
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
const resolveGroupJidForParticipantCacheEvent = (event) => {
|
|
103
|
+
if (event.action === 'linked_group_promote' || event.action === 'linked_group_demote') {
|
|
104
|
+
return event.contextGroupJid ?? event.groupJid ?? null;
|
|
105
|
+
}
|
|
106
|
+
return event.groupJid ?? null;
|
|
107
|
+
};
|
|
108
|
+
const extractParticipantUsersFromGroupEvent = (event) => {
|
|
109
|
+
const candidates = [];
|
|
110
|
+
for (const participant of event.participants ?? []) {
|
|
111
|
+
if (participant.jid) {
|
|
112
|
+
candidates.push(participant.jid);
|
|
113
|
+
}
|
|
114
|
+
if (participant.lidJid) {
|
|
115
|
+
candidates.push(participant.lidJid);
|
|
116
|
+
}
|
|
117
|
+
if (participant.phoneJid) {
|
|
118
|
+
candidates.push(participant.phoneJid);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return sanitizeParticipantUsers(candidates);
|
|
122
|
+
};
|
|
123
|
+
const refreshParticipantUsers = async (groupJid) => {
|
|
124
|
+
const queried = await queryGroupParticipantJids(groupJid);
|
|
125
|
+
const participants = sanitizeParticipantUsers(queried);
|
|
126
|
+
await participantsStore.upsertGroupParticipants({
|
|
127
|
+
groupJid,
|
|
128
|
+
participants,
|
|
129
|
+
updatedAtMs: Date.now()
|
|
130
|
+
});
|
|
131
|
+
return participants;
|
|
132
|
+
};
|
|
133
|
+
const resolveParticipantUsers = async (groupJid) => {
|
|
134
|
+
const cached = await participantsStore.getGroupParticipants(groupJid);
|
|
135
|
+
if (cached && cached.participants.length > 0) {
|
|
136
|
+
return sanitizeParticipantUsers(cached.participants);
|
|
137
|
+
}
|
|
138
|
+
return refreshParticipantUsers(groupJid);
|
|
139
|
+
};
|
|
140
|
+
const mutateFromGroupEvent = async (event) => {
|
|
141
|
+
const groupJid = resolveGroupJidForParticipantCacheEvent(event);
|
|
142
|
+
if (!groupJid) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (event.action === 'delete') {
|
|
146
|
+
await participantsStore.deleteGroupParticipants(groupJid);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const participantUsers = extractParticipantUsersFromGroupEvent(event);
|
|
150
|
+
if (event.action === 'create') {
|
|
151
|
+
if (participantUsers.length === 0) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
await participantsStore.upsertGroupParticipants({
|
|
155
|
+
groupJid,
|
|
156
|
+
participants: participantUsers,
|
|
157
|
+
updatedAtMs: Date.now()
|
|
158
|
+
});
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const cached = await participantsStore.getGroupParticipants(groupJid);
|
|
162
|
+
if (!cached || cached.participants.length === 0) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const cachedParticipants = sanitizeParticipantUsers(cached.participants);
|
|
166
|
+
if (cachedParticipants.length === 0) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (event.action === 'add' ||
|
|
170
|
+
event.action === 'promote' ||
|
|
171
|
+
event.action === 'demote' ||
|
|
172
|
+
event.action === 'linked_group_promote' ||
|
|
173
|
+
event.action === 'linked_group_demote') {
|
|
174
|
+
await mergeParticipantUsersIntoCache(groupJid, cachedParticipants, participantUsers);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (event.action === 'remove') {
|
|
178
|
+
await removeParticipantUsersFromCache(groupJid, cachedParticipants, participantUsers);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (event.action === 'modify') {
|
|
182
|
+
const authorUsers = event.authorJid ? sanitizeParticipantUsers([event.authorJid]) : [];
|
|
183
|
+
await replaceParticipantUsersInCache(groupJid, cachedParticipants, authorUsers, participantUsers);
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
return {
|
|
187
|
+
resolveParticipantUsers,
|
|
188
|
+
refreshParticipantUsers,
|
|
189
|
+
mutateFromGroupEvent
|
|
190
|
+
};
|
|
191
|
+
}
|
package/dist/crypto/core/hkdf.js
CHANGED
|
@@ -4,23 +4,18 @@ exports.hkdf = hkdf;
|
|
|
4
4
|
exports.hkdfSplit = hkdfSplit;
|
|
5
5
|
const node_crypto_1 = require("node:crypto");
|
|
6
6
|
const bytes_1 = require("../../util/bytes");
|
|
7
|
-
/**
|
|
8
|
-
* HKDF key derivation using SHA-256
|
|
9
|
-
*/
|
|
10
7
|
async function hkdf(ikm, salt, info, outLength) {
|
|
11
8
|
const key = await node_crypto_1.webcrypto.subtle.importKey('raw', ikm, 'HKDF', false, ['deriveBits']);
|
|
9
|
+
const infoBytes = typeof info === 'string' ? (info === '' ? bytes_1.EMPTY_BYTES : bytes_1.TEXT_ENCODER.encode(info)) : info;
|
|
12
10
|
const bits = await node_crypto_1.webcrypto.subtle.deriveBits({
|
|
13
11
|
name: 'HKDF',
|
|
14
12
|
hash: 'SHA-256',
|
|
15
13
|
salt: salt ?? bytes_1.EMPTY_BYTES,
|
|
16
|
-
info:
|
|
14
|
+
info: infoBytes
|
|
17
15
|
}, key, outLength * 8);
|
|
18
16
|
return (0, bytes_1.toBytesView)(bits);
|
|
19
17
|
}
|
|
20
|
-
/**
|
|
21
|
-
* HKDF key derivation that outputs two 32-byte keys
|
|
22
|
-
*/
|
|
23
18
|
async function hkdfSplit(ikm, salt, info) {
|
|
24
19
|
const out = await hkdf(ikm, salt, info, 64);
|
|
25
|
-
return [out.subarray(0, 32), out.subarray(32
|
|
20
|
+
return [out.subarray(0, 32), out.subarray(32)];
|
|
26
21
|
}
|
|
@@ -3,14 +3,11 @@
|
|
|
3
3
|
* Cryptographic utilities
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ed25519VerifyRaw = exports.aesCtrDecrypt = exports.aesCtrEncrypt = exports.pbkdf2DeriveAesCtrKey = exports.hmacSign = exports.importHmacSha512Key = exports.importHmacKey = exports.aesCbcDecrypt = exports.aesCbcEncrypt = exports.importAesCbcKey = exports.aesGcmDecrypt = exports.aesGcmEncrypt = exports.importAesGcmKey = exports.sha512 = exports.sha256 = exports.sha1 = exports.randomIntAsync = exports.randomBytesAsync = exports.buildNonce = exports.readVersionedContent = exports.prependVersion = exports.toRawPubKey = exports.toSerializedPubKey = exports.hkdfSplit = exports.hkdf = exports.
|
|
6
|
+
exports.ed25519VerifyRaw = exports.aesCtrDecrypt = exports.aesCtrEncrypt = exports.pbkdf2DeriveAesCtrKey = exports.hmacSign = exports.importHmacSha512Key = exports.importHmacKey = exports.aesCbcDecrypt = exports.aesCbcEncrypt = exports.importAesCbcKey = exports.aesGcmDecrypt = exports.aesGcmEncrypt = exports.importAesGcmKey = exports.sha512 = exports.sha256 = exports.sha1 = exports.randomIntAsync = exports.randomBytesAsync = exports.buildNonce = exports.readVersionedContent = exports.prependVersion = exports.toRawPubKey = exports.toSerializedPubKey = exports.hkdfSplit = exports.hkdf = exports.X25519 = exports.Ed25519 = void 0;
|
|
7
7
|
var Ed25519_1 = require("../curves/Ed25519");
|
|
8
8
|
Object.defineProperty(exports, "Ed25519", { enumerable: true, get: function () { return Ed25519_1.Ed25519; } });
|
|
9
9
|
var X25519_1 = require("../curves/X25519");
|
|
10
10
|
Object.defineProperty(exports, "X25519", { enumerable: true, get: function () { return X25519_1.X25519; } });
|
|
11
|
-
var encoding_1 = require("../core/encoding");
|
|
12
|
-
Object.defineProperty(exports, "decodeBase64Url", { enumerable: true, get: function () { return encoding_1.decodeBase64Url; } });
|
|
13
|
-
Object.defineProperty(exports, "assert32", { enumerable: true, get: function () { return encoding_1.assert32; } });
|
|
14
11
|
var hkdf_1 = require("../core/hkdf");
|
|
15
12
|
Object.defineProperty(exports, "hkdf", { enumerable: true, get: function () { return hkdf_1.hkdf; } });
|
|
16
13
|
Object.defineProperty(exports, "hkdfSplit", { enumerable: true, get: function () { return hkdf_1.hkdfSplit; } });
|
package/dist/crypto/core/keys.js
CHANGED
|
@@ -6,6 +6,7 @@ exports.versionByte = versionByte;
|
|
|
6
6
|
exports.prependVersion = prependVersion;
|
|
7
7
|
exports.readVersionedContent = readVersionedContent;
|
|
8
8
|
const constants_1 = require("../core/constants");
|
|
9
|
+
const bytes_1 = require("../../util/bytes");
|
|
9
10
|
/**
|
|
10
11
|
* Converts a 32-byte raw public key to 33-byte serialized format (with 0x05 prefix)
|
|
11
12
|
*/
|
|
@@ -16,9 +17,7 @@ function toSerializedPubKey(key) {
|
|
|
16
17
|
}
|
|
17
18
|
return key;
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
-
throw new Error(`invalid signal public key length ${key.length}`);
|
|
21
|
-
}
|
|
20
|
+
(0, bytes_1.assertByteLength)(key, 32, `invalid signal public key length ${key.length}`);
|
|
22
21
|
const out = new Uint8Array(33);
|
|
23
22
|
out[0] = constants_1.SERIALIZED_PUB_KEY_PREFIX;
|
|
24
23
|
out.set(key, 1);
|
|
@@ -22,17 +22,20 @@ exports.aesCtrDecrypt = aesCtrDecrypt;
|
|
|
22
22
|
exports.ed25519VerifyRaw = ed25519VerifyRaw;
|
|
23
23
|
const node_crypto_1 = require("node:crypto");
|
|
24
24
|
const bytes_1 = require("../../util/bytes");
|
|
25
|
+
async function digestBytes(algorithm, value) {
|
|
26
|
+
return (0, bytes_1.toBytesView)(await node_crypto_1.webcrypto.subtle.digest(algorithm, value));
|
|
27
|
+
}
|
|
25
28
|
// ============================================
|
|
26
29
|
// Hash functions
|
|
27
30
|
// ============================================
|
|
28
31
|
async function sha256(value) {
|
|
29
|
-
return (
|
|
32
|
+
return digestBytes('SHA-256', value);
|
|
30
33
|
}
|
|
31
34
|
async function sha1(value) {
|
|
32
|
-
return (
|
|
35
|
+
return digestBytes('SHA-1', value);
|
|
33
36
|
}
|
|
34
37
|
async function sha512(value) {
|
|
35
|
-
return (
|
|
38
|
+
return digestBytes('SHA-512', value);
|
|
36
39
|
}
|
|
37
40
|
function md5Bytes(input) {
|
|
38
41
|
return (0, bytes_1.toBytesView)((0, node_crypto_1.createHash)('md5').update(input).digest());
|
|
@@ -44,12 +47,10 @@ async function importAesGcmKey(raw, usages) {
|
|
|
44
47
|
return node_crypto_1.webcrypto.subtle.importKey('raw', raw, 'AES-GCM', false, usages);
|
|
45
48
|
}
|
|
46
49
|
async function aesGcmEncrypt(key, nonce, plaintext, aad = bytes_1.EMPTY_BYTES) {
|
|
47
|
-
|
|
48
|
-
return (0, bytes_1.toBytesView)(result);
|
|
50
|
+
return (0, bytes_1.toBytesView)(await node_crypto_1.webcrypto.subtle.encrypt({ name: 'AES-GCM', iv: nonce, additionalData: aad }, key, plaintext));
|
|
49
51
|
}
|
|
50
52
|
async function aesGcmDecrypt(key, nonce, ciphertext, aad = bytes_1.EMPTY_BYTES) {
|
|
51
|
-
|
|
52
|
-
return (0, bytes_1.toBytesView)(result);
|
|
53
|
+
return (0, bytes_1.toBytesView)(await node_crypto_1.webcrypto.subtle.decrypt({ name: 'AES-GCM', iv: nonce, additionalData: aad }, key, ciphertext));
|
|
53
54
|
}
|
|
54
55
|
// ============================================
|
|
55
56
|
// AES-CBC (for Signal protocol)
|
|
@@ -61,12 +62,10 @@ async function importAesCbcKey(keyBytes) {
|
|
|
61
62
|
]);
|
|
62
63
|
}
|
|
63
64
|
async function aesCbcEncrypt(key, iv, plaintext) {
|
|
64
|
-
|
|
65
|
-
return (0, bytes_1.toBytesView)(result);
|
|
65
|
+
return (0, bytes_1.toBytesView)(await node_crypto_1.webcrypto.subtle.encrypt({ name: 'AES-CBC', iv }, key, plaintext));
|
|
66
66
|
}
|
|
67
67
|
async function aesCbcDecrypt(key, iv, ciphertext) {
|
|
68
|
-
|
|
69
|
-
return (0, bytes_1.toBytesView)(result);
|
|
68
|
+
return (0, bytes_1.toBytesView)(await node_crypto_1.webcrypto.subtle.decrypt({ name: 'AES-CBC', iv }, key, ciphertext));
|
|
70
69
|
}
|
|
71
70
|
// ============================================
|
|
72
71
|
// HMAC-SHA256 (for Signal protocol)
|
|
@@ -105,12 +104,10 @@ async function pbkdf2DeriveAesCtrKey(password, salt, iterations) {
|
|
|
105
104
|
// AES-CTR (for pairing code crypto)
|
|
106
105
|
// ============================================
|
|
107
106
|
async function aesCtrEncrypt(key, counter, plaintext) {
|
|
108
|
-
|
|
109
|
-
return (0, bytes_1.toBytesView)(result);
|
|
107
|
+
return (0, bytes_1.toBytesView)(await node_crypto_1.webcrypto.subtle.encrypt({ name: 'AES-CTR', counter, length: 64 }, key, plaintext));
|
|
110
108
|
}
|
|
111
109
|
async function aesCtrDecrypt(key, counter, ciphertext) {
|
|
112
|
-
|
|
113
|
-
return (0, bytes_1.toBytesView)(result);
|
|
110
|
+
return (0, bytes_1.toBytesView)(await node_crypto_1.webcrypto.subtle.decrypt({ name: 'AES-CTR', counter, length: 64 }, key, ciphertext));
|
|
114
111
|
}
|
|
115
112
|
// ============================================
|
|
116
113
|
// Ed25519 raw verify (for Signal variant sigs)
|
|
@@ -1,32 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.randomIntAsync = void 0;
|
|
3
4
|
exports.randomBytesAsync = randomBytesAsync;
|
|
4
|
-
exports.randomIntAsync = randomIntAsync;
|
|
5
5
|
const node_crypto_1 = require("node:crypto");
|
|
6
|
+
const node_util_1 = require("node:util");
|
|
6
7
|
const bytes_1 = require("../../util/bytes");
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return new Promise((resolve, reject) => {
|
|
12
|
-
(0, node_crypto_1.randomBytes)(size, (error, buffer) => {
|
|
13
|
-
if (error)
|
|
14
|
-
reject(error);
|
|
15
|
-
else
|
|
16
|
-
resolve((0, bytes_1.toBytesView)(buffer));
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Generates a cryptographically secure random integer in the range [min, max)
|
|
22
|
-
*/
|
|
23
|
-
function randomIntAsync(min, max) {
|
|
24
|
-
return new Promise((resolve, reject) => {
|
|
25
|
-
(0, node_crypto_1.randomInt)(min, max, (error, value) => {
|
|
26
|
-
if (error)
|
|
27
|
-
reject(error);
|
|
28
|
-
else
|
|
29
|
-
resolve(value);
|
|
30
|
-
});
|
|
31
|
-
});
|
|
8
|
+
const randomBytesAsyncImpl = (0, node_util_1.promisify)(node_crypto_1.randomBytes);
|
|
9
|
+
const randomIntAsyncImpl = (0, node_util_1.promisify)(node_crypto_1.randomInt);
|
|
10
|
+
async function randomBytesAsync(size) {
|
|
11
|
+
return (0, bytes_1.toBytesView)(await randomBytesAsyncImpl(size));
|
|
32
12
|
}
|
|
13
|
+
exports.randomIntAsync = randomIntAsyncImpl;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Ed25519 = void 0;
|
|
4
4
|
const node_crypto_1 = require("node:crypto");
|
|
5
|
-
const encoding_1 = require("../core/encoding");
|
|
6
5
|
const constants_1 = require("../curves/constants");
|
|
7
6
|
const types_1 = require("../curves/types");
|
|
8
7
|
const bytes_1 = require("../../util/bytes");
|
|
@@ -14,27 +13,27 @@ class Ed25519 {
|
|
|
14
13
|
]));
|
|
15
14
|
const privateJwk = await node_crypto_1.webcrypto.subtle.exportKey('jwk', keys.privateKey);
|
|
16
15
|
return {
|
|
17
|
-
pubKey: (0,
|
|
18
|
-
privKey: (0,
|
|
16
|
+
pubKey: (0, bytes_1.decodeBase64Url)(privateJwk.x, 'ed25519 public key'),
|
|
17
|
+
privKey: (0, bytes_1.decodeBase64Url)(privateJwk.d, 'ed25519 private key')
|
|
19
18
|
};
|
|
20
19
|
}
|
|
21
20
|
static async keyPairFromPrivateKey(privKey) {
|
|
22
|
-
(0,
|
|
21
|
+
(0, bytes_1.assertByteLength)(privKey, 32, 'ed25519 private key must be 32 bytes');
|
|
23
22
|
const privateKey = await node_crypto_1.webcrypto.subtle.importKey('pkcs8', (0, types_1.pkcs8FromRawPrivate)(constants_1.ED25519_PKCS8_PREFIX, privKey), { name: 'Ed25519' }, true, ['sign']);
|
|
24
23
|
const privateJwk = await node_crypto_1.webcrypto.subtle.exportKey('jwk', privateKey);
|
|
25
24
|
return {
|
|
26
|
-
pubKey: (0,
|
|
27
|
-
privKey: (0,
|
|
25
|
+
pubKey: (0, bytes_1.decodeBase64Url)(privateJwk.x, 'ed25519 public key'),
|
|
26
|
+
privKey: (0, bytes_1.decodeBase64Url)(privateJwk.d, 'ed25519 private key')
|
|
28
27
|
};
|
|
29
28
|
}
|
|
30
29
|
static async sign(message, privKey) {
|
|
31
|
-
(0,
|
|
30
|
+
(0, bytes_1.assertByteLength)(privKey, 32, 'ed25519 private key must be 32 bytes');
|
|
32
31
|
const privateKey = await node_crypto_1.webcrypto.subtle.importKey('pkcs8', (0, types_1.pkcs8FromRawPrivate)(constants_1.ED25519_PKCS8_PREFIX, privKey), { name: 'Ed25519' }, false, ['sign']);
|
|
33
32
|
const signature = await node_crypto_1.webcrypto.subtle.sign('Ed25519', privateKey, message);
|
|
34
33
|
return (0, bytes_1.toBytesView)(signature);
|
|
35
34
|
}
|
|
36
35
|
static async verify(message, signature, pubKey) {
|
|
37
|
-
(0,
|
|
36
|
+
(0, bytes_1.assertByteLength)(pubKey, 32, 'ed25519 public key must be 32 bytes');
|
|
38
37
|
const publicKey = await node_crypto_1.webcrypto.subtle.importKey('raw', pubKey, { name: 'Ed25519' }, false, ['verify']);
|
|
39
38
|
return node_crypto_1.webcrypto.subtle.verify('Ed25519', publicKey, signature, message);
|
|
40
39
|
}
|
|
@@ -4,25 +4,20 @@ exports.X25519 = void 0;
|
|
|
4
4
|
exports.clampCurvePrivateKeyInPlace = clampCurvePrivateKeyInPlace;
|
|
5
5
|
exports.montgomeryToEdwardsPublic = montgomeryToEdwardsPublic;
|
|
6
6
|
const node_crypto_1 = require("node:crypto");
|
|
7
|
-
const encoding_1 = require("../core/encoding");
|
|
8
7
|
const constants_1 = require("../curves/constants");
|
|
9
8
|
const types_1 = require("../curves/types");
|
|
10
9
|
const le_1 = require("../math/le");
|
|
11
10
|
const mod_1 = require("../math/mod");
|
|
12
11
|
const bytes_1 = require("../../util/bytes");
|
|
13
12
|
function clampCurvePrivateKeyInPlace(privateKey) {
|
|
14
|
-
|
|
15
|
-
throw new Error(`invalid curve25519 private key length ${privateKey.length}`);
|
|
16
|
-
}
|
|
13
|
+
(0, bytes_1.assertByteLength)(privateKey, 32, `invalid curve25519 private key length ${privateKey.length}`);
|
|
17
14
|
privateKey[0] &= 248;
|
|
18
15
|
privateKey[31] &= 127;
|
|
19
16
|
privateKey[31] |= 64;
|
|
20
17
|
return privateKey;
|
|
21
18
|
}
|
|
22
19
|
function montgomeryToEdwardsPublic(curvePublicKey, signBit) {
|
|
23
|
-
|
|
24
|
-
throw new Error(`invalid curve25519 public key length ${curvePublicKey.length}`);
|
|
25
|
-
}
|
|
20
|
+
(0, bytes_1.assertByteLength)(curvePublicKey, 32, `invalid curve25519 public key length ${curvePublicKey.length}`);
|
|
26
21
|
const x = (0, le_1.bytesToBigIntLE)(curvePublicKey);
|
|
27
22
|
if (x === mod_1.FIELD_P - 1n) {
|
|
28
23
|
throw new Error('invalid curve25519 low-order public key');
|
|
@@ -39,24 +34,26 @@ class X25519 {
|
|
|
39
34
|
]));
|
|
40
35
|
const privateJwk = await node_crypto_1.webcrypto.subtle.exportKey('jwk', keys.privateKey);
|
|
41
36
|
return {
|
|
42
|
-
pubKey: (0,
|
|
43
|
-
privKey: (0,
|
|
37
|
+
pubKey: (0, bytes_1.decodeBase64Url)(privateJwk.x, 'x25519 public key'),
|
|
38
|
+
privKey: (0, bytes_1.decodeBase64Url)(privateJwk.d, 'x25519 private key')
|
|
44
39
|
};
|
|
45
40
|
}
|
|
46
41
|
static async keyPairFromPrivateKey(privKey) {
|
|
47
|
-
(0,
|
|
42
|
+
(0, bytes_1.assertByteLength)(privKey, 32, 'x25519 private key must be 32 bytes');
|
|
48
43
|
const privateKey = await node_crypto_1.webcrypto.subtle.importKey('pkcs8', (0, types_1.pkcs8FromRawPrivate)(constants_1.X25519_PKCS8_PREFIX, privKey), { name: 'X25519' }, true, ['deriveBits']);
|
|
49
44
|
const privateJwk = await node_crypto_1.webcrypto.subtle.exportKey('jwk', privateKey);
|
|
50
45
|
return {
|
|
51
|
-
pubKey: (0,
|
|
52
|
-
privKey: (0,
|
|
46
|
+
pubKey: (0, bytes_1.decodeBase64Url)(privateJwk.x, 'x25519 public key'),
|
|
47
|
+
privKey: (0, bytes_1.decodeBase64Url)(privateJwk.d, 'x25519 private key')
|
|
53
48
|
};
|
|
54
49
|
}
|
|
55
50
|
static async scalarMult(privKey, pubKey) {
|
|
56
|
-
(0,
|
|
57
|
-
(0,
|
|
58
|
-
const privateKey = await
|
|
59
|
-
|
|
51
|
+
(0, bytes_1.assertByteLength)(privKey, 32, 'x25519 private key must be 32 bytes');
|
|
52
|
+
(0, bytes_1.assertByteLength)(pubKey, 32, 'x25519 public key must be 32 bytes');
|
|
53
|
+
const [privateKey, publicKey] = await Promise.all([
|
|
54
|
+
node_crypto_1.webcrypto.subtle.importKey('pkcs8', (0, types_1.pkcs8FromRawPrivate)(constants_1.X25519_PKCS8_PREFIX, privKey), { name: 'X25519' }, false, ['deriveBits']),
|
|
55
|
+
node_crypto_1.webcrypto.subtle.importKey('raw', pubKey, { name: 'X25519' }, false, [])
|
|
56
|
+
]);
|
|
60
57
|
const sharedBits = await node_crypto_1.webcrypto.subtle.deriveBits({ name: 'X25519', public: publicKey }, privateKey, 256);
|
|
61
58
|
return (0, bytes_1.toBytesView)(sharedBits);
|
|
62
59
|
}
|
package/dist/crypto/index.js
CHANGED
|
@@ -14,9 +14,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.X25519 = exports.Ed25519 = void 0;
|
|
18
17
|
__exportStar(require("./core"), exports);
|
|
19
|
-
var Ed25519_1 = require("./curves/Ed25519");
|
|
20
|
-
Object.defineProperty(exports, "Ed25519", { enumerable: true, get: function () { return Ed25519_1.Ed25519; } });
|
|
21
|
-
var X25519_1 = require("./curves/X25519");
|
|
22
|
-
Object.defineProperty(exports, "X25519", { enumerable: true, get: function () { return X25519_1.X25519; } });
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { APP_STATE_DERIVED_INDEX_KEY_END, APP_STATE_DERIVED_KEY_LENGTH, APP_STATE_DERIVED_PATCH_MAC_KEY_END, APP_STATE_DERIVED_SNAPSHOT_MAC_KEY_END, APP_STATE_DERIVED_VALUE_ENCRYPTION_KEY_END, APP_STATE_DERIVED_VALUE_MAC_KEY_END, APP_STATE_EMPTY_LT_HASH, APP_STATE_IV_LENGTH, APP_STATE_MAC_OCTET_LENGTH, APP_STATE_POINT_SIZE, APP_STATE_VALUE_MAC_LENGTH } from './constants.js';
|
|
2
|
-
import { toNetworkOrder64 } from './utils.js';
|
|
3
2
|
import { hkdf } from '../crypto/core/hkdf.js';
|
|
4
3
|
import { aesCbcDecrypt, aesCbcEncrypt, hmacSign, importAesCbcKey, importHmacKey, importHmacSha512Key } from '../crypto/core/primitives.js';
|
|
5
4
|
import { randomBytesAsync } from '../crypto/core/random.js';
|
|
6
5
|
import { proto } from '../proto.js';
|
|
7
6
|
import { WA_APP_STATE_KDF_INFO } from '../protocol/constants.js';
|
|
8
|
-
import { bytesToBase64 } from '../util/
|
|
9
|
-
import { concatBytes, EMPTY_BYTES, TEXT_DECODER, TEXT_ENCODER, uint8Equal } from '../util/bytes.js';
|
|
7
|
+
import { bytesToBase64 } from '../util/bytes.js';
|
|
8
|
+
import { concatBytes, EMPTY_BYTES, intToBytes, TEXT_DECODER, TEXT_ENCODER, uint8Equal } from '../util/bytes.js';
|
|
10
9
|
import { setBoundedMapEntry } from '../util/collections.js';
|
|
10
|
+
import { normalizeNonNegativeInteger } from '../util/primitives.js';
|
|
11
11
|
const DEFAULT_DERIVED_KEYS_CACHE_MAX_SIZE = 256;
|
|
12
12
|
export class WaAppStateCrypto {
|
|
13
13
|
constructor(derivedKeysCacheMaxSize = DEFAULT_DERIVED_KEYS_CACHE_MAX_SIZE) {
|
|
14
14
|
this.derivedKeysCache = new Map();
|
|
15
|
-
this.derivedKeysCacheMaxSize =
|
|
16
|
-
this.normalizeDerivedKeysCacheMaxSize(derivedKeysCacheMaxSize);
|
|
15
|
+
this.derivedKeysCacheMaxSize = normalizeNonNegativeInteger(derivedKeysCacheMaxSize, DEFAULT_DERIVED_KEYS_CACHE_MAX_SIZE);
|
|
17
16
|
}
|
|
18
17
|
clearCache() {
|
|
19
18
|
this.derivedKeysCache.clear();
|
|
@@ -107,7 +106,7 @@ export class WaAppStateCrypto {
|
|
|
107
106
|
const derivedKeys = await this.deriveKeys(keyData);
|
|
108
107
|
const payload = concatBytes([
|
|
109
108
|
ltHash,
|
|
110
|
-
|
|
109
|
+
intToBytes(8, version),
|
|
111
110
|
TEXT_ENCODER.encode(collectionName)
|
|
112
111
|
]);
|
|
113
112
|
const key = await importHmacKey(derivedKeys.snapshotMacKey);
|
|
@@ -118,7 +117,7 @@ export class WaAppStateCrypto {
|
|
|
118
117
|
const payload = concatBytes([
|
|
119
118
|
snapshotMac,
|
|
120
119
|
...valueMacs,
|
|
121
|
-
|
|
120
|
+
intToBytes(8, version),
|
|
122
121
|
TEXT_ENCODER.encode(collectionName)
|
|
123
122
|
]);
|
|
124
123
|
const key = await importHmacKey(derivedKeys.patchMacKey);
|
|
@@ -183,12 +182,6 @@ export class WaAppStateCrypto {
|
|
|
183
182
|
const full = await hmacSign(key, concatBytes([associatedData, cipherWithIv, octetLength]));
|
|
184
183
|
return full.slice(0, APP_STATE_VALUE_MAC_LENGTH);
|
|
185
184
|
}
|
|
186
|
-
normalizeDerivedKeysCacheMaxSize(value) {
|
|
187
|
-
if (!Number.isFinite(value)) {
|
|
188
|
-
return DEFAULT_DERIVED_KEYS_CACHE_MAX_SIZE;
|
|
189
|
-
}
|
|
190
|
-
return Math.max(0, Math.trunc(value));
|
|
191
|
-
}
|
|
192
185
|
touchDerivedKeysCacheEntry(cacheKey, keys) {
|
|
193
186
|
if (this.derivedKeysCacheMaxSize <= 0) {
|
|
194
187
|
return;
|