@zapo-js/fake-server 1.0.0 → 1.1.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 +93 -5
- package/dist/api/FakePeer.js +7 -1
- package/dist/api/FakeServerSession.d.ts +67 -0
- package/dist/api/FakeServerSession.js +293 -0
- package/dist/api/FakeWaServer.d.ts +74 -38
- package/dist/api/FakeWaServer.js +125 -276
- package/dist/api/iq-handlers.d.ts +1 -0
- package/dist/api/iq-handlers.js +23 -0
- package/dist/bin.js +69 -21
- package/dist/esm/api/FakePeer.js +7 -1
- package/dist/esm/api/FakeServerSession.js +287 -0
- package/dist/esm/api/FakeWaServer.js +123 -275
- package/dist/esm/api/iq-handlers.js +23 -0
- package/dist/esm/bin.js +67 -19
- package/dist/esm/index.js +1 -1
- package/dist/esm/infra/WaFakeConnectionPipeline.js +21 -9
- package/dist/esm/protocol/auth/cert-chain.js +13 -2
- package/dist/esm/protocol/iq/router.js +8 -2
- package/dist/esm/transport/util.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -1
- package/dist/infra/WaFakeConnectionPipeline.d.ts +10 -2
- package/dist/infra/WaFakeConnectionPipeline.js +21 -9
- package/dist/protocol/auth/cert-chain.d.ts +4 -0
- package/dist/protocol/auth/cert-chain.js +13 -2
- package/dist/protocol/iq/router.d.ts +7 -1
- package/dist/protocol/iq/router.js +8 -2
- package/dist/transport/util.d.ts +1 -1
- package/dist/transport/util.js +2 -1
- package/package.json +6 -1
|
@@ -1,47 +1,65 @@
|
|
|
1
1
|
import { Agent as HttpsAgent } from 'node:https';
|
|
2
2
|
import { type WaFakeAuthenticatedInfo, WaFakeConnectionPipeline } from '../infra/WaFakeConnectionPipeline';
|
|
3
|
+
import type { ParsedClientPayload } from '../protocol/auth/client-payload-validate';
|
|
4
|
+
import type { BuildSuccessNodeInput } from '../protocol/auth/success-node';
|
|
3
5
|
import type { BuildAbPropsResultInput } from '../protocol/iq/abprops';
|
|
4
6
|
import { type BuildServerSyncNotificationInput, type FakeAppStateCollectionPayload } from '../protocol/iq/appstate-sync';
|
|
5
7
|
import type { FakeBusinessProfile } from '../protocol/iq/business';
|
|
6
8
|
import type { FakePrivacyCategoryName, FakePrivacySettingsState } from '../protocol/iq/privacy';
|
|
7
9
|
import type { FakePrivacyTokenIssue } from '../protocol/iq/privacy-token';
|
|
8
10
|
import type { FakeProfilePictureResult } from '../protocol/iq/profile';
|
|
9
|
-
import {
|
|
11
|
+
import type { WaFakeIqMatcher, WaFakeIqResponder } from '../protocol/iq/router';
|
|
10
12
|
import type { ClientPreKeyBundle } from '../protocol/signal/prekey-upload';
|
|
11
13
|
import { type PublishedMediaBlob, type PublishMediaInput } from '../state/fake-media-store';
|
|
12
14
|
import { type BinaryNode } from '../transport/codec';
|
|
13
|
-
import { AppStateSyncManager, type CapturedAppStateMutation } from './AppStateSyncManager';
|
|
15
|
+
import { type AppStateSyncManager, type CapturedAppStateMutation } from './AppStateSyncManager';
|
|
14
16
|
import { type FakePairingDriverOptions } from './FakePairingDriver';
|
|
15
17
|
import { type CreateFakePeerOptions, FakePeer } from './FakePeer';
|
|
16
|
-
import {
|
|
18
|
+
import { type ExpectIqOptions, type ExpectStanzaOptions, FakeServerSession, type StanzaMatcher } from './FakeServerSession';
|
|
19
|
+
import type { PreKeyDispenser } from './PreKeyDispenser';
|
|
17
20
|
import { type AuthenticatedPipelineListener, Scenario } from './Scenario';
|
|
18
|
-
import {
|
|
21
|
+
import type { CapturedBlocklistChange, CapturedDirtyBitsClear, CapturedGroupOp, CapturedPrivacySet, CapturedProfilePictureSet, CapturedStatusSet, FakeGroupMetadata, ServerRegistries } from './ServerRegistries';
|
|
19
22
|
export type { FakeGroupMetadata, CapturedGroupOp, CapturedPrivacySet, CapturedBlocklistChange, CapturedProfilePictureSet, CapturedStatusSet, CapturedDirtyBitsClear } from './ServerRegistries';
|
|
20
23
|
export type { CapturedAppStateMutation } from './AppStateSyncManager';
|
|
21
24
|
export interface FakeWaServerOptions {
|
|
22
25
|
readonly host?: string;
|
|
23
26
|
readonly port?: number;
|
|
24
27
|
readonly path?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Attributes stamped on the post-handshake `<success/>` node of every
|
|
30
|
+
* authenticated connection (lid, display name, props versions, ...).
|
|
31
|
+
*/
|
|
32
|
+
readonly successNodeAttributes?: BuildSuccessNodeInput;
|
|
33
|
+
/**
|
|
34
|
+
* Register the built-in IQ auto-handlers that answer everything the lib
|
|
35
|
+
* emits during normal operation. Default `true`; pass `false` to start
|
|
36
|
+
* with an empty router and wire every response via `registerIqHandler`.
|
|
37
|
+
*/
|
|
38
|
+
readonly defaultIqHandlers?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Assigns each authenticated connection to an isolated session, keyed by
|
|
41
|
+
* the returned id. Two connections that resolve to different ids share no
|
|
42
|
+
* peers, groups, prekeys, app-state, or captured stanzas. When omitted,
|
|
43
|
+
* every connection uses one shared default session (single-client mode).
|
|
44
|
+
*
|
|
45
|
+
* The resolver runs once per connection, right after authentication, so
|
|
46
|
+
* `info.clientPayload` is available for keying by login identity, e.g.
|
|
47
|
+
* `sessionKey: ({ clientPayload }) => clientPayload.kind === 'login' ?
|
|
48
|
+
* clientPayload.username : 'pending'`.
|
|
49
|
+
*/
|
|
50
|
+
readonly sessionKey?: (info: FakeSessionKeyInfo) => string;
|
|
51
|
+
}
|
|
52
|
+
export interface FakeSessionKeyInfo {
|
|
53
|
+
readonly clientPayload: ParsedClientPayload;
|
|
54
|
+
readonly pipeline: WaFakeConnectionPipeline;
|
|
25
55
|
}
|
|
26
56
|
export interface FakeWaServerNoiseRootCa {
|
|
27
57
|
readonly publicKey: Uint8Array;
|
|
28
58
|
readonly serial: number;
|
|
29
59
|
}
|
|
30
60
|
export type FakeWaServerPipelineListener = (pipeline: WaFakeConnectionPipeline) => void;
|
|
31
|
-
export
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
export interface ExpectStanzaOptions {
|
|
35
|
-
readonly timeoutMs?: number;
|
|
36
|
-
}
|
|
37
|
-
export interface StanzaMatcher {
|
|
38
|
-
readonly tag?: string;
|
|
39
|
-
readonly type?: string;
|
|
40
|
-
readonly xmlns?: string;
|
|
41
|
-
readonly from?: string;
|
|
42
|
-
readonly to?: string;
|
|
43
|
-
readonly childTag?: string;
|
|
44
|
-
}
|
|
61
|
+
export { FakeServerSession } from './FakeServerSession';
|
|
62
|
+
export type { ExpectIqOptions, ExpectStanzaOptions, StanzaMatcher } from './FakeServerSession';
|
|
45
63
|
export interface CapturedMediaUpload {
|
|
46
64
|
readonly path: string;
|
|
47
65
|
readonly mediaType: string;
|
|
@@ -51,22 +69,18 @@ export interface CapturedMediaUpload {
|
|
|
51
69
|
readonly receivedAtMs: number;
|
|
52
70
|
}
|
|
53
71
|
export declare class FakeWaServer {
|
|
54
|
-
readonly registries: ServerRegistries;
|
|
55
|
-
readonly preKeyDispenser: PreKeyDispenser;
|
|
56
|
-
readonly appStateSync: AppStateSyncManager;
|
|
57
72
|
private readonly wsServer;
|
|
58
73
|
private readonly pipelines;
|
|
59
|
-
private readonly
|
|
60
|
-
private readonly
|
|
61
|
-
private readonly pendingIqExpectations;
|
|
62
|
-
private readonly pendingStanzaExpectations;
|
|
74
|
+
private readonly defaultSession;
|
|
75
|
+
private readonly pipelineSessions;
|
|
63
76
|
private readonly authenticatedListeners;
|
|
64
|
-
private readonly
|
|
65
|
-
private readonly
|
|
77
|
+
private readonly sessions;
|
|
78
|
+
private readonly globalIqHandlers;
|
|
79
|
+
private readonly options;
|
|
66
80
|
private rootCa;
|
|
67
81
|
private serverStaticKeyPair;
|
|
68
82
|
private listenInfo;
|
|
69
|
-
private
|
|
83
|
+
private readonly pipelineListeners;
|
|
70
84
|
private rejectMode;
|
|
71
85
|
private readonly mediaStore;
|
|
72
86
|
private readonly mediaHttpsServer;
|
|
@@ -74,7 +88,20 @@ export declare class FakeWaServer {
|
|
|
74
88
|
private nextUploadCounter;
|
|
75
89
|
private cachedMediaProxyAgent;
|
|
76
90
|
constructor(options?: FakeWaServerOptions);
|
|
77
|
-
|
|
91
|
+
/** State of the single default session (the only session for one client). */
|
|
92
|
+
get registries(): ServerRegistries;
|
|
93
|
+
get preKeyDispenser(): PreKeyDispenser;
|
|
94
|
+
get appStateSync(): AppStateSyncManager;
|
|
95
|
+
/**
|
|
96
|
+
* Returns the isolated session for `id`, creating it on first use. Every
|
|
97
|
+
* session gets its own registries, prekey dispenser, app-state, IQ router,
|
|
98
|
+
* and stanza capture. Use with the `sessionKey` option to run several
|
|
99
|
+
* `WaClient`s against one server without them sharing any state.
|
|
100
|
+
*/
|
|
101
|
+
session(id: string): FakeServerSession;
|
|
102
|
+
/** The session a connection is bound to (default before authentication). */
|
|
103
|
+
sessionFor(pipeline: WaFakeConnectionPipeline): FakeServerSession;
|
|
104
|
+
private createSession;
|
|
78
105
|
registerIqHandler(matcher: WaFakeIqMatcher, respond: WaFakeIqResponder, label?: string): () => void;
|
|
79
106
|
routeIqForTest(iq: BinaryNode): Promise<BinaryNode | null>;
|
|
80
107
|
onOutboundGroupOp(listener: (op: CapturedGroupOp) => void): () => void;
|
|
@@ -124,13 +151,12 @@ export declare class FakeWaServer {
|
|
|
124
151
|
expectIq(matcher: WaFakeIqMatcher, options?: ExpectIqOptions): Promise<BinaryNode>;
|
|
125
152
|
capturedStanzaSnapshot(): readonly BinaryNode[];
|
|
126
153
|
/**
|
|
127
|
-
* Subscribes to every stanza captured from the client side (the lib)
|
|
128
|
-
* The listener is called synchronously for each new
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
* `expectStanza(...)` per iteration.
|
|
154
|
+
* Subscribes to every stanza captured from the client side (the lib) of
|
|
155
|
+
* the default session. The listener is called synchronously for each new
|
|
156
|
+
* stanza as it arrives. Returns an unsubscribe function. Useful for
|
|
157
|
+
* benches that need to count or react to a stream of receipts/messages
|
|
158
|
+
* without paying the O(N²) cost of polling `capturedStanzaSnapshot()` or
|
|
159
|
+
* queuing one `expectStanza(...)` per iteration.
|
|
134
160
|
*/
|
|
135
161
|
onCapturedStanza(listener: (node: BinaryNode) => void): () => void;
|
|
136
162
|
expectStanza(matcher: StanzaMatcher, options?: ExpectStanzaOptions): Promise<BinaryNode>;
|
|
@@ -163,11 +189,21 @@ export declare class FakeWaServer {
|
|
|
163
189
|
get host(): string;
|
|
164
190
|
get port(): number;
|
|
165
191
|
get noiseRootCa(): FakeWaServerNoiseRootCa;
|
|
166
|
-
|
|
192
|
+
/**
|
|
193
|
+
* Subscribes to every new connection pipeline (pre-auth). Listeners
|
|
194
|
+
* fan out; returns an unsubscribe function.
|
|
195
|
+
*/
|
|
196
|
+
onPipeline(listener: FakeWaServerPipelineListener): () => void;
|
|
167
197
|
listen(): Promise<void>;
|
|
168
198
|
stop(): Promise<void>;
|
|
169
199
|
private handleConnection;
|
|
170
|
-
|
|
200
|
+
/**
|
|
201
|
+
* Rebinds a connection to its keyed session once authenticated. Runs
|
|
202
|
+
* before user `onAuthenticated` listeners and before any client stanza, so
|
|
203
|
+
* captures and IQ routing land in the right session from the first frame.
|
|
204
|
+
* No-op without a `sessionKey` resolver (single default session).
|
|
205
|
+
*/
|
|
206
|
+
private bindPipelineSession;
|
|
171
207
|
private buildMediaRequestHandler;
|
|
172
208
|
private handleMediaUpload;
|
|
173
209
|
private requireListening;
|