@zapo-js/fake-server 0.3.0 → 1.0.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 +3 -3
- package/dist/api/AppStateSyncManager.d.ts +0 -1
- package/dist/api/AppStateSyncManager.js +0 -1
- package/dist/api/FakePairingDriver.d.ts +0 -1
- package/dist/api/FakePairingDriver.js +0 -1
- package/dist/api/FakePeer.d.ts +77 -4
- package/dist/api/FakePeer.js +201 -1
- package/dist/api/FakeWaServer.d.ts +11 -1
- package/dist/api/FakeWaServer.js +34 -2
- package/dist/api/PreKeyDispenser.d.ts +0 -1
- package/dist/api/PreKeyDispenser.js +0 -1
- package/dist/api/Scenario.d.ts +0 -1
- package/dist/api/Scenario.js +0 -1
- package/dist/api/ServerRegistries.d.ts +0 -1
- package/dist/api/ServerRegistries.js +0 -1
- package/dist/api/iq-handlers.d.ts +0 -1
- package/dist/api/iq-handlers.js +0 -1
- package/dist/{cli.d.ts → bin.d.ts} +0 -1
- package/dist/{cli.js → bin.js} +1 -2
- package/dist/esm/api/AppStateSyncManager.js +146 -0
- package/dist/esm/api/FakePairingDriver.js +31 -0
- package/dist/esm/api/FakePeer.js +604 -0
- package/dist/esm/api/FakeWaServer.js +680 -0
- package/dist/esm/api/PreKeyDispenser.js +93 -0
- package/dist/esm/api/Scenario.js +32 -0
- package/dist/esm/api/ServerRegistries.js +261 -0
- package/dist/esm/api/iq-handlers.js +492 -0
- package/dist/esm/bin.js +246 -0
- package/dist/esm/index.js +26 -0
- package/dist/esm/infra/WaFakeConnection.js +49 -0
- package/dist/esm/infra/WaFakeConnectionPipeline.js +223 -0
- package/dist/esm/infra/WaFakeFrameSocket.js +117 -0
- package/dist/esm/infra/WaFakeMediaHttpsServer.js +126 -0
- package/dist/esm/infra/WaFakeNoiseHandshake.js +67 -0
- package/dist/esm/infra/WaFakeTransport.js +31 -0
- package/dist/esm/infra/WaFakeWsServer.js +96 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/protocol/auth/cert-chain.js +39 -0
- package/dist/esm/protocol/auth/client-payload-validate.js +55 -0
- package/dist/esm/protocol/auth/fake-primary-device.js +47 -0
- package/dist/esm/protocol/auth/pair-device.js +87 -0
- package/dist/esm/protocol/auth/success-node.js +26 -0
- package/dist/esm/protocol/iq/abprops.js +30 -0
- package/dist/esm/protocol/iq/appstate-sync.js +146 -0
- package/dist/esm/protocol/iq/business.js +59 -0
- package/dist/esm/protocol/iq/dirty-bits.js +19 -0
- package/dist/esm/protocol/iq/group-ops.js +154 -0
- package/dist/esm/protocol/iq/newsletter.js +14 -0
- package/dist/esm/protocol/iq/prekey-fetch.js +88 -0
- package/dist/esm/protocol/iq/privacy-token.js +26 -0
- package/dist/esm/protocol/iq/privacy.js +123 -0
- package/dist/esm/protocol/iq/profile.js +72 -0
- package/dist/esm/protocol/iq/router.js +111 -0
- package/dist/esm/protocol/iq/usync.js +64 -0
- package/dist/esm/protocol/push/app-state-key-share.js +26 -0
- package/dist/esm/protocol/push/call-failure.js +27 -0
- package/dist/esm/protocol/push/chatstate.js +23 -0
- package/dist/esm/protocol/push/error-stanza.js +13 -0
- package/dist/esm/protocol/push/history-sync.js +111 -0
- package/dist/esm/protocol/push/message.js +38 -0
- package/dist/esm/protocol/push/notification.js +29 -0
- package/dist/esm/protocol/push/presence.js +14 -0
- package/dist/esm/protocol/push/receipt.js +21 -0
- package/dist/esm/protocol/signal/fake-app-state-crypto.js +196 -0
- package/dist/esm/protocol/signal/fake-peer-double-ratchet.js +398 -0
- package/dist/esm/protocol/signal/fake-peer-group-recv-session.js +120 -0
- package/dist/esm/protocol/signal/fake-peer-identity.js +8 -0
- package/dist/esm/protocol/signal/fake-peer-key-bundle.js +25 -0
- package/dist/esm/protocol/signal/fake-sender-key.js +83 -0
- package/dist/esm/protocol/signal/prekey-upload.js +107 -0
- package/dist/esm/protocol/stream/stream-error.js +56 -0
- package/dist/esm/state/fake-app-state-collection.js +134 -0
- package/dist/esm/state/fake-media-store.js +53 -0
- package/dist/esm/transport/codec.js +8 -0
- package/dist/esm/transport/crypto.js +8 -0
- package/dist/esm/transport/protos.js +7 -0
- package/dist/esm/transport/util.js +8 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/infra/WaFakeConnection.d.ts +0 -1
- package/dist/infra/WaFakeConnection.js +0 -1
- package/dist/infra/WaFakeConnectionPipeline.d.ts +0 -1
- package/dist/infra/WaFakeConnectionPipeline.js +27 -24
- package/dist/infra/WaFakeFrameSocket.d.ts +0 -1
- package/dist/infra/WaFakeFrameSocket.js +0 -1
- package/dist/infra/WaFakeMediaHttpsServer.d.ts +0 -1
- package/dist/infra/WaFakeMediaHttpsServer.js +0 -1
- package/dist/infra/WaFakeNoiseHandshake.d.ts +8 -10
- package/dist/infra/WaFakeNoiseHandshake.js +19 -24
- package/dist/infra/WaFakeTransport.d.ts +2 -4
- package/dist/infra/WaFakeTransport.js +2 -1
- package/dist/infra/WaFakeWsServer.d.ts +0 -1
- package/dist/infra/WaFakeWsServer.js +0 -1
- package/dist/protocol/auth/cert-chain.d.ts +0 -1
- package/dist/protocol/auth/cert-chain.js +0 -1
- package/dist/protocol/auth/client-payload-validate.d.ts +0 -1
- package/dist/protocol/auth/client-payload-validate.js +0 -1
- package/dist/protocol/auth/fake-primary-device.d.ts +0 -1
- package/dist/protocol/auth/fake-primary-device.js +1 -3
- package/dist/protocol/auth/pair-device.d.ts +0 -1
- package/dist/protocol/auth/pair-device.js +4 -16
- package/dist/protocol/auth/success-node.d.ts +0 -1
- package/dist/protocol/auth/success-node.js +0 -1
- package/dist/protocol/iq/abprops.d.ts +0 -1
- package/dist/protocol/iq/abprops.js +0 -1
- package/dist/protocol/iq/appstate-sync.d.ts +0 -1
- package/dist/protocol/iq/appstate-sync.js +0 -1
- package/dist/protocol/iq/business.d.ts +0 -1
- package/dist/protocol/iq/business.js +0 -1
- package/dist/protocol/iq/dirty-bits.d.ts +0 -1
- package/dist/protocol/iq/dirty-bits.js +0 -1
- package/dist/protocol/iq/group-ops.d.ts +0 -1
- package/dist/protocol/iq/group-ops.js +0 -1
- package/dist/protocol/iq/newsletter.d.ts +0 -1
- package/dist/protocol/iq/newsletter.js +0 -1
- package/dist/protocol/iq/prekey-fetch.d.ts +0 -1
- package/dist/protocol/iq/prekey-fetch.js +0 -1
- package/dist/protocol/iq/privacy-token.d.ts +0 -1
- package/dist/protocol/iq/privacy-token.js +0 -1
- package/dist/protocol/iq/privacy.d.ts +0 -1
- package/dist/protocol/iq/privacy.js +15 -16
- package/dist/protocol/iq/profile.d.ts +0 -1
- package/dist/protocol/iq/profile.js +0 -1
- package/dist/protocol/iq/router.d.ts +0 -1
- package/dist/protocol/iq/router.js +0 -1
- package/dist/protocol/iq/usync.d.ts +0 -1
- package/dist/protocol/iq/usync.js +0 -1
- package/dist/protocol/push/app-state-key-share.d.ts +0 -1
- package/dist/protocol/push/app-state-key-share.js +0 -1
- package/dist/protocol/push/call-failure.d.ts +0 -1
- package/dist/protocol/push/call-failure.js +0 -1
- package/dist/protocol/push/chatstate.d.ts +0 -1
- package/dist/protocol/push/chatstate.js +0 -1
- package/dist/protocol/push/error-stanza.d.ts +0 -1
- package/dist/protocol/push/error-stanza.js +0 -1
- package/dist/protocol/push/history-sync.d.ts +0 -1
- package/dist/protocol/push/history-sync.js +0 -1
- package/dist/protocol/push/message.d.ts +0 -1
- package/dist/protocol/push/message.js +0 -1
- package/dist/protocol/push/notification.d.ts +0 -1
- package/dist/protocol/push/notification.js +0 -1
- package/dist/protocol/push/presence.d.ts +0 -1
- package/dist/protocol/push/presence.js +0 -1
- package/dist/protocol/push/receipt.d.ts +0 -1
- package/dist/protocol/push/receipt.js +0 -1
- package/dist/protocol/signal/fake-app-state-crypto.d.ts +7 -9
- package/dist/protocol/signal/fake-app-state-crypto.js +31 -33
- package/dist/protocol/signal/fake-peer-double-ratchet.d.ts +0 -1
- package/dist/protocol/signal/fake-peer-double-ratchet.js +23 -28
- package/dist/protocol/signal/fake-peer-group-recv-session.d.ts +0 -1
- package/dist/protocol/signal/fake-peer-group-recv-session.js +6 -10
- package/dist/protocol/signal/fake-peer-identity.d.ts +0 -1
- package/dist/protocol/signal/fake-peer-identity.js +0 -1
- package/dist/protocol/signal/fake-peer-key-bundle.d.ts +0 -1
- package/dist/protocol/signal/fake-peer-key-bundle.js +0 -1
- package/dist/protocol/signal/fake-sender-key.d.ts +0 -1
- package/dist/protocol/signal/fake-sender-key.js +5 -9
- package/dist/protocol/signal/prekey-upload.d.ts +0 -1
- package/dist/protocol/signal/prekey-upload.js +0 -1
- package/dist/protocol/stream/stream-error.d.ts +0 -1
- package/dist/protocol/stream/stream-error.js +0 -1
- package/dist/state/fake-app-state-collection.d.ts +0 -1
- package/dist/state/fake-app-state-collection.js +0 -1
- package/dist/state/fake-media-store.d.ts +0 -1
- package/dist/state/fake-media-store.js +2 -2
- package/dist/transport/codec.d.ts +2 -3
- package/dist/transport/codec.js +2 -3
- package/dist/transport/crypto.d.ts +5 -7
- package/dist/transport/crypto.js +6 -11
- package/dist/transport/protos.d.ts +2 -4
- package/dist/transport/protos.js +2 -4
- package/dist/transport/util.d.ts +8 -0
- package/dist/transport/util.js +15 -0
- package/package.json +21 -6
- package/dist/api/AppStateSyncManager.d.ts.map +0 -1
- package/dist/api/AppStateSyncManager.js.map +0 -1
- package/dist/api/FakePairingDriver.d.ts.map +0 -1
- package/dist/api/FakePairingDriver.js.map +0 -1
- package/dist/api/FakePeer.d.ts.map +0 -1
- package/dist/api/FakePeer.js.map +0 -1
- package/dist/api/FakeWaServer.d.ts.map +0 -1
- package/dist/api/FakeWaServer.js.map +0 -1
- package/dist/api/PreKeyDispenser.d.ts.map +0 -1
- package/dist/api/PreKeyDispenser.js.map +0 -1
- package/dist/api/Scenario.d.ts.map +0 -1
- package/dist/api/Scenario.js.map +0 -1
- package/dist/api/ServerRegistries.d.ts.map +0 -1
- package/dist/api/ServerRegistries.js.map +0 -1
- package/dist/api/iq-handlers.d.ts.map +0 -1
- package/dist/api/iq-handlers.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/infra/WaFakeConnection.d.ts.map +0 -1
- package/dist/infra/WaFakeConnection.js.map +0 -1
- package/dist/infra/WaFakeConnectionPipeline.d.ts.map +0 -1
- package/dist/infra/WaFakeConnectionPipeline.js.map +0 -1
- package/dist/infra/WaFakeFrameSocket.d.ts.map +0 -1
- package/dist/infra/WaFakeFrameSocket.js.map +0 -1
- package/dist/infra/WaFakeMediaHttpsServer.d.ts.map +0 -1
- package/dist/infra/WaFakeMediaHttpsServer.js.map +0 -1
- package/dist/infra/WaFakeNoiseHandshake.d.ts.map +0 -1
- package/dist/infra/WaFakeNoiseHandshake.js.map +0 -1
- package/dist/infra/WaFakeTransport.d.ts.map +0 -1
- package/dist/infra/WaFakeTransport.js.map +0 -1
- package/dist/infra/WaFakeWsServer.d.ts.map +0 -1
- package/dist/infra/WaFakeWsServer.js.map +0 -1
- package/dist/protocol/auth/cert-chain.d.ts.map +0 -1
- package/dist/protocol/auth/cert-chain.js.map +0 -1
- package/dist/protocol/auth/client-payload-validate.d.ts.map +0 -1
- package/dist/protocol/auth/client-payload-validate.js.map +0 -1
- package/dist/protocol/auth/fake-primary-device.d.ts.map +0 -1
- package/dist/protocol/auth/fake-primary-device.js.map +0 -1
- package/dist/protocol/auth/pair-device.d.ts.map +0 -1
- package/dist/protocol/auth/pair-device.js.map +0 -1
- package/dist/protocol/auth/success-node.d.ts.map +0 -1
- package/dist/protocol/auth/success-node.js.map +0 -1
- package/dist/protocol/iq/abprops.d.ts.map +0 -1
- package/dist/protocol/iq/abprops.js.map +0 -1
- package/dist/protocol/iq/appstate-sync.d.ts.map +0 -1
- package/dist/protocol/iq/appstate-sync.js.map +0 -1
- package/dist/protocol/iq/business.d.ts.map +0 -1
- package/dist/protocol/iq/business.js.map +0 -1
- package/dist/protocol/iq/dirty-bits.d.ts.map +0 -1
- package/dist/protocol/iq/dirty-bits.js.map +0 -1
- package/dist/protocol/iq/group-ops.d.ts.map +0 -1
- package/dist/protocol/iq/group-ops.js.map +0 -1
- package/dist/protocol/iq/newsletter.d.ts.map +0 -1
- package/dist/protocol/iq/newsletter.js.map +0 -1
- package/dist/protocol/iq/prekey-fetch.d.ts.map +0 -1
- package/dist/protocol/iq/prekey-fetch.js.map +0 -1
- package/dist/protocol/iq/privacy-token.d.ts.map +0 -1
- package/dist/protocol/iq/privacy-token.js.map +0 -1
- package/dist/protocol/iq/privacy.d.ts.map +0 -1
- package/dist/protocol/iq/privacy.js.map +0 -1
- package/dist/protocol/iq/profile.d.ts.map +0 -1
- package/dist/protocol/iq/profile.js.map +0 -1
- package/dist/protocol/iq/router.d.ts.map +0 -1
- package/dist/protocol/iq/router.js.map +0 -1
- package/dist/protocol/iq/usync.d.ts.map +0 -1
- package/dist/protocol/iq/usync.js.map +0 -1
- package/dist/protocol/push/app-state-key-share.d.ts.map +0 -1
- package/dist/protocol/push/app-state-key-share.js.map +0 -1
- package/dist/protocol/push/call-failure.d.ts.map +0 -1
- package/dist/protocol/push/call-failure.js.map +0 -1
- package/dist/protocol/push/chatstate.d.ts.map +0 -1
- package/dist/protocol/push/chatstate.js.map +0 -1
- package/dist/protocol/push/error-stanza.d.ts.map +0 -1
- package/dist/protocol/push/error-stanza.js.map +0 -1
- package/dist/protocol/push/history-sync.d.ts.map +0 -1
- package/dist/protocol/push/history-sync.js.map +0 -1
- package/dist/protocol/push/message.d.ts.map +0 -1
- package/dist/protocol/push/message.js.map +0 -1
- package/dist/protocol/push/notification.d.ts.map +0 -1
- package/dist/protocol/push/notification.js.map +0 -1
- package/dist/protocol/push/presence.d.ts.map +0 -1
- package/dist/protocol/push/presence.js.map +0 -1
- package/dist/protocol/push/receipt.d.ts.map +0 -1
- package/dist/protocol/push/receipt.js.map +0 -1
- package/dist/protocol/signal/fake-app-state-crypto.d.ts.map +0 -1
- package/dist/protocol/signal/fake-app-state-crypto.js.map +0 -1
- package/dist/protocol/signal/fake-peer-double-ratchet.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-double-ratchet.js.map +0 -1
- package/dist/protocol/signal/fake-peer-group-recv-session.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-group-recv-session.js.map +0 -1
- package/dist/protocol/signal/fake-peer-identity.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-identity.js.map +0 -1
- package/dist/protocol/signal/fake-peer-key-bundle.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-key-bundle.js.map +0 -1
- package/dist/protocol/signal/fake-peer-recv-session.d.ts +0 -60
- package/dist/protocol/signal/fake-peer-recv-session.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-recv-session.js +0 -284
- package/dist/protocol/signal/fake-peer-recv-session.js.map +0 -1
- package/dist/protocol/signal/fake-peer-session.d.ts +0 -87
- package/dist/protocol/signal/fake-peer-session.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-session.js +0 -207
- package/dist/protocol/signal/fake-peer-session.js.map +0 -1
- package/dist/protocol/signal/fake-sender-key.d.ts.map +0 -1
- package/dist/protocol/signal/fake-sender-key.js.map +0 -1
- package/dist/protocol/signal/prekey-upload.d.ts.map +0 -1
- package/dist/protocol/signal/prekey-upload.js.map +0 -1
- package/dist/protocol/stream/stream-error.d.ts.map +0 -1
- package/dist/protocol/stream/stream-error.js.map +0 -1
- package/dist/state/fake-app-state-collection.d.ts.map +0 -1
- package/dist/state/fake-app-state-collection.js.map +0 -1
- package/dist/state/fake-media-store.d.ts.map +0 -1
- package/dist/state/fake-media-store.js.map +0 -1
- package/dist/transport/codec.d.ts.map +0 -1
- package/dist/transport/codec.js.map +0 -1
- package/dist/transport/crypto.d.ts.map +0 -1
- package/dist/transport/crypto.js.map +0 -1
- package/dist/transport/index.d.ts +0 -4
- package/dist/transport/index.d.ts.map +0 -1
- package/dist/transport/index.js +0 -20
- package/dist/transport/index.js.map +0 -1
- package/dist/transport/protos.d.ts.map +0 -1
- package/dist/transport/protos.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @zapo-js/fake-server
|
|
2
2
|
|
|
3
|
-
In-process fake WhatsApp Web server that drives the real `zapo-js` `WaClient` end-to-end
|
|
3
|
+
In-process fake WhatsApp Web server that drives the real `zapo-js` `WaClient` end-to-end - full Noise XX/IK handshake, QR pairing, Signal Protocol (X3DH + Double Ratchet), SenderKey for groups, media upload/download over self-signed HTTPS, app-state sync - all without touching WhatsApp servers.
|
|
4
4
|
|
|
5
5
|
## Quick start
|
|
6
6
|
|
|
@@ -29,8 +29,8 @@ await server.stop()
|
|
|
29
29
|
```text
|
|
30
30
|
src/
|
|
31
31
|
├── api/ # Public-facing API
|
|
32
|
-
│ ├── FakeWaServer.ts # Main facade
|
|
33
|
-
│ ├── FakePeer.ts # Simulated WhatsApp peer
|
|
32
|
+
│ ├── FakeWaServer.ts # Main facade – WS server, IQ router, registries, lifecycle
|
|
33
|
+
│ ├── FakePeer.ts # Simulated WhatsApp peer – Signal crypto, send/recv, groups
|
|
34
34
|
│ ├── FakePairingDriver.ts # QR pairing flow orchestrator
|
|
35
35
|
│ └── Scenario.ts # Declarative test scenario DSL
|
|
36
36
|
├── protocol/ # Protocol-layer builders, parsers, crypto
|
|
@@ -24,4 +24,3 @@ export declare class AppStateSyncManager {
|
|
|
24
24
|
pushServerSyncNotification(pipeline: WaFakeConnectionPipeline, input: BuildServerSyncNotificationInput): Promise<void>;
|
|
25
25
|
consumeOutboundAppStatePatches(iq: BinaryNode): Promise<void>;
|
|
26
26
|
}
|
|
27
|
-
//# sourceMappingURL=AppStateSyncManager.d.ts.map
|
package/dist/api/FakePeer.d.ts
CHANGED
|
@@ -12,6 +12,13 @@ export interface CreateFakePeerOptions {
|
|
|
12
12
|
readonly displayName?: string;
|
|
13
13
|
readonly keyBundle?: FakePeerKeyBundle;
|
|
14
14
|
readonly skipOneTimePreKey?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Stash every outbound (id → plaintext + pristine ciphertext) so
|
|
17
|
+
* tests / benches can drive replays via {@link FakePeer.replaySentMessage}.
|
|
18
|
+
* Off by default to avoid inflating the fixture's heap on long
|
|
19
|
+
* memory-focused runs that never replay.
|
|
20
|
+
*/
|
|
21
|
+
readonly enableReplayCache?: boolean;
|
|
15
22
|
}
|
|
16
23
|
export interface SendMessageOptions {
|
|
17
24
|
readonly id?: string;
|
|
@@ -45,20 +52,57 @@ interface FakePeerDeps {
|
|
|
45
52
|
export declare class FakePeer {
|
|
46
53
|
readonly jid: string;
|
|
47
54
|
readonly displayName?: string;
|
|
48
|
-
|
|
55
|
+
keyBundle: FakePeerKeyBundle;
|
|
49
56
|
readonly identity: FakePeerIdentity;
|
|
50
57
|
private readonly deps;
|
|
51
|
-
private
|
|
58
|
+
private ratchet;
|
|
52
59
|
private readonly skipOneTimePreKey;
|
|
53
|
-
private
|
|
60
|
+
private reservedOneTimePreKey;
|
|
54
61
|
private ratchetInitiated;
|
|
55
62
|
private nextMessageCounter;
|
|
63
|
+
private readonly replayCacheEnabled;
|
|
64
|
+
private readonly sentPlaintextById;
|
|
65
|
+
private readonly sentEncryptedById;
|
|
56
66
|
private readonly senderKeysByGroup;
|
|
57
67
|
private readonly groupsBootstrapped;
|
|
58
68
|
private readonly groupRecvSession;
|
|
59
69
|
private constructor();
|
|
60
70
|
static create(options: CreateFakePeerOptions, deps: FakePeerDeps): Promise<FakePeer>;
|
|
61
71
|
sendMessage(message: proto.IMessage, options?: SendMessageOptions): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Re-encrypts and re-pushes a previously sent message identified by
|
|
74
|
+
* `originalMsgId`. Used by tests / benches that exercise the lib's
|
|
75
|
+
* incoming-retry path: after the lib emits `<receipt type="retry">`
|
|
76
|
+
* back to this peer, the peer is expected to re-send the same
|
|
77
|
+
* plaintext so the lib can decrypt it successfully on the second
|
|
78
|
+
* attempt.
|
|
79
|
+
*
|
|
80
|
+
* The replay reuses the original stanza id by default so the lib's
|
|
81
|
+
* dedup logic (and tests that wait for a specific id) see the resend
|
|
82
|
+
* as a continuation of the same outbound. Pass `resendId` to use a
|
|
83
|
+
* different id.
|
|
84
|
+
*/
|
|
85
|
+
replaySentMessage(originalMsgId: string, options?: {
|
|
86
|
+
readonly resendId?: string;
|
|
87
|
+
}): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Rotates the peer's prekey material and resets the Signal session
|
|
90
|
+
* state so the lib has to re-run X3DH on the next outbound. Keeps
|
|
91
|
+
* the identity key pair (same user) but issues a new signed prekey
|
|
92
|
+
* + new one-time prekey set. After this call:
|
|
93
|
+
* - `keyBundle` reflects the new material;
|
|
94
|
+
* - the underlying `FakePeerDoubleRatchet` is fresh – the next
|
|
95
|
+
* inbound from the lib must be a `pkmsg` (initial signal
|
|
96
|
+
* message), which the new `keyBundle` is wired to decrypt;
|
|
97
|
+
* - any cached one-time prekey reservation in the dispenser is
|
|
98
|
+
* dropped so subsequent retry-receipts include this peer's new
|
|
99
|
+
* keys directly via {@link sendRetryReceipt}.
|
|
100
|
+
*
|
|
101
|
+
* Use this to simulate the "session lost" scenario that real
|
|
102
|
+
* WhatsApp clients trigger when they need the sender to fully
|
|
103
|
+
* re-bootstrap the Signal session via the retry-receipt path.
|
|
104
|
+
*/
|
|
105
|
+
rotateForRetry(): Promise<void>;
|
|
62
106
|
sendConversation(text: string, options?: SendMessageOptions): Promise<void>;
|
|
63
107
|
sendMessageEdit(input: {
|
|
64
108
|
readonly targetMessageId: string;
|
|
@@ -131,6 +175,36 @@ export declare class FakePeer {
|
|
|
131
175
|
sendAppStateSyncKeyShare(input: BuildAppStateSyncKeyShareInput, options?: SendMessageOptions): Promise<void>;
|
|
132
176
|
sendGroupConversation(groupJid: string, text: string, options?: SendMessageOptions): Promise<void>;
|
|
133
177
|
sendGroupMessage(groupJid: string, message: proto.IMessage, options?: SendMessageOptions): Promise<void>;
|
|
178
|
+
/**
|
|
179
|
+
* Sends a `<receipt type="retry">` stanza to the lib asking it to
|
|
180
|
+
* re-encrypt and re-send the message identified by `originalMsgId`.
|
|
181
|
+
* Used by benches / tests that exercise the lib's outbound retry
|
|
182
|
+
* replay path.
|
|
183
|
+
*
|
|
184
|
+
* Shape matches WhatsApp Web's `WAWebRetryRequestParser`:
|
|
185
|
+
* `<receipt id type=retry from t><retry id count?/><registration>4B</registration>[<keys>...</keys>]</receipt>`.
|
|
186
|
+
*
|
|
187
|
+
* When `includeKeys` is true (default), the `<keys>` block carries
|
|
188
|
+
* the peer's current identity + signed prekey + one-time prekey.
|
|
189
|
+
* This forces the lib's `WaRetryCoordinator` to tear down the
|
|
190
|
+
* existing session and re-run X3DH against these fresh keys before
|
|
191
|
+
* re-encrypting the original payload, so the resend lands as a
|
|
192
|
+
* `pkmsg` against the peer's *new* prekey state. Pair this with
|
|
193
|
+
* {@link rotateForRetry} to simulate full session loss + recovery.
|
|
194
|
+
*
|
|
195
|
+
* `<device-identity>` is omitted: it's `maybeChild` in wa-web and
|
|
196
|
+
* also optional in the lib's parser. The fake-peer fixture doesn't
|
|
197
|
+
* have an ADV primary-device to sign one, and the lib's outbound
|
|
198
|
+
* retry replay path does not require it.
|
|
199
|
+
*/
|
|
200
|
+
sendRetryReceipt(originalMsgId: string, options?: {
|
|
201
|
+
readonly count?: number;
|
|
202
|
+
readonly receiptId?: string;
|
|
203
|
+
readonly t?: number;
|
|
204
|
+
readonly error?: number;
|
|
205
|
+
readonly includeKeys?: boolean;
|
|
206
|
+
}): Promise<void>;
|
|
207
|
+
private buildRetryKeysNode;
|
|
134
208
|
expectMessage(options?: ExpectMessageOptions): Promise<ReceivedMessage>;
|
|
135
209
|
expectGroupMessage(groupJid: string, options?: ExpectGroupMessageOptions): Promise<ReceivedMessage>;
|
|
136
210
|
private decryptPairwise;
|
|
@@ -140,4 +214,3 @@ export declare class FakePeer {
|
|
|
140
214
|
private nextId;
|
|
141
215
|
}
|
|
142
216
|
export {};
|
|
143
|
-
//# sourceMappingURL=FakePeer.d.ts.map
|
package/dist/api/FakePeer.js
CHANGED
|
@@ -14,6 +14,8 @@ class FakePeer {
|
|
|
14
14
|
constructor(keyBundle, options, deps) {
|
|
15
15
|
this.ratchetInitiated = false;
|
|
16
16
|
this.nextMessageCounter = 0;
|
|
17
|
+
this.sentPlaintextById = new Map();
|
|
18
|
+
this.sentEncryptedById = new Map();
|
|
17
19
|
this.senderKeysByGroup = new Map();
|
|
18
20
|
this.groupsBootstrapped = new Set();
|
|
19
21
|
this.groupRecvSession = new fake_peer_group_recv_session_1.FakePeerGroupRecvSession();
|
|
@@ -26,6 +28,7 @@ class FakePeer {
|
|
|
26
28
|
this.displayName = options.displayName;
|
|
27
29
|
this.deps = deps;
|
|
28
30
|
this.skipOneTimePreKey = options.skipOneTimePreKey === true;
|
|
31
|
+
this.replayCacheEnabled = options.enableReplayCache === true;
|
|
29
32
|
this.reservedOneTimePreKey =
|
|
30
33
|
!this.skipOneTimePreKey && deps.reserveOneTimePreKey
|
|
31
34
|
? deps.reserveOneTimePreKey()
|
|
@@ -45,6 +48,18 @@ class FakePeer {
|
|
|
45
48
|
: ciphertext;
|
|
46
49
|
const enc = { type, ciphertext: finalCiphertext };
|
|
47
50
|
const id = options.id ?? this.nextId();
|
|
51
|
+
if (this.replayCacheEnabled) {
|
|
52
|
+
// Stash the plaintext so the bench / a test can replay this
|
|
53
|
+
// exact payload later in response to an incoming retry
|
|
54
|
+
// receipt from the lib (replaySentMessage). Also stash the
|
|
55
|
+
// PRISTINE ciphertext (pre-tamper) + signal type so a
|
|
56
|
+
// replay can put the original frame back on the wire –
|
|
57
|
+
// matches how a real Signal sender re-sends after a
|
|
58
|
+
// recipient asks for retry: same counter + ratchet key,
|
|
59
|
+
// just an uncorrupted body.
|
|
60
|
+
this.sentPlaintextById.set(id, message);
|
|
61
|
+
this.sentEncryptedById.set(id, { type, ciphertext });
|
|
62
|
+
}
|
|
48
63
|
const stanza = (0, message_1.buildMessage)({
|
|
49
64
|
id,
|
|
50
65
|
from: options.from ?? this.jid,
|
|
@@ -56,6 +71,76 @@ class FakePeer {
|
|
|
56
71
|
});
|
|
57
72
|
await this.deps.pushStanza(stanza);
|
|
58
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Re-encrypts and re-pushes a previously sent message identified by
|
|
76
|
+
* `originalMsgId`. Used by tests / benches that exercise the lib's
|
|
77
|
+
* incoming-retry path: after the lib emits `<receipt type="retry">`
|
|
78
|
+
* back to this peer, the peer is expected to re-send the same
|
|
79
|
+
* plaintext so the lib can decrypt it successfully on the second
|
|
80
|
+
* attempt.
|
|
81
|
+
*
|
|
82
|
+
* The replay reuses the original stanza id by default so the lib's
|
|
83
|
+
* dedup logic (and tests that wait for a specific id) see the resend
|
|
84
|
+
* as a continuation of the same outbound. Pass `resendId` to use a
|
|
85
|
+
* different id.
|
|
86
|
+
*/
|
|
87
|
+
async replaySentMessage(originalMsgId, options = {}) {
|
|
88
|
+
const stored = this.sentEncryptedById.get(originalMsgId);
|
|
89
|
+
if (stored) {
|
|
90
|
+
// Re-send the pristine ciphertext – same Signal counter +
|
|
91
|
+
// ratchet key as the original send, just without the
|
|
92
|
+
// tamper. The lib's recv chain still has the message key
|
|
93
|
+
// for that counter, so this is the recovery path real
|
|
94
|
+
// WhatsApp peers walk after observing a retry receipt for
|
|
95
|
+
// a frame the recipient failed to decrypt.
|
|
96
|
+
const enc = { type: stored.type, ciphertext: stored.ciphertext };
|
|
97
|
+
const id = options.resendId ?? originalMsgId;
|
|
98
|
+
const stanza = (0, message_1.buildMessage)({
|
|
99
|
+
id,
|
|
100
|
+
from: this.jid,
|
|
101
|
+
type: 'text',
|
|
102
|
+
notify: this.displayName,
|
|
103
|
+
enc: [enc]
|
|
104
|
+
});
|
|
105
|
+
await this.deps.pushStanza(stanza);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const message = this.sentPlaintextById.get(originalMsgId);
|
|
109
|
+
if (!message) {
|
|
110
|
+
throw new Error(`FakePeer.replaySentMessage: no sent plaintext for id ${originalMsgId}`);
|
|
111
|
+
}
|
|
112
|
+
await this.sendMessage(message, { id: options.resendId ?? originalMsgId });
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Rotates the peer's prekey material and resets the Signal session
|
|
116
|
+
* state so the lib has to re-run X3DH on the next outbound. Keeps
|
|
117
|
+
* the identity key pair (same user) but issues a new signed prekey
|
|
118
|
+
* + new one-time prekey set. After this call:
|
|
119
|
+
* - `keyBundle` reflects the new material;
|
|
120
|
+
* - the underlying `FakePeerDoubleRatchet` is fresh – the next
|
|
121
|
+
* inbound from the lib must be a `pkmsg` (initial signal
|
|
122
|
+
* message), which the new `keyBundle` is wired to decrypt;
|
|
123
|
+
* - any cached one-time prekey reservation in the dispenser is
|
|
124
|
+
* dropped so subsequent retry-receipts include this peer's new
|
|
125
|
+
* keys directly via {@link sendRetryReceipt}.
|
|
126
|
+
*
|
|
127
|
+
* Use this to simulate the "session lost" scenario that real
|
|
128
|
+
* WhatsApp clients trigger when they need the sender to fully
|
|
129
|
+
* re-bootstrap the Signal session via the retry-receipt path.
|
|
130
|
+
*/
|
|
131
|
+
async rotateForRetry() {
|
|
132
|
+
const refreshed = await (0, fake_peer_key_bundle_1.generateFakePeerKeyBundle)({
|
|
133
|
+
identityKeyPair: this.keyBundle.identityKeyPair,
|
|
134
|
+
registrationId: this.keyBundle.registrationId,
|
|
135
|
+
signedPreKeyId: this.keyBundle.signedPreKey.id + 1,
|
|
136
|
+
firstOneTimePreKeyId: (this.keyBundle.oneTimePreKeys[this.keyBundle.oneTimePreKeys.length - 1]?.id ?? 0) +
|
|
137
|
+
1
|
|
138
|
+
});
|
|
139
|
+
this.keyBundle = refreshed;
|
|
140
|
+
this.ratchet = new fake_peer_double_ratchet_1.FakePeerDoubleRatchet(refreshed);
|
|
141
|
+
this.ratchetInitiated = false;
|
|
142
|
+
this.reservedOneTimePreKey = null;
|
|
143
|
+
}
|
|
59
144
|
sendConversation(text, options = {}) {
|
|
60
145
|
return this.sendMessage({ conversation: text }, options);
|
|
61
146
|
}
|
|
@@ -234,6 +319,112 @@ class FakePeer {
|
|
|
234
319
|
});
|
|
235
320
|
await this.deps.pushStanza(groupStanza);
|
|
236
321
|
}
|
|
322
|
+
/**
|
|
323
|
+
* Sends a `<receipt type="retry">` stanza to the lib asking it to
|
|
324
|
+
* re-encrypt and re-send the message identified by `originalMsgId`.
|
|
325
|
+
* Used by benches / tests that exercise the lib's outbound retry
|
|
326
|
+
* replay path.
|
|
327
|
+
*
|
|
328
|
+
* Shape matches WhatsApp Web's `WAWebRetryRequestParser`:
|
|
329
|
+
* `<receipt id type=retry from t><retry id count?/><registration>4B</registration>[<keys>...</keys>]</receipt>`.
|
|
330
|
+
*
|
|
331
|
+
* When `includeKeys` is true (default), the `<keys>` block carries
|
|
332
|
+
* the peer's current identity + signed prekey + one-time prekey.
|
|
333
|
+
* This forces the lib's `WaRetryCoordinator` to tear down the
|
|
334
|
+
* existing session and re-run X3DH against these fresh keys before
|
|
335
|
+
* re-encrypting the original payload, so the resend lands as a
|
|
336
|
+
* `pkmsg` against the peer's *new* prekey state. Pair this with
|
|
337
|
+
* {@link rotateForRetry} to simulate full session loss + recovery.
|
|
338
|
+
*
|
|
339
|
+
* `<device-identity>` is omitted: it's `maybeChild` in wa-web and
|
|
340
|
+
* also optional in the lib's parser. The fake-peer fixture doesn't
|
|
341
|
+
* have an ADV primary-device to sign one, and the lib's outbound
|
|
342
|
+
* retry replay path does not require it.
|
|
343
|
+
*/
|
|
344
|
+
async sendRetryReceipt(originalMsgId, options = {}) {
|
|
345
|
+
const receiptId = options.receiptId ?? originalMsgId;
|
|
346
|
+
const retryCount = options.count ?? 1;
|
|
347
|
+
const t = options.t ?? Math.floor(Date.now() / 1000);
|
|
348
|
+
const error = options.error;
|
|
349
|
+
const includeKeys = options.includeKeys !== false;
|
|
350
|
+
const registration = new Uint8Array(4);
|
|
351
|
+
const regId = this.keyBundle.registrationId & 0xffffffff;
|
|
352
|
+
registration[0] = (regId >>> 24) & 0xff;
|
|
353
|
+
registration[1] = (regId >>> 16) & 0xff;
|
|
354
|
+
registration[2] = (regId >>> 8) & 0xff;
|
|
355
|
+
registration[3] = regId & 0xff;
|
|
356
|
+
const retryAttrs = {
|
|
357
|
+
v: '1',
|
|
358
|
+
count: String(retryCount),
|
|
359
|
+
id: originalMsgId,
|
|
360
|
+
t: String(t)
|
|
361
|
+
};
|
|
362
|
+
if (error !== undefined && error !== 0) {
|
|
363
|
+
retryAttrs.error = String(error);
|
|
364
|
+
}
|
|
365
|
+
const content = [
|
|
366
|
+
{
|
|
367
|
+
tag: 'retry',
|
|
368
|
+
attrs: retryAttrs
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
tag: 'registration',
|
|
372
|
+
attrs: {},
|
|
373
|
+
content: registration
|
|
374
|
+
}
|
|
375
|
+
];
|
|
376
|
+
if (includeKeys) {
|
|
377
|
+
content.push(this.buildRetryKeysNode());
|
|
378
|
+
}
|
|
379
|
+
const receipt = {
|
|
380
|
+
tag: 'receipt',
|
|
381
|
+
attrs: {
|
|
382
|
+
id: receiptId,
|
|
383
|
+
from: this.jid,
|
|
384
|
+
type: 'retry',
|
|
385
|
+
t: String(t)
|
|
386
|
+
},
|
|
387
|
+
content
|
|
388
|
+
};
|
|
389
|
+
await this.deps.pushStanza(receipt);
|
|
390
|
+
}
|
|
391
|
+
buildRetryKeysNode() {
|
|
392
|
+
const skey = this.keyBundle.signedPreKey;
|
|
393
|
+
const oneTime = this.keyBundle.oneTimePreKeys[0];
|
|
394
|
+
if (!oneTime) {
|
|
395
|
+
throw new Error('FakePeer.sendRetryReceipt: no one-time prekey available');
|
|
396
|
+
}
|
|
397
|
+
const skeyIdBytes = encodeUint3(skey.id);
|
|
398
|
+
const keyIdBytes = encodeUint3(oneTime.id);
|
|
399
|
+
return {
|
|
400
|
+
tag: 'keys',
|
|
401
|
+
attrs: {},
|
|
402
|
+
content: [
|
|
403
|
+
{
|
|
404
|
+
tag: 'identity',
|
|
405
|
+
attrs: {},
|
|
406
|
+
content: this.keyBundle.identityKeyPair.pubKey
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
tag: 'skey',
|
|
410
|
+
attrs: {},
|
|
411
|
+
content: [
|
|
412
|
+
{ tag: 'id', attrs: {}, content: skeyIdBytes },
|
|
413
|
+
{ tag: 'value', attrs: {}, content: skey.keyPair.pubKey },
|
|
414
|
+
{ tag: 'signature', attrs: {}, content: skey.signature }
|
|
415
|
+
]
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
tag: 'key',
|
|
419
|
+
attrs: {},
|
|
420
|
+
content: [
|
|
421
|
+
{ tag: 'id', attrs: {}, content: keyIdBytes },
|
|
422
|
+
{ tag: 'value', attrs: {}, content: oneTime.keyPair.pubKey }
|
|
423
|
+
]
|
|
424
|
+
}
|
|
425
|
+
]
|
|
426
|
+
};
|
|
427
|
+
}
|
|
237
428
|
expectMessage(options = {}) {
|
|
238
429
|
const timeoutMs = options.timeoutMs ?? 5000;
|
|
239
430
|
return new Promise((resolve, reject) => {
|
|
@@ -395,6 +586,16 @@ function findTopLevelEnc(stanza, type) {
|
|
|
395
586
|
}
|
|
396
587
|
return null;
|
|
397
588
|
}
|
|
589
|
+
function encodeUint3(value) {
|
|
590
|
+
if (!Number.isInteger(value) || value < 0 || value > 0xffffff) {
|
|
591
|
+
throw new Error(`encodeUint3: value out of range: ${value}`);
|
|
592
|
+
}
|
|
593
|
+
const out = new Uint8Array(3);
|
|
594
|
+
out[0] = (value >>> 16) & 0xff;
|
|
595
|
+
out[1] = (value >>> 8) & 0xff;
|
|
596
|
+
out[2] = value & 0xff;
|
|
597
|
+
return out;
|
|
598
|
+
}
|
|
398
599
|
function encodePlaintextWithPadding(message) {
|
|
399
600
|
const encoded = protos_1.proto.Message.encode(message).finish();
|
|
400
601
|
const padLen = 16 - (encoded.byteLength % 16);
|
|
@@ -405,4 +606,3 @@ function encodePlaintextWithPadding(message) {
|
|
|
405
606
|
}
|
|
406
607
|
return out;
|
|
407
608
|
}
|
|
408
|
-
//# sourceMappingURL=FakePeer.js.map
|
|
@@ -62,6 +62,7 @@ export declare class FakeWaServer {
|
|
|
62
62
|
private readonly pendingStanzaExpectations;
|
|
63
63
|
private readonly authenticatedListeners;
|
|
64
64
|
private readonly inboundStanzaListeners;
|
|
65
|
+
private readonly capturedStanzaListeners;
|
|
65
66
|
private rootCa;
|
|
66
67
|
private serverStaticKeyPair;
|
|
67
68
|
private listenInfo;
|
|
@@ -122,6 +123,16 @@ export declare class FakeWaServer {
|
|
|
122
123
|
scenario(configure: (s: Scenario) => void): void;
|
|
123
124
|
expectIq(matcher: WaFakeIqMatcher, options?: ExpectIqOptions): Promise<BinaryNode>;
|
|
124
125
|
capturedStanzaSnapshot(): readonly BinaryNode[];
|
|
126
|
+
/**
|
|
127
|
+
* Subscribes to every stanza captured from the client side (the lib).
|
|
128
|
+
* The listener is called synchronously for each new stanza as it
|
|
129
|
+
* arrives, in addition to `capturedStanzas` being appended. Returns
|
|
130
|
+
* an unsubscribe function. Useful for benches that need to count or
|
|
131
|
+
* react to a stream of receipts/messages without paying the O(N²)
|
|
132
|
+
* cost of polling `capturedStanzaSnapshot()` or queuing one
|
|
133
|
+
* `expectStanza(...)` per iteration.
|
|
134
|
+
*/
|
|
135
|
+
onCapturedStanza(listener: (node: BinaryNode) => void): () => void;
|
|
125
136
|
expectStanza(matcher: StanzaMatcher, options?: ExpectStanzaOptions): Promise<BinaryNode>;
|
|
126
137
|
broadcastStanza(node: BinaryNode): Promise<number>;
|
|
127
138
|
waitForAuthenticatedPipeline(timeoutMs?: number): Promise<WaFakeConnectionPipeline>;
|
|
@@ -164,4 +175,3 @@ export declare class FakeWaServer {
|
|
|
164
175
|
}
|
|
165
176
|
export type { WaFakeAuthenticatedInfo, WaFakeConnectionPipeline };
|
|
166
177
|
export type { BinaryNode };
|
|
167
|
-
//# sourceMappingURL=FakeWaServer.d.ts.map
|
package/dist/api/FakeWaServer.js
CHANGED
|
@@ -28,6 +28,7 @@ class FakeWaServer {
|
|
|
28
28
|
this.pendingStanzaExpectations = new Set();
|
|
29
29
|
this.authenticatedListeners = new Set();
|
|
30
30
|
this.inboundStanzaListeners = new Set();
|
|
31
|
+
this.capturedStanzaListeners = new Set();
|
|
31
32
|
this.rootCa = null;
|
|
32
33
|
this.serverStaticKeyPair = null;
|
|
33
34
|
this.listenInfo = null;
|
|
@@ -247,6 +248,21 @@ class FakeWaServer {
|
|
|
247
248
|
capturedStanzaSnapshot() {
|
|
248
249
|
return this.capturedStanzas.slice();
|
|
249
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Subscribes to every stanza captured from the client side (the lib).
|
|
253
|
+
* The listener is called synchronously for each new stanza as it
|
|
254
|
+
* arrives, in addition to `capturedStanzas` being appended. Returns
|
|
255
|
+
* an unsubscribe function. Useful for benches that need to count or
|
|
256
|
+
* react to a stream of receipts/messages without paying the O(N²)
|
|
257
|
+
* cost of polling `capturedStanzaSnapshot()` or queuing one
|
|
258
|
+
* `expectStanza(...)` per iteration.
|
|
259
|
+
*/
|
|
260
|
+
onCapturedStanza(listener) {
|
|
261
|
+
this.capturedStanzaListeners.add(listener);
|
|
262
|
+
return () => {
|
|
263
|
+
this.capturedStanzaListeners.delete(listener);
|
|
264
|
+
};
|
|
265
|
+
}
|
|
250
266
|
expectStanza(matcher, options = {}) {
|
|
251
267
|
const timeoutMs = options.timeoutMs ?? 2000;
|
|
252
268
|
for (const captured of this.capturedStanzas) {
|
|
@@ -318,7 +334,16 @@ class FakeWaServer {
|
|
|
318
334
|
}
|
|
319
335
|
get mediaProxyAgent() {
|
|
320
336
|
if (!this.cachedMediaProxyAgent) {
|
|
321
|
-
|
|
337
|
+
// keepAlive is required for representative perf measurements
|
|
338
|
+
// and matches what real-world WhatsApp clients do – every
|
|
339
|
+
// media upload/download would otherwise pay a full TLS
|
|
340
|
+
// handshake. The `src/media/__tests__/media.test.ts` fixtures
|
|
341
|
+
// and a production-quality `proxy.mediaUpload` configuration
|
|
342
|
+
// all set this; mirroring it here keeps benches in line.
|
|
343
|
+
this.cachedMediaProxyAgent = new node_https_1.Agent({
|
|
344
|
+
rejectUnauthorized: false,
|
|
345
|
+
keepAlive: true
|
|
346
|
+
});
|
|
322
347
|
}
|
|
323
348
|
return this.cachedMediaProxyAgent;
|
|
324
349
|
}
|
|
@@ -472,6 +497,14 @@ class FakeWaServer {
|
|
|
472
497
|
}
|
|
473
498
|
handleCapturedStanza(node) {
|
|
474
499
|
this.capturedStanzas.push(node);
|
|
500
|
+
for (const listener of this.capturedStanzaListeners) {
|
|
501
|
+
try {
|
|
502
|
+
listener(node);
|
|
503
|
+
}
|
|
504
|
+
catch (error) {
|
|
505
|
+
void error;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
475
508
|
for (const listener of this.inboundStanzaListeners) {
|
|
476
509
|
try {
|
|
477
510
|
listener(node);
|
|
@@ -649,4 +682,3 @@ function describeStanzaMatcher(matcher) {
|
|
|
649
682
|
parts.push(`childTag=${matcher.childTag}`);
|
|
650
683
|
return parts.length > 0 ? parts.join(', ') : 'any stanza';
|
|
651
684
|
}
|
|
652
|
-
//# sourceMappingURL=FakeWaServer.js.map
|
package/dist/api/Scenario.d.ts
CHANGED
package/dist/api/Scenario.js
CHANGED
|
@@ -44,4 +44,3 @@ export interface IqHandlerDeps {
|
|
|
44
44
|
export declare function parseUsyncRequestedUserJids(iq: BinaryNode): readonly string[];
|
|
45
45
|
export declare function parseRequestedKeyJids(iq: BinaryNode): readonly string[];
|
|
46
46
|
export declare function registerDefaultIqHandlers(router: WaFakeIqRouter, deps: IqHandlerDeps): void;
|
|
47
|
-
//# sourceMappingURL=iq-handlers.d.ts.map
|
package/dist/api/iq-handlers.js
CHANGED
package/dist/{cli.js → bin.js}
RENAMED
|
@@ -62,7 +62,7 @@ function parseArgs(argv) {
|
|
|
62
62
|
return { host, port, path, peerJids, groupSpecs, log, quiet, json, help };
|
|
63
63
|
}
|
|
64
64
|
function printHelp() {
|
|
65
|
-
process.stdout.write(`@zapo-js/fake-server
|
|
65
|
+
process.stdout.write(`@zapo-js/fake-server – standalone fake WhatsApp Web server
|
|
66
66
|
|
|
67
67
|
USAGE
|
|
68
68
|
npx @zapo-js/fake-server [flags]
|
|
@@ -246,4 +246,3 @@ main().catch((error) => {
|
|
|
246
246
|
process.stderr.write(`fatal: ${error instanceof Error ? (error.stack ?? error.message) : String(error)}\n`);
|
|
247
247
|
process.exit(1);
|
|
248
248
|
});
|
|
249
|
-
//# sourceMappingURL=cli.js.map
|