@zapo-js/fake-server 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 +176 -0
- package/dist/api/AppStateSyncManager.d.ts +27 -0
- package/dist/api/AppStateSyncManager.d.ts.map +1 -0
- package/dist/api/AppStateSyncManager.js +151 -0
- package/dist/api/AppStateSyncManager.js.map +1 -0
- package/dist/api/FakePairingDriver.d.ts +27 -0
- package/dist/api/FakePairingDriver.d.ts.map +1 -0
- package/dist/api/FakePairingDriver.js +36 -0
- package/dist/api/FakePairingDriver.js.map +1 -0
- package/dist/api/FakePeer.d.ts +143 -0
- package/dist/api/FakePeer.d.ts.map +1 -0
- package/dist/api/FakePeer.js +408 -0
- package/dist/api/FakePeer.js.map +1 -0
- package/dist/api/FakeWaServer.d.ts +167 -0
- package/dist/api/FakeWaServer.d.ts.map +1 -0
- package/dist/api/FakeWaServer.js +652 -0
- package/dist/api/FakeWaServer.js.map +1 -0
- package/dist/api/PreKeyDispenser.d.ts +23 -0
- package/dist/api/PreKeyDispenser.d.ts.map +1 -0
- package/dist/api/PreKeyDispenser.js +98 -0
- package/dist/api/PreKeyDispenser.js.map +1 -0
- package/dist/api/Scenario.d.ts +24 -0
- package/dist/api/Scenario.d.ts.map +1 -0
- package/dist/api/Scenario.js +38 -0
- package/dist/api/Scenario.js.map +1 -0
- package/dist/api/ServerRegistries.d.ts +110 -0
- package/dist/api/ServerRegistries.d.ts.map +1 -0
- package/dist/api/ServerRegistries.js +268 -0
- package/dist/api/ServerRegistries.js.map +1 -0
- package/dist/api/iq-handlers.d.ts +47 -0
- package/dist/api/iq-handlers.d.ts.map +1 -0
- package/dist/api/iq-handlers.js +498 -0
- package/dist/api/iq-handlers.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +249 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/infra/WaFakeConnection.d.ts +23 -0
- package/dist/infra/WaFakeConnection.d.ts.map +1 -0
- package/dist/infra/WaFakeConnection.js +54 -0
- package/dist/infra/WaFakeConnection.js.map +1 -0
- package/dist/infra/WaFakeConnectionPipeline.d.ts +51 -0
- package/dist/infra/WaFakeConnectionPipeline.d.ts.map +1 -0
- package/dist/infra/WaFakeConnectionPipeline.js +224 -0
- package/dist/infra/WaFakeConnectionPipeline.js.map +1 -0
- package/dist/infra/WaFakeFrameSocket.d.ts +29 -0
- package/dist/infra/WaFakeFrameSocket.d.ts.map +1 -0
- package/dist/infra/WaFakeFrameSocket.js +122 -0
- package/dist/infra/WaFakeFrameSocket.js.map +1 -0
- package/dist/infra/WaFakeMediaHttpsServer.d.ts +16 -0
- package/dist/infra/WaFakeMediaHttpsServer.d.ts.map +1 -0
- package/dist/infra/WaFakeMediaHttpsServer.js +131 -0
- package/dist/infra/WaFakeMediaHttpsServer.js.map +1 -0
- package/dist/infra/WaFakeNoiseHandshake.d.ts +23 -0
- package/dist/infra/WaFakeNoiseHandshake.d.ts.map +1 -0
- package/dist/infra/WaFakeNoiseHandshake.js +76 -0
- package/dist/infra/WaFakeNoiseHandshake.js.map +1 -0
- package/dist/infra/WaFakeTransport.d.ts +15 -0
- package/dist/infra/WaFakeTransport.d.ts.map +1 -0
- package/dist/infra/WaFakeTransport.js +34 -0
- package/dist/infra/WaFakeTransport.js.map +1 -0
- package/dist/infra/WaFakeWsServer.d.ts +29 -0
- package/dist/infra/WaFakeWsServer.d.ts.map +1 -0
- package/dist/infra/WaFakeWsServer.js +101 -0
- package/dist/infra/WaFakeWsServer.js.map +1 -0
- package/dist/protocol/auth/cert-chain.d.ts +18 -0
- package/dist/protocol/auth/cert-chain.d.ts.map +1 -0
- package/dist/protocol/auth/cert-chain.js +44 -0
- package/dist/protocol/auth/cert-chain.js.map +1 -0
- package/dist/protocol/auth/client-payload-validate.d.ts +21 -0
- package/dist/protocol/auth/client-payload-validate.d.ts.map +1 -0
- package/dist/protocol/auth/client-payload-validate.js +61 -0
- package/dist/protocol/auth/client-payload-validate.js.map +1 -0
- package/dist/protocol/auth/fake-primary-device.d.ts +19 -0
- package/dist/protocol/auth/fake-primary-device.d.ts.map +1 -0
- package/dist/protocol/auth/fake-primary-device.js +53 -0
- package/dist/protocol/auth/fake-primary-device.js.map +1 -0
- package/dist/protocol/auth/pair-device.d.ts +26 -0
- package/dist/protocol/auth/pair-device.d.ts.map +1 -0
- package/dist/protocol/auth/pair-device.js +104 -0
- package/dist/protocol/auth/pair-device.js.map +1 -0
- package/dist/protocol/auth/success-node.d.ts +15 -0
- package/dist/protocol/auth/success-node.d.ts.map +1 -0
- package/dist/protocol/auth/success-node.js +30 -0
- package/dist/protocol/auth/success-node.js.map +1 -0
- package/dist/protocol/iq/abprops.d.ts +14 -0
- package/dist/protocol/iq/abprops.d.ts.map +1 -0
- package/dist/protocol/iq/abprops.js +34 -0
- package/dist/protocol/iq/abprops.js.map +1 -0
- package/dist/protocol/iq/appstate-sync.d.ts +38 -0
- package/dist/protocol/iq/appstate-sync.d.ts.map +1 -0
- package/dist/protocol/iq/appstate-sync.js +154 -0
- package/dist/protocol/iq/appstate-sync.js.map +1 -0
- package/dist/protocol/iq/business.d.ts +13 -0
- package/dist/protocol/iq/business.d.ts.map +1 -0
- package/dist/protocol/iq/business.js +64 -0
- package/dist/protocol/iq/business.js.map +1 -0
- package/dist/protocol/iq/dirty-bits.d.ts +8 -0
- package/dist/protocol/iq/dirty-bits.d.ts.map +1 -0
- package/dist/protocol/iq/dirty-bits.js +23 -0
- package/dist/protocol/iq/dirty-bits.js.map +1 -0
- package/dist/protocol/iq/group-ops.d.ts +34 -0
- package/dist/protocol/iq/group-ops.d.ts.map +1 -0
- package/dist/protocol/iq/group-ops.js +164 -0
- package/dist/protocol/iq/group-ops.js.map +1 -0
- package/dist/protocol/iq/newsletter.d.ts +4 -0
- package/dist/protocol/iq/newsletter.d.ts.map +1 -0
- package/dist/protocol/iq/newsletter.js +18 -0
- package/dist/protocol/iq/newsletter.js.map +1 -0
- package/dist/protocol/iq/prekey-fetch.d.ts +18 -0
- package/dist/protocol/iq/prekey-fetch.d.ts.map +1 -0
- package/dist/protocol/iq/prekey-fetch.js +92 -0
- package/dist/protocol/iq/prekey-fetch.js.map +1 -0
- package/dist/protocol/iq/privacy-token.d.ts +9 -0
- package/dist/protocol/iq/privacy-token.d.ts.map +1 -0
- package/dist/protocol/iq/privacy-token.js +30 -0
- package/dist/protocol/iq/privacy-token.js.map +1 -0
- package/dist/protocol/iq/privacy.d.ts +22 -0
- package/dist/protocol/iq/privacy.d.ts.map +1 -0
- package/dist/protocol/iq/privacy.js +133 -0
- package/dist/protocol/iq/privacy.js.map +1 -0
- package/dist/protocol/iq/profile.d.ts +22 -0
- package/dist/protocol/iq/profile.d.ts.map +1 -0
- package/dist/protocol/iq/profile.js +80 -0
- package/dist/protocol/iq/profile.js.map +1 -0
- package/dist/protocol/iq/router.d.ts +39 -0
- package/dist/protocol/iq/router.d.ts.map +1 -0
- package/dist/protocol/iq/router.js +118 -0
- package/dist/protocol/iq/router.js.map +1 -0
- package/dist/protocol/iq/usync.d.ts +8 -0
- package/dist/protocol/iq/usync.d.ts.map +1 -0
- package/dist/protocol/iq/usync.js +68 -0
- package/dist/protocol/iq/usync.js.map +1 -0
- package/dist/protocol/push/app-state-key-share.d.ts +17 -0
- package/dist/protocol/push/app-state-key-share.d.ts.map +1 -0
- package/dist/protocol/push/app-state-key-share.js +30 -0
- package/dist/protocol/push/app-state-key-share.js.map +1 -0
- package/dist/protocol/push/call-failure.d.ts +16 -0
- package/dist/protocol/push/call-failure.d.ts.map +1 -0
- package/dist/protocol/push/call-failure.js +32 -0
- package/dist/protocol/push/call-failure.js.map +1 -0
- package/dist/protocol/push/chatstate.d.ts +15 -0
- package/dist/protocol/push/chatstate.d.ts.map +1 -0
- package/dist/protocol/push/chatstate.js +27 -0
- package/dist/protocol/push/chatstate.js.map +1 -0
- package/dist/protocol/push/error-stanza.d.ts +8 -0
- package/dist/protocol/push/error-stanza.d.ts.map +1 -0
- package/dist/protocol/push/error-stanza.js +17 -0
- package/dist/protocol/push/error-stanza.js.map +1 -0
- package/dist/protocol/push/history-sync.d.ts +46 -0
- package/dist/protocol/push/history-sync.d.ts.map +1 -0
- package/dist/protocol/push/history-sync.js +117 -0
- package/dist/protocol/push/history-sync.js.map +1 -0
- package/dist/protocol/push/message.d.ts +21 -0
- package/dist/protocol/push/message.d.ts.map +1 -0
- package/dist/protocol/push/message.js +42 -0
- package/dist/protocol/push/message.js.map +1 -0
- package/dist/protocol/push/notification.d.ts +21 -0
- package/dist/protocol/push/notification.d.ts.map +1 -0
- package/dist/protocol/push/notification.js +34 -0
- package/dist/protocol/push/notification.js.map +1 -0
- package/dist/protocol/push/presence.d.ts +11 -0
- package/dist/protocol/push/presence.d.ts.map +1 -0
- package/dist/protocol/push/presence.js +18 -0
- package/dist/protocol/push/presence.js.map +1 -0
- package/dist/protocol/push/receipt.d.ts +14 -0
- package/dist/protocol/push/receipt.d.ts.map +1 -0
- package/dist/protocol/push/receipt.js +25 -0
- package/dist/protocol/push/receipt.js.map +1 -0
- package/dist/protocol/signal/fake-app-state-crypto.d.ts +49 -0
- package/dist/protocol/signal/fake-app-state-crypto.d.ts.map +1 -0
- package/dist/protocol/signal/fake-app-state-crypto.js +202 -0
- package/dist/protocol/signal/fake-app-state-crypto.js.map +1 -0
- package/dist/protocol/signal/fake-peer-double-ratchet.d.ts +38 -0
- package/dist/protocol/signal/fake-peer-double-ratchet.d.ts.map +1 -0
- package/dist/protocol/signal/fake-peer-double-ratchet.js +408 -0
- package/dist/protocol/signal/fake-peer-double-ratchet.js.map +1 -0
- package/dist/protocol/signal/fake-peer-group-recv-session.d.ts +10 -0
- package/dist/protocol/signal/fake-peer-group-recv-session.d.ts.map +1 -0
- package/dist/protocol/signal/fake-peer-group-recv-session.js +129 -0
- package/dist/protocol/signal/fake-peer-group-recv-session.js.map +1 -0
- package/dist/protocol/signal/fake-peer-identity.d.ts +7 -0
- package/dist/protocol/signal/fake-peer-identity.d.ts.map +1 -0
- package/dist/protocol/signal/fake-peer-identity.js +12 -0
- package/dist/protocol/signal/fake-peer-identity.js.map +1 -0
- package/dist/protocol/signal/fake-peer-key-bundle.d.ts +24 -0
- package/dist/protocol/signal/fake-peer-key-bundle.d.ts.map +1 -0
- package/dist/protocol/signal/fake-peer-key-bundle.js +29 -0
- package/dist/protocol/signal/fake-peer-key-bundle.js.map +1 -0
- package/dist/protocol/signal/fake-peer-recv-session.d.ts +60 -0
- package/dist/protocol/signal/fake-peer-recv-session.d.ts.map +1 -0
- package/dist/protocol/signal/fake-peer-recv-session.js +284 -0
- package/dist/protocol/signal/fake-peer-recv-session.js.map +1 -0
- package/dist/protocol/signal/fake-peer-session.d.ts +87 -0
- package/dist/protocol/signal/fake-peer-session.d.ts.map +1 -0
- package/dist/protocol/signal/fake-peer-session.js +207 -0
- package/dist/protocol/signal/fake-peer-session.js.map +1 -0
- package/dist/protocol/signal/fake-sender-key.d.ts +15 -0
- package/dist/protocol/signal/fake-sender-key.d.ts.map +1 -0
- package/dist/protocol/signal/fake-sender-key.js +91 -0
- package/dist/protocol/signal/fake-sender-key.js.map +1 -0
- package/dist/protocol/signal/prekey-upload.d.ts +22 -0
- package/dist/protocol/signal/prekey-upload.d.ts.map +1 -0
- package/dist/protocol/signal/prekey-upload.js +113 -0
- package/dist/protocol/signal/prekey-upload.js.map +1 -0
- package/dist/protocol/stream/stream-error.d.ts +8 -0
- package/dist/protocol/stream/stream-error.d.ts.map +1 -0
- package/dist/protocol/stream/stream-error.js +64 -0
- package/dist/protocol/stream/stream-error.js.map +1 -0
- package/dist/state/fake-app-state-collection.d.ts +35 -0
- package/dist/state/fake-app-state-collection.d.ts.map +1 -0
- package/dist/state/fake-app-state-collection.js +139 -0
- package/dist/state/fake-app-state-collection.js.map +1 -0
- package/dist/state/fake-media-store.d.ts +35 -0
- package/dist/state/fake-media-store.d.ts.map +1 -0
- package/dist/state/fake-media-store.js +57 -0
- package/dist/state/fake-media-store.js.map +1 -0
- package/dist/transport/codec.d.ts +10 -0
- package/dist/transport/codec.d.ts.map +1 -0
- package/dist/transport/codec.js +17 -0
- package/dist/transport/codec.js.map +1 -0
- package/dist/transport/crypto.d.ts +11 -0
- package/dist/transport/crypto.d.ts.map +1 -0
- package/dist/transport/crypto.js +36 -0
- package/dist/transport/crypto.js.map +1 -0
- package/dist/transport/index.d.ts +4 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +20 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/protos.d.ts +10 -0
- package/dist/transport/protos.d.ts.map +1 -0
- package/dist/transport/protos.js +13 -0
- package/dist/transport/protos.js.map +1 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# @zapo-js/fake-server
|
|
2
|
+
|
|
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
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { FakeWaServer } from '@zapo-js/fake-server'
|
|
9
|
+
import { createStore, WaClient } from 'zapo-js'
|
|
10
|
+
|
|
11
|
+
const server = await FakeWaServer.start()
|
|
12
|
+
const client = new WaClient({
|
|
13
|
+
store: createStore({
|
|
14
|
+
providers: { auth: 'memory', signal: 'memory', senderKey: 'memory', appState: 'memory' }
|
|
15
|
+
}),
|
|
16
|
+
chatSocketUrls: [server.url],
|
|
17
|
+
testHooks: { noiseRootCa: server.noiseRootCa },
|
|
18
|
+
proxy: { mediaUpload: server.mediaProxyAgent, mediaDownload: server.mediaProxyAgent }
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
await client.connect()
|
|
22
|
+
const pipeline = await server.waitForAuthenticatedPipeline()
|
|
23
|
+
// ... pair, create peers, send messages
|
|
24
|
+
await server.stop()
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Architecture
|
|
28
|
+
|
|
29
|
+
```text
|
|
30
|
+
src/
|
|
31
|
+
├── api/ # Public-facing API
|
|
32
|
+
│ ├── FakeWaServer.ts # Main facade — WS server, IQ router, registries, lifecycle
|
|
33
|
+
│ ├── FakePeer.ts # Simulated WhatsApp peer — Signal crypto, send/recv, groups
|
|
34
|
+
│ ├── FakePairingDriver.ts # QR pairing flow orchestrator
|
|
35
|
+
│ └── Scenario.ts # Declarative test scenario DSL
|
|
36
|
+
├── protocol/ # Protocol-layer builders, parsers, crypto
|
|
37
|
+
│ ├── auth/ # Pairing, ADV identity, cert chain, client payload
|
|
38
|
+
│ ├── iq/ # IQ stanza handlers (abprops, privacy, groups, profile, ...)
|
|
39
|
+
│ ├── push/ # Inbound stanza builders (message, notification, receipt, ...)
|
|
40
|
+
│ ├── signal/ # Signal Protocol impl (Double Ratchet, SenderKey, prekeys)
|
|
41
|
+
│ └── stream/ # Stream error builders
|
|
42
|
+
├── infra/ # Transport infrastructure
|
|
43
|
+
│ ├── WaFakeWsServer.ts # Raw WebSocket server (ws)
|
|
44
|
+
│ ├── WaFakeConnection.ts # Per-connection WS wrapper
|
|
45
|
+
│ ├── WaFakeConnectionPipeline.ts # Noise handshake + authenticated frame transport
|
|
46
|
+
│ ├── WaFakeFrameSocket.ts # Length-prefixed framing layer
|
|
47
|
+
│ ├── WaFakeTransport.ts # AES-GCM noise transport (post-handshake encrypt/decrypt)
|
|
48
|
+
│ └── WaFakeMediaHttpsServer.ts # Self-signed HTTPS media up/download
|
|
49
|
+
├── state/ # State stores
|
|
50
|
+
│ ├── fake-media-store.ts # In-memory media blob store
|
|
51
|
+
│ └── fake-app-state-collection.ts # App-state patch/snapshot provider
|
|
52
|
+
├── transport/ # Re-exports from zapo-js (codec, crypto, protos)
|
|
53
|
+
└── __tests__/ # Cross-check test suite (147 tests)
|
|
54
|
+
└── helpers/ # Shared test utilities (zapo-client factory)
|
|
55
|
+
|
|
56
|
+
bench/
|
|
57
|
+
├── messaging.bench.ts # 4-scenario messaging profiler (send/recv × 1:1/group)
|
|
58
|
+
├── server-process.ts # Child-process entry for --separate-process mode
|
|
59
|
+
└── server-rpc.ts # IPC client for the child-process server
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Core concepts
|
|
63
|
+
|
|
64
|
+
### FakeWaServer
|
|
65
|
+
|
|
66
|
+
Central facade. Manages the WS listener, noise handshake, IQ router, and all state registries:
|
|
67
|
+
|
|
68
|
+
- **Peer registry** (`peerRegistry`): maps device JIDs → `FakePeer` instances. The global `usync` + `prekey-fetch` IQ handlers consult this.
|
|
69
|
+
- **Group registry** (`groupRegistry`): maps group JIDs → group metadata + participants. The `w:g2` handler serves it.
|
|
70
|
+
- **IQ router** (`WaFakeIqRouter`): first-match-wins stanza dispatcher with `{ xmlns, type, childTag }` matchers. ~20 global handlers registered in the constructor cover every IQ the lib emits during normal operation.
|
|
71
|
+
- **Prekey dispenser**: hands out unique one-time prekeys from the lib's upload to FakePeers. Resets on each forced refill (`triggerPreKeyUpload({ force: true })`).
|
|
72
|
+
- **Listener fan-outs**: `onOutboundGroupOp`, `onOutboundPrivacySet`, `onOutboundBlocklistChange`, `onOutboundProfilePictureSet`, `onOutboundStatusSet`, `onLogout`, `onOutboundPrivacyTokenIssue`, `onOutboundDirtyBitsClear`.
|
|
73
|
+
|
|
74
|
+
### FakePeer
|
|
75
|
+
|
|
76
|
+
Simulated WhatsApp peer with real Signal Protocol crypto:
|
|
77
|
+
|
|
78
|
+
- **1:1 messaging**: `peer.sendConversation(text)` encrypts via Double Ratchet and pushes a `<message><enc type="pkmsg|msg"/></message>` stanza.
|
|
79
|
+
- **Group messaging**: `peer.sendGroupConversation(groupJid, text)` bootstraps a SenderKey chain, encrypts the SKDM via 1:1 session, and sends `<enc type="skmsg"/>`.
|
|
80
|
+
- **Receive**: `peer.expectMessage()` / `peer.expectGroupMessage()` capture and decrypt the lib's outbound stanzas.
|
|
81
|
+
- **X3DH**: each peer generates its own identity keypair, signed prekey, and one-time prekeys. The prekey dispenser ensures unique consumption.
|
|
82
|
+
|
|
83
|
+
### Pairing
|
|
84
|
+
|
|
85
|
+
`server.runPairing(pipeline, { deviceJid }, materialFn)` drives the full QR-pairing flow:
|
|
86
|
+
|
|
87
|
+
1. Sends `pair-device` IQ with random refs
|
|
88
|
+
2. Awaits the `advSecretKey` + `identityPublicKey` from the client's `auth_qr` event
|
|
89
|
+
3. Builds an `ADVSignedDeviceIdentityHMAC` with a fresh fake primary keypair
|
|
90
|
+
4. Pushes `pair-success` IQ
|
|
91
|
+
|
|
92
|
+
After pairing, the lib reconnects with IK handshake. Use `waitForNextAuthenticatedPipeline()` to capture the post-pair pipeline.
|
|
93
|
+
|
|
94
|
+
## IQ coverage
|
|
95
|
+
|
|
96
|
+
Every outbound IQ the lib sends during normal operation is handled:
|
|
97
|
+
|
|
98
|
+
| IQ | Handler | State mutation |
|
|
99
|
+
| -------------------------------------------------------------------------------- | ----------------------------- | --------------------------------------- |
|
|
100
|
+
| `abt` get | `abprops` | Seedable via `setAbProps()` |
|
|
101
|
+
| `w:p` / `urn:xmpp:ping` get | `whatsapp-ping` / `xmpp-ping` | Ack |
|
|
102
|
+
| `encrypt` set | `prekey-upload` | Captures bundle, resets dispenser |
|
|
103
|
+
| `encrypt` get `<digest>` | `signal-digest` | Returns 404 → forces upload |
|
|
104
|
+
| `encrypt` set `<rotate>` | `signed-prekey-rotate` | Ack |
|
|
105
|
+
| `encrypt` get `<key>` | `prekey-fetch` | Serves peer bundles from registry |
|
|
106
|
+
| `usync` get | `usync` | Resolves device IDs from registry |
|
|
107
|
+
| `w:m` set `<media_conn>` | `media-conn` | Points lib at fake HTTPS server |
|
|
108
|
+
| `w:sync:app:state` set | `app-state-sync` | Serves patches/snapshots from providers |
|
|
109
|
+
| `w:g2` get `<query>` | `group-metadata` | Serves from group registry |
|
|
110
|
+
| `w:g2` set `<create\|add\|remove\|promote\|demote\|subject\|description\|leave>` | `group-*` | Mutates group registry |
|
|
111
|
+
| `privacy` get | `privacy-get` | Serves settings + disallowed lists |
|
|
112
|
+
| `privacy` set `<privacy>` | `privacy-set` | Mutates privacy state |
|
|
113
|
+
| `privacy` set `<tokens>` | `privacy-token-issue` | Captures issued tokens |
|
|
114
|
+
| `blocklist` get/set | `blocklist-*` | Mutates blocklist |
|
|
115
|
+
| `w:profile:picture` get/set | `profile-picture-*` | Mutates profile picture registry |
|
|
116
|
+
| `status` set | `status-set` | Captures latest status |
|
|
117
|
+
| `w:biz` get/set | `business-profile-*` | Serves/captures business profiles |
|
|
118
|
+
| `md` set `<remove-companion-device>` | `remove-companion-device` | Fires logout listeners |
|
|
119
|
+
| `newsletter` get `<my_addons>` | `newsletter-my-addons` | Ack |
|
|
120
|
+
| `urn:xmpp:whatsapp:dirty` set | `dirty-bits-clear` | Captures cleared bits |
|
|
121
|
+
|
|
122
|
+
## Benchmarking
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Default: 1000 contacts × 2 devices, 4 groups × 500 members, 1000 msgs/scenario
|
|
126
|
+
npm --workspace=@zapo-js/fake-server run bench:messaging
|
|
127
|
+
|
|
128
|
+
# With CPU + heap profiling (separate process for clean lib-only profiles)
|
|
129
|
+
node --expose-gc --import tsx packages/fake-server/bench/messaging.bench.ts \
|
|
130
|
+
--separate-process --cpu --per-scenario --heap --out-dir=./profiles
|
|
131
|
+
|
|
132
|
+
# Focused on a single scenario
|
|
133
|
+
ZAPO_BENCH_SCENARIOS=send_group ZAPO_BENCH_MESSAGES=2000 \
|
|
134
|
+
node --expose-gc --import tsx packages/fake-server/bench/messaging.bench.ts --cpu
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Profiling flags
|
|
138
|
+
|
|
139
|
+
| Flag | Output |
|
|
140
|
+
| ------------------------- | ---------------------------------------------------------------- |
|
|
141
|
+
| `--cpu` | `cpu-<ts>.cpuprofile` (whole run) |
|
|
142
|
+
| `--heap` | `heap-<ts>.heaptimeline` (allocation tracking) |
|
|
143
|
+
| `--snapshot` | `snapshot-{start,end}-<ts>.heapsnapshot` |
|
|
144
|
+
| `--per-scenario` | Per-scenario CPU profiles |
|
|
145
|
+
| `--snapshot-per-scenario` | Per-scenario heap snapshots |
|
|
146
|
+
| `--separate-process` | Forks fake server into child process for clean lib CPU profiling |
|
|
147
|
+
| `--out-dir=<path>` | Output directory (default: cwd) |
|
|
148
|
+
|
|
149
|
+
### Env vars
|
|
150
|
+
|
|
151
|
+
| Var | Default | Description |
|
|
152
|
+
| ---------------------------- | ------- | ------------------------------------------------------------ |
|
|
153
|
+
| `ZAPO_BENCH_CONTACTS` | 1000 | Number of contacts |
|
|
154
|
+
| `ZAPO_BENCH_CONTACT_DEVICES` | 2 | Devices per contact |
|
|
155
|
+
| `ZAPO_BENCH_GROUPS` | 4 | Number of groups |
|
|
156
|
+
| `ZAPO_BENCH_GROUP_MEMBERS` | 500 | Members per group |
|
|
157
|
+
| `ZAPO_BENCH_MESSAGES` | 1000 | Messages per scenario |
|
|
158
|
+
| `ZAPO_BENCH_SCENARIOS` | all | CSV of: `send_1to1`, `recv_1to1`, `send_group`, `recv_group` |
|
|
159
|
+
| `ZAPO_BENCH_JSON` | 0 | Set to `1` to print JSON results |
|
|
160
|
+
| `ZAPO_BENCH_VERBOSE` | 0 | Set to `1` to forward lib warns/errors |
|
|
161
|
+
|
|
162
|
+
## CLI
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
# Standalone server for manual testing
|
|
166
|
+
npm --workspace=@zapo-js/fake-server run cli -- --port 5222 --peer 5511888@s.whatsapp.net --log
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Test suite
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
npm --workspace=@zapo-js/fake-server test
|
|
173
|
+
# 147 tests, --test-concurrency=1
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Cross-check tests drive a real `WaClient` against the fake server and assert on both sides (lib emits correct events, peer decrypts correctly). Unit tests validate protocol builders/parsers in isolation.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type WaFakeConnectionPipeline } from '../infra/WaFakeConnectionPipeline';
|
|
2
|
+
import { type BuildServerSyncNotificationInput, type FakeAppStateCollectionPayload } from '../protocol/iq/appstate-sync';
|
|
3
|
+
import { FakeAppStateCrypto } from '../protocol/signal/fake-app-state-crypto';
|
|
4
|
+
import { type BinaryNode } from '../transport/codec';
|
|
5
|
+
import { type Proto } from '../transport/protos';
|
|
6
|
+
export interface CapturedAppStateMutation {
|
|
7
|
+
readonly collection: string;
|
|
8
|
+
readonly operation: 'set' | 'remove';
|
|
9
|
+
readonly index: string;
|
|
10
|
+
readonly action: string | undefined;
|
|
11
|
+
readonly version: number;
|
|
12
|
+
readonly value: Proto.ISyncActionValue | null;
|
|
13
|
+
readonly patchVersion: number;
|
|
14
|
+
}
|
|
15
|
+
export declare class AppStateSyncManager {
|
|
16
|
+
readonly appStateCollectionProviders: Map<string, () => Promise<FakeAppStateCollectionPayload | null> | FakeAppStateCollectionPayload | null>;
|
|
17
|
+
readonly appStateSyncKeysByKeyId: Map<string, Uint8Array<ArrayBufferLike>>;
|
|
18
|
+
readonly appStateCrypto: FakeAppStateCrypto;
|
|
19
|
+
readonly outboundMutationListeners: Set<(mutation: CapturedAppStateMutation) => void>;
|
|
20
|
+
registerAppStateSyncKey(keyId: Uint8Array, keyData: Uint8Array): void;
|
|
21
|
+
onOutboundAppStateMutation(listener: (mutation: CapturedAppStateMutation) => void): () => void;
|
|
22
|
+
expectAppStateMutation(predicate: (mutation: CapturedAppStateMutation) => boolean, timeoutMs?: number): Promise<CapturedAppStateMutation>;
|
|
23
|
+
provideAppStateCollection(name: string, provider: () => Promise<FakeAppStateCollectionPayload | null> | FakeAppStateCollectionPayload | null): () => void;
|
|
24
|
+
pushServerSyncNotification(pipeline: WaFakeConnectionPipeline, input: BuildServerSyncNotificationInput): Promise<void>;
|
|
25
|
+
consumeOutboundAppStatePatches(iq: BinaryNode): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=AppStateSyncManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppStateSyncManager.d.ts","sourceRoot":"","sources":["../../src/api/AppStateSyncManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,mCAAmC,CAAA;AACjF,OAAO,EAEH,KAAK,gCAAgC,EACrC,KAAK,6BAA6B,EACrC,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAA;AAC7E,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAS,KAAK,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAEvD,MAAM,WAAW,wBAAwB;IACrC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,SAAS,EAAE,KAAK,GAAG,QAAQ,CAAA;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,gBAAgB,GAAG,IAAI,CAAA;IAC7C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAChC;AAWD,qBAAa,mBAAmB;IAC5B,SAAgB,2BAA2B,oBAEjC,OAAO,CAAC,6BAA6B,GAAG,IAAI,CAAC,GAAG,6BAA6B,GAAG,IAAI,EAC3F;IACH,SAAgB,uBAAuB,2CAAgC;IACvE,SAAgB,cAAc,qBAA2B;IACzD,SAAgB,yBAAyB,iBAC1B,wBAAwB,KAAK,IAAI,EAC7C;IAEI,uBAAuB,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAIrE,0BAA0B,CAC7B,QAAQ,EAAE,CAAC,QAAQ,EAAE,wBAAwB,KAAK,IAAI,GACvD,MAAM,IAAI;IAON,sBAAsB,CACzB,SAAS,EAAE,CAAC,QAAQ,EAAE,wBAAwB,KAAK,OAAO,EAC1D,SAAS,SAAS,GACnB,OAAO,CAAC,wBAAwB,CAAC;IAe7B,yBAAyB,CAC5B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MACJ,OAAO,CAAC,6BAA6B,GAAG,IAAI,CAAC,GAC7C,6BAA6B,GAC7B,IAAI,GACX,MAAM,IAAI;IAOA,0BAA0B,CACnC,QAAQ,EAAE,wBAAwB,EAClC,KAAK,EAAE,gCAAgC,GACxC,OAAO,CAAC,IAAI,CAAC;IAIH,8BAA8B,CAAC,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAiF7E"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AppStateSyncManager = void 0;
|
|
4
|
+
const appstate_sync_1 = require("../protocol/iq/appstate-sync");
|
|
5
|
+
const fake_app_state_crypto_1 = require("../protocol/signal/fake-app-state-crypto");
|
|
6
|
+
const protos_1 = require("../transport/protos");
|
|
7
|
+
function toHex(bytes) {
|
|
8
|
+
let out = '';
|
|
9
|
+
for (let index = 0; index < bytes.byteLength; index += 1) {
|
|
10
|
+
const value = bytes[index];
|
|
11
|
+
out += value < 16 ? `0${value.toString(16)}` : value.toString(16);
|
|
12
|
+
}
|
|
13
|
+
return out;
|
|
14
|
+
}
|
|
15
|
+
class AppStateSyncManager {
|
|
16
|
+
constructor() {
|
|
17
|
+
this.appStateCollectionProviders = new Map();
|
|
18
|
+
this.appStateSyncKeysByKeyId = new Map();
|
|
19
|
+
this.appStateCrypto = new fake_app_state_crypto_1.FakeAppStateCrypto();
|
|
20
|
+
this.outboundMutationListeners = new Set();
|
|
21
|
+
}
|
|
22
|
+
registerAppStateSyncKey(keyId, keyData) {
|
|
23
|
+
this.appStateSyncKeysByKeyId.set(toHex(keyId), keyData);
|
|
24
|
+
}
|
|
25
|
+
onOutboundAppStateMutation(listener) {
|
|
26
|
+
this.outboundMutationListeners.add(listener);
|
|
27
|
+
return () => {
|
|
28
|
+
this.outboundMutationListeners.delete(listener);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
expectAppStateMutation(predicate, timeoutMs = 15000) {
|
|
32
|
+
return new Promise((resolve, reject) => {
|
|
33
|
+
const timer = setTimeout(() => {
|
|
34
|
+
unsubscribe();
|
|
35
|
+
reject(new Error(`expectAppStateMutation timed out after ${timeoutMs}ms`));
|
|
36
|
+
}, timeoutMs);
|
|
37
|
+
const unsubscribe = this.onOutboundAppStateMutation((mutation) => {
|
|
38
|
+
if (!predicate(mutation))
|
|
39
|
+
return;
|
|
40
|
+
clearTimeout(timer);
|
|
41
|
+
unsubscribe();
|
|
42
|
+
resolve(mutation);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
provideAppStateCollection(name, provider) {
|
|
47
|
+
this.appStateCollectionProviders.set(name, provider);
|
|
48
|
+
return () => {
|
|
49
|
+
this.appStateCollectionProviders.delete(name);
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
async pushServerSyncNotification(pipeline, input) {
|
|
53
|
+
await pipeline.sendStanza((0, appstate_sync_1.buildServerSyncNotification)(input));
|
|
54
|
+
}
|
|
55
|
+
async consumeOutboundAppStatePatches(iq) {
|
|
56
|
+
if (!Array.isArray(iq.content))
|
|
57
|
+
return;
|
|
58
|
+
const sync = iq.content.find((child) => child.tag === 'sync');
|
|
59
|
+
if (!sync || !Array.isArray(sync.content))
|
|
60
|
+
return;
|
|
61
|
+
for (const collectionNode of sync.content) {
|
|
62
|
+
if (collectionNode.tag !== 'collection')
|
|
63
|
+
continue;
|
|
64
|
+
if (!Array.isArray(collectionNode.content))
|
|
65
|
+
continue;
|
|
66
|
+
const collectionName = collectionNode.attrs.name;
|
|
67
|
+
if (!collectionName)
|
|
68
|
+
continue;
|
|
69
|
+
for (const patchNode of collectionNode.content) {
|
|
70
|
+
if (patchNode.tag !== 'patch')
|
|
71
|
+
continue;
|
|
72
|
+
const patchBytes = patchNode.content;
|
|
73
|
+
if (!(patchBytes instanceof Uint8Array))
|
|
74
|
+
continue;
|
|
75
|
+
try {
|
|
76
|
+
const decoded = protos_1.proto.SyncdPatch.decode(patchBytes);
|
|
77
|
+
const keyId = decoded.keyId?.id;
|
|
78
|
+
if (!keyId)
|
|
79
|
+
continue;
|
|
80
|
+
const keyData = this.appStateSyncKeysByKeyId.get(toHex(keyId));
|
|
81
|
+
if (!keyData)
|
|
82
|
+
continue;
|
|
83
|
+
const rawVersion = decoded.version?.version;
|
|
84
|
+
let patchVersion = 0;
|
|
85
|
+
if (typeof rawVersion === 'number') {
|
|
86
|
+
patchVersion = rawVersion;
|
|
87
|
+
}
|
|
88
|
+
else if (rawVersion !== null &&
|
|
89
|
+
rawVersion !== undefined &&
|
|
90
|
+
typeof rawVersion.toNumber === 'function') {
|
|
91
|
+
patchVersion = rawVersion.toNumber();
|
|
92
|
+
}
|
|
93
|
+
for (const mutation of decoded.mutations ?? []) {
|
|
94
|
+
const operationCode = mutation.operation;
|
|
95
|
+
if (operationCode === null || operationCode === undefined)
|
|
96
|
+
continue;
|
|
97
|
+
const record = mutation.record;
|
|
98
|
+
if (!record)
|
|
99
|
+
continue;
|
|
100
|
+
const indexMac = record.index?.blob;
|
|
101
|
+
const valueBlob = record.value?.blob;
|
|
102
|
+
if (!indexMac || !valueBlob)
|
|
103
|
+
continue;
|
|
104
|
+
const operation = operationCode === protos_1.proto.SyncdMutation.SyncdOperation.REMOVE
|
|
105
|
+
? 'remove'
|
|
106
|
+
: 'set';
|
|
107
|
+
const decrypted = await this.appStateCrypto.decryptMutation({
|
|
108
|
+
operation,
|
|
109
|
+
keyId,
|
|
110
|
+
keyData,
|
|
111
|
+
indexMac,
|
|
112
|
+
valueBlob
|
|
113
|
+
});
|
|
114
|
+
let action;
|
|
115
|
+
try {
|
|
116
|
+
const parsed = JSON.parse(decrypted.index);
|
|
117
|
+
if (Array.isArray(parsed) && typeof parsed[0] === 'string') {
|
|
118
|
+
action = parsed[0];
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// Ignore malformed index payloads; mutation capture still proceeds.
|
|
123
|
+
}
|
|
124
|
+
const captured = {
|
|
125
|
+
collection: collectionName,
|
|
126
|
+
operation,
|
|
127
|
+
index: decrypted.index,
|
|
128
|
+
action,
|
|
129
|
+
version: decrypted.version,
|
|
130
|
+
value: decrypted.value,
|
|
131
|
+
patchVersion
|
|
132
|
+
};
|
|
133
|
+
for (const listener of this.outboundMutationListeners) {
|
|
134
|
+
try {
|
|
135
|
+
listener(captured);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
// Listener failures are best-effort.
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// Ignore malformed/undecryptable patches.
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
exports.AppStateSyncManager = AppStateSyncManager;
|
|
151
|
+
//# sourceMappingURL=AppStateSyncManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppStateSyncManager.js","sourceRoot":"","sources":["../../src/api/AppStateSyncManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Runs the server side of the QR pairing flow. */
|
|
2
|
+
import type { WaFakeConnectionPipeline } from '../infra/WaFakeConnectionPipeline';
|
|
3
|
+
import { type FakePrimaryDevice } from '../protocol/auth/fake-primary-device';
|
|
4
|
+
export interface FakePairingDriverOptions {
|
|
5
|
+
readonly deviceJid: string;
|
|
6
|
+
readonly deviceLid?: string;
|
|
7
|
+
readonly companionDeviceId?: number;
|
|
8
|
+
readonly platform?: string;
|
|
9
|
+
readonly primary?: FakePrimaryDevice;
|
|
10
|
+
}
|
|
11
|
+
export interface CompanionPairingMaterial {
|
|
12
|
+
readonly advSecretKey: Uint8Array;
|
|
13
|
+
readonly identityPublicKey: Uint8Array;
|
|
14
|
+
}
|
|
15
|
+
export interface FakePairingDriverDeps {
|
|
16
|
+
readonly pipeline: WaFakeConnectionPipeline;
|
|
17
|
+
readonly waitForPairDeviceAck?: (pairDeviceIqId: string) => Promise<void>;
|
|
18
|
+
readonly companionMaterialResolver: () => Promise<CompanionPairingMaterial>;
|
|
19
|
+
}
|
|
20
|
+
export declare class FakePairingDriver {
|
|
21
|
+
private readonly options;
|
|
22
|
+
private readonly deps;
|
|
23
|
+
private primary;
|
|
24
|
+
constructor(options: FakePairingDriverOptions, deps: FakePairingDriverDeps);
|
|
25
|
+
run(): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=FakePairingDriver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FakePairingDriver.d.ts","sourceRoot":"","sources":["../../src/api/FakePairingDriver.ts"],"names":[],"mappings":"AAAA,mDAAmD;AAEnD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAA;AACjF,OAAO,EAEH,KAAK,iBAAiB,EAEzB,MAAM,sCAAsC,CAAA;AAI7C,MAAM,WAAW,wBAAwB;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAA;CACvC;AAED,MAAM,WAAW,wBAAwB;IACrC,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAA;IACjC,QAAQ,CAAC,iBAAiB,EAAE,UAAU,CAAA;CACzC;AAED,MAAM,WAAW,qBAAqB;IAClC,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,CAAA;IAC3C,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACzE,QAAQ,CAAC,yBAAyB,EAAE,MAAM,OAAO,CAAC,wBAAwB,CAAC,CAAA;CAC9E;AAED,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuB;IAC5C,OAAO,CAAC,OAAO,CAAiC;gBAE7B,OAAO,EAAE,wBAAwB,EAAE,IAAI,EAAE,qBAAqB;IAKpE,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA2BpC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** Runs the server side of the QR pairing flow. */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.FakePairingDriver = void 0;
|
|
5
|
+
const fake_primary_device_1 = require("../protocol/auth/fake-primary-device");
|
|
6
|
+
const pair_device_1 = require("../protocol/auth/pair-device");
|
|
7
|
+
const crypto_1 = require("../transport/crypto");
|
|
8
|
+
class FakePairingDriver {
|
|
9
|
+
constructor(options, deps) {
|
|
10
|
+
this.primary = null;
|
|
11
|
+
this.options = options;
|
|
12
|
+
this.deps = deps;
|
|
13
|
+
}
|
|
14
|
+
async run() {
|
|
15
|
+
this.primary = this.options.primary ?? (await (0, fake_primary_device_1.generateFakePrimaryDevice)());
|
|
16
|
+
const refs = await Promise.all(Array.from({ length: 6 }, () => (0, crypto_1.randomBytesAsync)(16)));
|
|
17
|
+
const pairDeviceIq = (0, pair_device_1.buildPairDeviceIq)({ refs });
|
|
18
|
+
await this.deps.pipeline.sendStanza(pairDeviceIq);
|
|
19
|
+
const waitForAck = this.deps.waitForPairDeviceAck?.(pairDeviceIq.attrs.id) ?? Promise.resolve();
|
|
20
|
+
const [material] = await Promise.all([this.deps.companionMaterialResolver(), waitForAck]);
|
|
21
|
+
const { deviceIdentityBytes } = await (0, fake_primary_device_1.buildAdvSignedDeviceIdentity)({
|
|
22
|
+
primary: this.primary,
|
|
23
|
+
advSecretKey: material.advSecretKey,
|
|
24
|
+
companionIdentityPublicKey: material.identityPublicKey,
|
|
25
|
+
companionDeviceId: this.options.companionDeviceId ?? 1
|
|
26
|
+
});
|
|
27
|
+
await this.deps.pipeline.sendStanza((0, pair_device_1.buildPairSuccessIq)({
|
|
28
|
+
deviceJid: this.options.deviceJid,
|
|
29
|
+
deviceLid: this.options.deviceLid,
|
|
30
|
+
platform: this.options.platform ?? 'IOS',
|
|
31
|
+
deviceIdentityBytes
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.FakePairingDriver = FakePairingDriver;
|
|
36
|
+
//# sourceMappingURL=FakePairingDriver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FakePairingDriver.js","sourceRoot":"","sources":["../../src/api/FakePairingDriver.ts"],"names":[],"mappings":";AAAA,mDAAmD;;;AAGnD,8EAI6C;AAC7C,8DAAoF;AACpF,gDAAsD;AAqBtD,MAAa,iBAAiB;IAK1B,YAAmB,OAAiC,EAAE,IAA2B;QAFzE,YAAO,GAA6B,IAAI,CAAA;QAG5C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IACpB,CAAC;IAEM,KAAK,CAAC,GAAG;QACZ,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,MAAM,IAAA,+CAAyB,GAAE,CAAC,CAAA;QAE1E,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,IAAA,yBAAgB,EAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACrF,MAAM,YAAY,GAAG,IAAA,+BAAiB,EAAC,EAAE,IAAI,EAAE,CAAC,CAAA;QAChD,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;QACjD,MAAM,UAAU,GACZ,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAA;QAEhF,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,yBAAyB,EAAE,EAAE,UAAU,CAAC,CAAC,CAAA;QAEzF,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,IAAA,kDAA4B,EAAC;YAC/D,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,0BAA0B,EAAE,QAAQ,CAAC,iBAAiB;YACtD,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,IAAI,CAAC;SACzD,CAAC,CAAA;QAEF,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAC/B,IAAA,gCAAkB,EAAC;YACf,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YACjC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YACjC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,KAAK;YACxC,mBAAmB;SACtB,CAAC,CACL,CAAA;IACL,CAAC;CACJ;AArCD,8CAqCC"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/** Fake peer used by tests to encrypt and push Signal messages to the lib. */
|
|
2
|
+
import { type BuildAppStateSyncKeyShareInput } from '../protocol/push/app-state-key-share';
|
|
3
|
+
import { type BuildHistorySyncExternalInput, type BuildHistorySyncInput } from '../protocol/push/history-sync';
|
|
4
|
+
import { buildMessage } from '../protocol/push/message';
|
|
5
|
+
import type { FakePeerIdentity } from '../protocol/signal/fake-peer-identity';
|
|
6
|
+
import { type FakePeerKeyBundle } from '../protocol/signal/fake-peer-key-bundle';
|
|
7
|
+
import type { ClientPreKeyBundle } from '../protocol/signal/prekey-upload';
|
|
8
|
+
import type { BinaryNode } from '../transport/codec';
|
|
9
|
+
import { proto } from '../transport/protos';
|
|
10
|
+
export interface CreateFakePeerOptions {
|
|
11
|
+
readonly jid: string;
|
|
12
|
+
readonly displayName?: string;
|
|
13
|
+
readonly keyBundle?: FakePeerKeyBundle;
|
|
14
|
+
readonly skipOneTimePreKey?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface SendMessageOptions {
|
|
17
|
+
readonly id?: string;
|
|
18
|
+
readonly t?: number;
|
|
19
|
+
readonly type?: string;
|
|
20
|
+
readonly from?: string;
|
|
21
|
+
readonly participant?: string;
|
|
22
|
+
/** Mutates ciphertext before wrapping in `<enc>` (for corruption tests). */
|
|
23
|
+
readonly tamperCiphertext?: (ciphertext: Uint8Array) => Uint8Array;
|
|
24
|
+
}
|
|
25
|
+
export interface ReceivedMessage {
|
|
26
|
+
readonly message: proto.IMessage;
|
|
27
|
+
readonly stanza: BinaryNode;
|
|
28
|
+
readonly encType: 'pkmsg' | 'msg' | 'skmsg';
|
|
29
|
+
}
|
|
30
|
+
export interface ExpectMessageOptions {
|
|
31
|
+
readonly timeoutMs?: number;
|
|
32
|
+
}
|
|
33
|
+
export interface ExpectGroupMessageOptions extends ExpectMessageOptions {
|
|
34
|
+
readonly senderJid?: string;
|
|
35
|
+
}
|
|
36
|
+
interface FakePeerDeps {
|
|
37
|
+
readonly bundleResolver: () => Promise<ClientPreKeyBundle>;
|
|
38
|
+
readonly reserveOneTimePreKey?: () => {
|
|
39
|
+
readonly keyId: number;
|
|
40
|
+
readonly publicKey: Uint8Array;
|
|
41
|
+
} | null;
|
|
42
|
+
readonly pushStanza: (node: ReturnType<typeof buildMessage>) => Promise<void>;
|
|
43
|
+
readonly subscribeInboundMessages: (listener: (stanza: BinaryNode) => void) => () => void;
|
|
44
|
+
}
|
|
45
|
+
export declare class FakePeer {
|
|
46
|
+
readonly jid: string;
|
|
47
|
+
readonly displayName?: string;
|
|
48
|
+
readonly keyBundle: FakePeerKeyBundle;
|
|
49
|
+
readonly identity: FakePeerIdentity;
|
|
50
|
+
private readonly deps;
|
|
51
|
+
private readonly ratchet;
|
|
52
|
+
private readonly skipOneTimePreKey;
|
|
53
|
+
private readonly reservedOneTimePreKey;
|
|
54
|
+
private ratchetInitiated;
|
|
55
|
+
private nextMessageCounter;
|
|
56
|
+
private readonly senderKeysByGroup;
|
|
57
|
+
private readonly groupsBootstrapped;
|
|
58
|
+
private readonly groupRecvSession;
|
|
59
|
+
private constructor();
|
|
60
|
+
static create(options: CreateFakePeerOptions, deps: FakePeerDeps): Promise<FakePeer>;
|
|
61
|
+
sendMessage(message: proto.IMessage, options?: SendMessageOptions): Promise<void>;
|
|
62
|
+
sendConversation(text: string, options?: SendMessageOptions): Promise<void>;
|
|
63
|
+
sendMessageEdit(input: {
|
|
64
|
+
readonly targetMessageId: string;
|
|
65
|
+
readonly newText: string;
|
|
66
|
+
}, options?: SendMessageOptions): Promise<void>;
|
|
67
|
+
sendMessageRevoke(input: {
|
|
68
|
+
readonly targetMessageId: string;
|
|
69
|
+
}, options?: SendMessageOptions): Promise<void>;
|
|
70
|
+
sendReaction(input: {
|
|
71
|
+
readonly targetMessageId: string;
|
|
72
|
+
readonly emoji: string;
|
|
73
|
+
}, options?: SendMessageOptions): Promise<void>;
|
|
74
|
+
sendHistorySync(input?: BuildHistorySyncInput, options?: SendMessageOptions): Promise<void>;
|
|
75
|
+
sendHistorySyncExternal(input: BuildHistorySyncExternalInput, options?: SendMessageOptions): Promise<void>;
|
|
76
|
+
sendImageMessage(input: {
|
|
77
|
+
readonly directPath: string;
|
|
78
|
+
readonly mediaKey: Uint8Array;
|
|
79
|
+
readonly fileSha256: Uint8Array;
|
|
80
|
+
readonly fileEncSha256: Uint8Array;
|
|
81
|
+
readonly fileLength: number;
|
|
82
|
+
readonly mimetype?: string;
|
|
83
|
+
readonly caption?: string;
|
|
84
|
+
readonly width?: number;
|
|
85
|
+
readonly height?: number;
|
|
86
|
+
}, options?: SendMessageOptions): Promise<void>;
|
|
87
|
+
sendVideoMessage(input: {
|
|
88
|
+
readonly directPath: string;
|
|
89
|
+
readonly mediaKey: Uint8Array;
|
|
90
|
+
readonly fileSha256: Uint8Array;
|
|
91
|
+
readonly fileEncSha256: Uint8Array;
|
|
92
|
+
readonly fileLength: number;
|
|
93
|
+
readonly mimetype?: string;
|
|
94
|
+
readonly caption?: string;
|
|
95
|
+
readonly seconds?: number;
|
|
96
|
+
readonly width?: number;
|
|
97
|
+
readonly height?: number;
|
|
98
|
+
}, options?: SendMessageOptions): Promise<void>;
|
|
99
|
+
sendAudioMessage(input: {
|
|
100
|
+
readonly directPath: string;
|
|
101
|
+
readonly mediaKey: Uint8Array;
|
|
102
|
+
readonly fileSha256: Uint8Array;
|
|
103
|
+
readonly fileEncSha256: Uint8Array;
|
|
104
|
+
readonly fileLength: number;
|
|
105
|
+
readonly mimetype?: string;
|
|
106
|
+
readonly seconds?: number;
|
|
107
|
+
readonly ptt?: boolean;
|
|
108
|
+
}, options?: SendMessageOptions): Promise<void>;
|
|
109
|
+
sendDocumentMessage(input: {
|
|
110
|
+
readonly directPath: string;
|
|
111
|
+
readonly mediaKey: Uint8Array;
|
|
112
|
+
readonly fileSha256: Uint8Array;
|
|
113
|
+
readonly fileEncSha256: Uint8Array;
|
|
114
|
+
readonly fileLength: number;
|
|
115
|
+
readonly mimetype?: string;
|
|
116
|
+
readonly title?: string;
|
|
117
|
+
readonly fileName?: string;
|
|
118
|
+
readonly pageCount?: number;
|
|
119
|
+
}, options?: SendMessageOptions): Promise<void>;
|
|
120
|
+
sendStickerMessage(input: {
|
|
121
|
+
readonly directPath: string;
|
|
122
|
+
readonly mediaKey: Uint8Array;
|
|
123
|
+
readonly fileSha256: Uint8Array;
|
|
124
|
+
readonly fileEncSha256: Uint8Array;
|
|
125
|
+
readonly fileLength: number;
|
|
126
|
+
readonly mimetype?: string;
|
|
127
|
+
readonly width?: number;
|
|
128
|
+
readonly height?: number;
|
|
129
|
+
readonly isAnimated?: boolean;
|
|
130
|
+
}, options?: SendMessageOptions): Promise<void>;
|
|
131
|
+
sendAppStateSyncKeyShare(input: BuildAppStateSyncKeyShareInput, options?: SendMessageOptions): Promise<void>;
|
|
132
|
+
sendGroupConversation(groupJid: string, text: string, options?: SendMessageOptions): Promise<void>;
|
|
133
|
+
sendGroupMessage(groupJid: string, message: proto.IMessage, options?: SendMessageOptions): Promise<void>;
|
|
134
|
+
expectMessage(options?: ExpectMessageOptions): Promise<ReceivedMessage>;
|
|
135
|
+
expectGroupMessage(groupJid: string, options?: ExpectGroupMessageOptions): Promise<ReceivedMessage>;
|
|
136
|
+
private decryptPairwise;
|
|
137
|
+
decryptStanza(stanza: BinaryNode): Promise<ReceivedMessage | null>;
|
|
138
|
+
private bootstrapAndDecryptGroup;
|
|
139
|
+
private ensureRatchetInitiated;
|
|
140
|
+
private nextId;
|
|
141
|
+
}
|
|
142
|
+
export {};
|
|
143
|
+
//# sourceMappingURL=FakePeer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FakePeer.d.ts","sourceRoot":"","sources":["../../src/api/FakePeer.ts"],"names":[],"mappings":"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"}
|