@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.
Files changed (238) hide show
  1. package/README.md +176 -0
  2. package/dist/api/AppStateSyncManager.d.ts +27 -0
  3. package/dist/api/AppStateSyncManager.d.ts.map +1 -0
  4. package/dist/api/AppStateSyncManager.js +151 -0
  5. package/dist/api/AppStateSyncManager.js.map +1 -0
  6. package/dist/api/FakePairingDriver.d.ts +27 -0
  7. package/dist/api/FakePairingDriver.d.ts.map +1 -0
  8. package/dist/api/FakePairingDriver.js +36 -0
  9. package/dist/api/FakePairingDriver.js.map +1 -0
  10. package/dist/api/FakePeer.d.ts +143 -0
  11. package/dist/api/FakePeer.d.ts.map +1 -0
  12. package/dist/api/FakePeer.js +408 -0
  13. package/dist/api/FakePeer.js.map +1 -0
  14. package/dist/api/FakeWaServer.d.ts +167 -0
  15. package/dist/api/FakeWaServer.d.ts.map +1 -0
  16. package/dist/api/FakeWaServer.js +652 -0
  17. package/dist/api/FakeWaServer.js.map +1 -0
  18. package/dist/api/PreKeyDispenser.d.ts +23 -0
  19. package/dist/api/PreKeyDispenser.d.ts.map +1 -0
  20. package/dist/api/PreKeyDispenser.js +98 -0
  21. package/dist/api/PreKeyDispenser.js.map +1 -0
  22. package/dist/api/Scenario.d.ts +24 -0
  23. package/dist/api/Scenario.d.ts.map +1 -0
  24. package/dist/api/Scenario.js +38 -0
  25. package/dist/api/Scenario.js.map +1 -0
  26. package/dist/api/ServerRegistries.d.ts +110 -0
  27. package/dist/api/ServerRegistries.d.ts.map +1 -0
  28. package/dist/api/ServerRegistries.js +268 -0
  29. package/dist/api/ServerRegistries.js.map +1 -0
  30. package/dist/api/iq-handlers.d.ts +47 -0
  31. package/dist/api/iq-handlers.d.ts.map +1 -0
  32. package/dist/api/iq-handlers.js +498 -0
  33. package/dist/api/iq-handlers.js.map +1 -0
  34. package/dist/cli.d.ts +4 -0
  35. package/dist/cli.d.ts.map +1 -0
  36. package/dist/cli.js +249 -0
  37. package/dist/cli.js.map +1 -0
  38. package/dist/index.d.ts +51 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +74 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/infra/WaFakeConnection.d.ts +23 -0
  43. package/dist/infra/WaFakeConnection.d.ts.map +1 -0
  44. package/dist/infra/WaFakeConnection.js +54 -0
  45. package/dist/infra/WaFakeConnection.js.map +1 -0
  46. package/dist/infra/WaFakeConnectionPipeline.d.ts +51 -0
  47. package/dist/infra/WaFakeConnectionPipeline.d.ts.map +1 -0
  48. package/dist/infra/WaFakeConnectionPipeline.js +224 -0
  49. package/dist/infra/WaFakeConnectionPipeline.js.map +1 -0
  50. package/dist/infra/WaFakeFrameSocket.d.ts +29 -0
  51. package/dist/infra/WaFakeFrameSocket.d.ts.map +1 -0
  52. package/dist/infra/WaFakeFrameSocket.js +122 -0
  53. package/dist/infra/WaFakeFrameSocket.js.map +1 -0
  54. package/dist/infra/WaFakeMediaHttpsServer.d.ts +16 -0
  55. package/dist/infra/WaFakeMediaHttpsServer.d.ts.map +1 -0
  56. package/dist/infra/WaFakeMediaHttpsServer.js +131 -0
  57. package/dist/infra/WaFakeMediaHttpsServer.js.map +1 -0
  58. package/dist/infra/WaFakeNoiseHandshake.d.ts +23 -0
  59. package/dist/infra/WaFakeNoiseHandshake.d.ts.map +1 -0
  60. package/dist/infra/WaFakeNoiseHandshake.js +76 -0
  61. package/dist/infra/WaFakeNoiseHandshake.js.map +1 -0
  62. package/dist/infra/WaFakeTransport.d.ts +15 -0
  63. package/dist/infra/WaFakeTransport.d.ts.map +1 -0
  64. package/dist/infra/WaFakeTransport.js +34 -0
  65. package/dist/infra/WaFakeTransport.js.map +1 -0
  66. package/dist/infra/WaFakeWsServer.d.ts +29 -0
  67. package/dist/infra/WaFakeWsServer.d.ts.map +1 -0
  68. package/dist/infra/WaFakeWsServer.js +101 -0
  69. package/dist/infra/WaFakeWsServer.js.map +1 -0
  70. package/dist/protocol/auth/cert-chain.d.ts +18 -0
  71. package/dist/protocol/auth/cert-chain.d.ts.map +1 -0
  72. package/dist/protocol/auth/cert-chain.js +44 -0
  73. package/dist/protocol/auth/cert-chain.js.map +1 -0
  74. package/dist/protocol/auth/client-payload-validate.d.ts +21 -0
  75. package/dist/protocol/auth/client-payload-validate.d.ts.map +1 -0
  76. package/dist/protocol/auth/client-payload-validate.js +61 -0
  77. package/dist/protocol/auth/client-payload-validate.js.map +1 -0
  78. package/dist/protocol/auth/fake-primary-device.d.ts +19 -0
  79. package/dist/protocol/auth/fake-primary-device.d.ts.map +1 -0
  80. package/dist/protocol/auth/fake-primary-device.js +53 -0
  81. package/dist/protocol/auth/fake-primary-device.js.map +1 -0
  82. package/dist/protocol/auth/pair-device.d.ts +26 -0
  83. package/dist/protocol/auth/pair-device.d.ts.map +1 -0
  84. package/dist/protocol/auth/pair-device.js +104 -0
  85. package/dist/protocol/auth/pair-device.js.map +1 -0
  86. package/dist/protocol/auth/success-node.d.ts +15 -0
  87. package/dist/protocol/auth/success-node.d.ts.map +1 -0
  88. package/dist/protocol/auth/success-node.js +30 -0
  89. package/dist/protocol/auth/success-node.js.map +1 -0
  90. package/dist/protocol/iq/abprops.d.ts +14 -0
  91. package/dist/protocol/iq/abprops.d.ts.map +1 -0
  92. package/dist/protocol/iq/abprops.js +34 -0
  93. package/dist/protocol/iq/abprops.js.map +1 -0
  94. package/dist/protocol/iq/appstate-sync.d.ts +38 -0
  95. package/dist/protocol/iq/appstate-sync.d.ts.map +1 -0
  96. package/dist/protocol/iq/appstate-sync.js +154 -0
  97. package/dist/protocol/iq/appstate-sync.js.map +1 -0
  98. package/dist/protocol/iq/business.d.ts +13 -0
  99. package/dist/protocol/iq/business.d.ts.map +1 -0
  100. package/dist/protocol/iq/business.js +64 -0
  101. package/dist/protocol/iq/business.js.map +1 -0
  102. package/dist/protocol/iq/dirty-bits.d.ts +8 -0
  103. package/dist/protocol/iq/dirty-bits.d.ts.map +1 -0
  104. package/dist/protocol/iq/dirty-bits.js +23 -0
  105. package/dist/protocol/iq/dirty-bits.js.map +1 -0
  106. package/dist/protocol/iq/group-ops.d.ts +34 -0
  107. package/dist/protocol/iq/group-ops.d.ts.map +1 -0
  108. package/dist/protocol/iq/group-ops.js +164 -0
  109. package/dist/protocol/iq/group-ops.js.map +1 -0
  110. package/dist/protocol/iq/newsletter.d.ts +4 -0
  111. package/dist/protocol/iq/newsletter.d.ts.map +1 -0
  112. package/dist/protocol/iq/newsletter.js +18 -0
  113. package/dist/protocol/iq/newsletter.js.map +1 -0
  114. package/dist/protocol/iq/prekey-fetch.d.ts +18 -0
  115. package/dist/protocol/iq/prekey-fetch.d.ts.map +1 -0
  116. package/dist/protocol/iq/prekey-fetch.js +92 -0
  117. package/dist/protocol/iq/prekey-fetch.js.map +1 -0
  118. package/dist/protocol/iq/privacy-token.d.ts +9 -0
  119. package/dist/protocol/iq/privacy-token.d.ts.map +1 -0
  120. package/dist/protocol/iq/privacy-token.js +30 -0
  121. package/dist/protocol/iq/privacy-token.js.map +1 -0
  122. package/dist/protocol/iq/privacy.d.ts +22 -0
  123. package/dist/protocol/iq/privacy.d.ts.map +1 -0
  124. package/dist/protocol/iq/privacy.js +133 -0
  125. package/dist/protocol/iq/privacy.js.map +1 -0
  126. package/dist/protocol/iq/profile.d.ts +22 -0
  127. package/dist/protocol/iq/profile.d.ts.map +1 -0
  128. package/dist/protocol/iq/profile.js +80 -0
  129. package/dist/protocol/iq/profile.js.map +1 -0
  130. package/dist/protocol/iq/router.d.ts +39 -0
  131. package/dist/protocol/iq/router.d.ts.map +1 -0
  132. package/dist/protocol/iq/router.js +118 -0
  133. package/dist/protocol/iq/router.js.map +1 -0
  134. package/dist/protocol/iq/usync.d.ts +8 -0
  135. package/dist/protocol/iq/usync.d.ts.map +1 -0
  136. package/dist/protocol/iq/usync.js +68 -0
  137. package/dist/protocol/iq/usync.js.map +1 -0
  138. package/dist/protocol/push/app-state-key-share.d.ts +17 -0
  139. package/dist/protocol/push/app-state-key-share.d.ts.map +1 -0
  140. package/dist/protocol/push/app-state-key-share.js +30 -0
  141. package/dist/protocol/push/app-state-key-share.js.map +1 -0
  142. package/dist/protocol/push/call-failure.d.ts +16 -0
  143. package/dist/protocol/push/call-failure.d.ts.map +1 -0
  144. package/dist/protocol/push/call-failure.js +32 -0
  145. package/dist/protocol/push/call-failure.js.map +1 -0
  146. package/dist/protocol/push/chatstate.d.ts +15 -0
  147. package/dist/protocol/push/chatstate.d.ts.map +1 -0
  148. package/dist/protocol/push/chatstate.js +27 -0
  149. package/dist/protocol/push/chatstate.js.map +1 -0
  150. package/dist/protocol/push/error-stanza.d.ts +8 -0
  151. package/dist/protocol/push/error-stanza.d.ts.map +1 -0
  152. package/dist/protocol/push/error-stanza.js +17 -0
  153. package/dist/protocol/push/error-stanza.js.map +1 -0
  154. package/dist/protocol/push/history-sync.d.ts +46 -0
  155. package/dist/protocol/push/history-sync.d.ts.map +1 -0
  156. package/dist/protocol/push/history-sync.js +117 -0
  157. package/dist/protocol/push/history-sync.js.map +1 -0
  158. package/dist/protocol/push/message.d.ts +21 -0
  159. package/dist/protocol/push/message.d.ts.map +1 -0
  160. package/dist/protocol/push/message.js +42 -0
  161. package/dist/protocol/push/message.js.map +1 -0
  162. package/dist/protocol/push/notification.d.ts +21 -0
  163. package/dist/protocol/push/notification.d.ts.map +1 -0
  164. package/dist/protocol/push/notification.js +34 -0
  165. package/dist/protocol/push/notification.js.map +1 -0
  166. package/dist/protocol/push/presence.d.ts +11 -0
  167. package/dist/protocol/push/presence.d.ts.map +1 -0
  168. package/dist/protocol/push/presence.js +18 -0
  169. package/dist/protocol/push/presence.js.map +1 -0
  170. package/dist/protocol/push/receipt.d.ts +14 -0
  171. package/dist/protocol/push/receipt.d.ts.map +1 -0
  172. package/dist/protocol/push/receipt.js +25 -0
  173. package/dist/protocol/push/receipt.js.map +1 -0
  174. package/dist/protocol/signal/fake-app-state-crypto.d.ts +49 -0
  175. package/dist/protocol/signal/fake-app-state-crypto.d.ts.map +1 -0
  176. package/dist/protocol/signal/fake-app-state-crypto.js +202 -0
  177. package/dist/protocol/signal/fake-app-state-crypto.js.map +1 -0
  178. package/dist/protocol/signal/fake-peer-double-ratchet.d.ts +38 -0
  179. package/dist/protocol/signal/fake-peer-double-ratchet.d.ts.map +1 -0
  180. package/dist/protocol/signal/fake-peer-double-ratchet.js +408 -0
  181. package/dist/protocol/signal/fake-peer-double-ratchet.js.map +1 -0
  182. package/dist/protocol/signal/fake-peer-group-recv-session.d.ts +10 -0
  183. package/dist/protocol/signal/fake-peer-group-recv-session.d.ts.map +1 -0
  184. package/dist/protocol/signal/fake-peer-group-recv-session.js +129 -0
  185. package/dist/protocol/signal/fake-peer-group-recv-session.js.map +1 -0
  186. package/dist/protocol/signal/fake-peer-identity.d.ts +7 -0
  187. package/dist/protocol/signal/fake-peer-identity.d.ts.map +1 -0
  188. package/dist/protocol/signal/fake-peer-identity.js +12 -0
  189. package/dist/protocol/signal/fake-peer-identity.js.map +1 -0
  190. package/dist/protocol/signal/fake-peer-key-bundle.d.ts +24 -0
  191. package/dist/protocol/signal/fake-peer-key-bundle.d.ts.map +1 -0
  192. package/dist/protocol/signal/fake-peer-key-bundle.js +29 -0
  193. package/dist/protocol/signal/fake-peer-key-bundle.js.map +1 -0
  194. package/dist/protocol/signal/fake-peer-recv-session.d.ts +60 -0
  195. package/dist/protocol/signal/fake-peer-recv-session.d.ts.map +1 -0
  196. package/dist/protocol/signal/fake-peer-recv-session.js +284 -0
  197. package/dist/protocol/signal/fake-peer-recv-session.js.map +1 -0
  198. package/dist/protocol/signal/fake-peer-session.d.ts +87 -0
  199. package/dist/protocol/signal/fake-peer-session.d.ts.map +1 -0
  200. package/dist/protocol/signal/fake-peer-session.js +207 -0
  201. package/dist/protocol/signal/fake-peer-session.js.map +1 -0
  202. package/dist/protocol/signal/fake-sender-key.d.ts +15 -0
  203. package/dist/protocol/signal/fake-sender-key.d.ts.map +1 -0
  204. package/dist/protocol/signal/fake-sender-key.js +91 -0
  205. package/dist/protocol/signal/fake-sender-key.js.map +1 -0
  206. package/dist/protocol/signal/prekey-upload.d.ts +22 -0
  207. package/dist/protocol/signal/prekey-upload.d.ts.map +1 -0
  208. package/dist/protocol/signal/prekey-upload.js +113 -0
  209. package/dist/protocol/signal/prekey-upload.js.map +1 -0
  210. package/dist/protocol/stream/stream-error.d.ts +8 -0
  211. package/dist/protocol/stream/stream-error.d.ts.map +1 -0
  212. package/dist/protocol/stream/stream-error.js +64 -0
  213. package/dist/protocol/stream/stream-error.js.map +1 -0
  214. package/dist/state/fake-app-state-collection.d.ts +35 -0
  215. package/dist/state/fake-app-state-collection.d.ts.map +1 -0
  216. package/dist/state/fake-app-state-collection.js +139 -0
  217. package/dist/state/fake-app-state-collection.js.map +1 -0
  218. package/dist/state/fake-media-store.d.ts +35 -0
  219. package/dist/state/fake-media-store.d.ts.map +1 -0
  220. package/dist/state/fake-media-store.js +57 -0
  221. package/dist/state/fake-media-store.js.map +1 -0
  222. package/dist/transport/codec.d.ts +10 -0
  223. package/dist/transport/codec.d.ts.map +1 -0
  224. package/dist/transport/codec.js +17 -0
  225. package/dist/transport/codec.js.map +1 -0
  226. package/dist/transport/crypto.d.ts +11 -0
  227. package/dist/transport/crypto.d.ts.map +1 -0
  228. package/dist/transport/crypto.js +36 -0
  229. package/dist/transport/crypto.js.map +1 -0
  230. package/dist/transport/index.d.ts +4 -0
  231. package/dist/transport/index.d.ts.map +1 -0
  232. package/dist/transport/index.js +20 -0
  233. package/dist/transport/index.js.map +1 -0
  234. package/dist/transport/protos.d.ts +10 -0
  235. package/dist/transport/protos.d.ts.map +1 -0
  236. package/dist/transport/protos.js +13 -0
  237. package/dist/transport/protos.js.map +1 -0
  238. package/package.json +43 -0
@@ -0,0 +1,224 @@
1
+ "use strict";
2
+ /** Per-connection lifecycle pipeline (Noise handshake + stanza loop). */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.WaFakeConnectionPipeline = void 0;
5
+ const cert_chain_1 = require("../protocol/auth/cert-chain");
6
+ const client_payload_validate_1 = require("../protocol/auth/client-payload-validate");
7
+ const success_node_1 = require("../protocol/auth/success-node");
8
+ const codec_1 = require("../transport/codec");
9
+ const crypto_1 = require("../transport/crypto");
10
+ const protos_1 = require("../transport/protos");
11
+ const WaFakeFrameSocket_1 = require("./WaFakeFrameSocket");
12
+ const WaFakeNoiseHandshake_1 = require("./WaFakeNoiseHandshake");
13
+ const WaFakeTransport_1 = require("./WaFakeTransport");
14
+ const NOISE_XX_NAME = new TextEncoder().encode('Noise_XX_25519_AESGCM_SHA256\0\0\0\0');
15
+ const NOISE_IK_NAME = new TextEncoder().encode('Noise_IK_25519_AESGCM_SHA256\0\0\0\0');
16
+ const PROLOGUE = new Uint8Array([0x57, 0x41, 0x06, 0x03]);
17
+ class WaFakeConnectionPipeline {
18
+ constructor(config) {
19
+ this.events = {};
20
+ this.state = { kind: 'awaiting_prologue' };
21
+ this.chain = Promise.resolve();
22
+ this.config = config;
23
+ this.frameSocket = new WaFakeFrameSocket_1.WaFakeFrameSocket(config.connection);
24
+ this.frameSocket.setHandlers({
25
+ onPrologue: () => this.onPrologue(),
26
+ onFrame: (frame) => this.scheduleFrame(frame),
27
+ onClose: (info) => {
28
+ this.state = { kind: 'closed' };
29
+ this.events.onClose?.(info);
30
+ },
31
+ onError: (error) => this.events.onError?.(error)
32
+ });
33
+ }
34
+ setEvents(events) {
35
+ this.events = events;
36
+ }
37
+ isAuthenticated() {
38
+ return this.state.kind === 'authenticated';
39
+ }
40
+ async sendStanza(node) {
41
+ if (this.state.kind !== 'authenticated') {
42
+ throw new Error(`cannot send stanza while pipeline is in state "${this.state.kind}"`);
43
+ }
44
+ const stanza = (0, codec_1.encodeBinaryNodeStanza)(node);
45
+ // Keep outbound encrypted frames in FIFO order across concurrent callers.
46
+ const ciphertext = await this.state.transport.encryptFrame(stanza);
47
+ this.frameSocket.sendFrame(ciphertext);
48
+ }
49
+ onPrologue() {
50
+ if (this.state.kind !== 'awaiting_prologue') {
51
+ this.events.onError?.(new Error('received second prologue from client'));
52
+ return;
53
+ }
54
+ this.state = { kind: 'awaiting_client_hello' };
55
+ }
56
+ scheduleFrame(frame) {
57
+ this.chain = this.chain.then(() => this.handleFrame(frame));
58
+ }
59
+ async handleFrame(frame) {
60
+ try {
61
+ switch (this.state.kind) {
62
+ case 'awaiting_client_hello':
63
+ await this.handleClientHello(frame);
64
+ return;
65
+ case 'awaiting_client_finish':
66
+ await this.handleClientFinish(frame, this.state.handshake, this.state.serverEphemeralKeyPair);
67
+ return;
68
+ case 'authenticated':
69
+ await this.handleAuthenticatedFrame(frame, this.state.transport);
70
+ return;
71
+ default:
72
+ this.events.onError?.(new Error(`unexpected frame in state "${this.state.kind}"`));
73
+ }
74
+ }
75
+ catch (error) {
76
+ this.fail(error);
77
+ }
78
+ }
79
+ async handleClientHello(frame) {
80
+ const parsed = protos_1.proto.HandshakeMessage.decode(frame);
81
+ const clientHello = parsed.clientHello;
82
+ if (!clientHello?.ephemeral) {
83
+ throw new Error('ClientHello missing ephemeral');
84
+ }
85
+ // IK includes encrypted static+payload in ClientHello; XX does not.
86
+ if (clientHello.static && clientHello.payload) {
87
+ await this.handleIkClientHello(clientHello);
88
+ }
89
+ else {
90
+ await this.handleXxClientHello(clientHello.ephemeral);
91
+ }
92
+ }
93
+ async handleXxClientHello(clientEphemeralPub) {
94
+ const handshake = new WaFakeNoiseHandshake_1.WaFakeNoiseHandshake();
95
+ await handshake.start(NOISE_XX_NAME, PROLOGUE);
96
+ await handshake.authenticate(clientEphemeralPub);
97
+ const serverEphemeral = await crypto_1.X25519.generateKeyPair();
98
+ await handshake.authenticate(serverEphemeral.pubKey);
99
+ await handshake.mixIntoKey(await crypto_1.X25519.scalarMult(serverEphemeral.privKey, clientEphemeralPub));
100
+ const encryptedServerStatic = await handshake.encrypt(this.config.serverStaticKeyPair.pubKey);
101
+ await handshake.mixIntoKey(await crypto_1.X25519.scalarMult(this.config.serverStaticKeyPair.privKey, clientEphemeralPub));
102
+ const certChain = await (0, cert_chain_1.buildFakeCertChain)({
103
+ root: this.config.rootCa,
104
+ leafKey: this.config.serverStaticKeyPair.pubKey
105
+ });
106
+ const encryptedCertPayload = await handshake.encrypt(certChain.encoded);
107
+ const serverHello = protos_1.proto.HandshakeMessage.encode({
108
+ serverHello: {
109
+ ephemeral: serverEphemeral.pubKey,
110
+ static: encryptedServerStatic,
111
+ payload: encryptedCertPayload
112
+ }
113
+ }).finish();
114
+ this.frameSocket.sendFrame(serverHello);
115
+ this.state = {
116
+ kind: 'awaiting_client_finish',
117
+ handshake,
118
+ serverEphemeralKeyPair: serverEphemeral,
119
+ clientEphemeralPub
120
+ };
121
+ }
122
+ /** Server-side IK path used when the client already cached our static key. */
123
+ async handleIkClientHello(clientHello) {
124
+ if (!clientHello.ephemeral || !clientHello.static || !clientHello.payload) {
125
+ throw new Error('IK ClientHello missing ephemeral/static/payload');
126
+ }
127
+ const clientEphemeralPub = clientHello.ephemeral;
128
+ const encryptedClientStatic = clientHello.static;
129
+ const encryptedClientPayload = clientHello.payload;
130
+ const handshake = new WaFakeNoiseHandshake_1.WaFakeNoiseHandshake();
131
+ await handshake.start(NOISE_IK_NAME, PROLOGUE);
132
+ await handshake.authenticate(this.config.serverStaticKeyPair.pubKey);
133
+ await handshake.authenticate(clientEphemeralPub);
134
+ await handshake.mixIntoKey(await crypto_1.X25519.scalarMult(this.config.serverStaticKeyPair.privKey, clientEphemeralPub));
135
+ const clientStaticKey = await handshake.decrypt(encryptedClientStatic);
136
+ await handshake.mixIntoKey(await crypto_1.X25519.scalarMult(this.config.serverStaticKeyPair.privKey, clientStaticKey));
137
+ const clientPayloadBytes = await handshake.decrypt(encryptedClientPayload);
138
+ const clientPayload = (0, client_payload_validate_1.parseClientPayload)(clientPayloadBytes);
139
+ const serverEphemeral = await crypto_1.X25519.generateKeyPair();
140
+ await handshake.authenticate(serverEphemeral.pubKey);
141
+ await handshake.mixIntoKey(await crypto_1.X25519.scalarMult(serverEphemeral.privKey, clientEphemeralPub));
142
+ await handshake.mixIntoKey(await crypto_1.X25519.scalarMult(serverEphemeral.privKey, clientStaticKey));
143
+ const certChain = await (0, cert_chain_1.buildFakeCertChain)({
144
+ root: this.config.rootCa,
145
+ leafKey: this.config.serverStaticKeyPair.pubKey
146
+ });
147
+ const encryptedCertPayload = await handshake.encrypt(certChain.encoded);
148
+ const serverHello = protos_1.proto.HandshakeMessage.encode({
149
+ serverHello: {
150
+ ephemeral: serverEphemeral.pubKey,
151
+ payload: encryptedCertPayload
152
+ }
153
+ }).finish();
154
+ this.frameSocket.sendFrame(serverHello);
155
+ const keys = await handshake.finish();
156
+ const transport = new WaFakeTransport_1.WaFakeTransport({
157
+ recvKey: keys.recvKey,
158
+ sendKey: keys.sendKey
159
+ });
160
+ this.state = { kind: 'authenticated', transport };
161
+ await this.sendStanza((0, success_node_1.buildSuccessNode)(this.config.successNodeAttributes));
162
+ this.events.onAuthenticated?.({ clientPayload, clientStaticKey });
163
+ }
164
+ async handleClientFinish(frame, handshake, serverEphemeralKeyPair) {
165
+ const parsed = protos_1.proto.HandshakeMessage.decode(frame);
166
+ const clientFinish = parsed.clientFinish;
167
+ if (!clientFinish?.static || !clientFinish.payload) {
168
+ throw new Error('ClientFinish missing static/payload');
169
+ }
170
+ const clientStaticKey = await handshake.decrypt(clientFinish.static);
171
+ await handshake.mixIntoKey(await crypto_1.X25519.scalarMult(serverEphemeralKeyPair.privKey, clientStaticKey));
172
+ const clientPayloadBytes = await handshake.decrypt(clientFinish.payload);
173
+ const clientPayload = (0, client_payload_validate_1.parseClientPayload)(clientPayloadBytes);
174
+ const keys = await handshake.finish();
175
+ const transport = new WaFakeTransport_1.WaFakeTransport({
176
+ recvKey: keys.recvKey,
177
+ sendKey: keys.sendKey
178
+ });
179
+ this.state = { kind: 'authenticated', transport };
180
+ await this.sendStanza((0, success_node_1.buildSuccessNode)(this.config.successNodeAttributes));
181
+ this.events.onAuthenticated?.({ clientPayload, clientStaticKey });
182
+ }
183
+ async handleAuthenticatedFrame(frame, transport) {
184
+ const stanzaBytes = await transport.decryptFrame(frame);
185
+ const node = await (0, codec_1.decodeBinaryNodeStanza)(stanzaBytes);
186
+ this.events.onStanza?.(node);
187
+ if (node.tag === 'iq') {
188
+ const response = await this.config.iqRouter.route(node);
189
+ if (response !== null) {
190
+ await this.sendStanza(response);
191
+ }
192
+ else {
193
+ this.events.onUnhandledStanza?.(node);
194
+ }
195
+ return;
196
+ }
197
+ // Mirror the minimal ack shape that resolves the lib pending publish.
198
+ if (node.tag === 'message' && node.attrs.id) {
199
+ const messageType = node.attrs.type ?? 'text';
200
+ const from = node.attrs.to ?? 's.whatsapp.net';
201
+ const ackAttrs = {
202
+ id: node.attrs.id,
203
+ class: 'receipt',
204
+ type: messageType,
205
+ from
206
+ };
207
+ if (node.attrs.participant) {
208
+ ackAttrs.participant = node.attrs.participant;
209
+ }
210
+ await this.sendStanza({
211
+ tag: 'ack',
212
+ attrs: ackAttrs
213
+ });
214
+ }
215
+ }
216
+ fail(error) {
217
+ const err = error instanceof Error ? error : new Error(String(error));
218
+ this.events.onError?.(err);
219
+ this.state = { kind: 'closed' };
220
+ this.config.connection.close(1011, err.message.slice(0, 120));
221
+ }
222
+ }
223
+ exports.WaFakeConnectionPipeline = WaFakeConnectionPipeline;
224
+ //# sourceMappingURL=WaFakeConnectionPipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WaFakeConnectionPipeline.js","sourceRoot":"","sources":["../../src/infra/WaFakeConnectionPipeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /** WhatsApp frame codec (prologue + 3-byte length-prefixed frames). */
2
+ import type { WaFakeConnection } from './WaFakeConnection';
3
+ export interface WaFakeClientPrologue {
4
+ readonly protocolVersion: number;
5
+ readonly dictVersion: number;
6
+ readonly routingInfo: Uint8Array | null;
7
+ }
8
+ export interface WaFakeFrameSocketHandlers {
9
+ readonly onPrologue?: (prologue: WaFakeClientPrologue) => void;
10
+ readonly onFrame?: (frame: Uint8Array) => void;
11
+ readonly onClose?: (info: {
12
+ readonly code: number;
13
+ readonly reason: string;
14
+ }) => void;
15
+ readonly onError?: (error: Error) => void;
16
+ }
17
+ export declare class WaFakeFrameSocket {
18
+ private readonly connection;
19
+ private handlers;
20
+ private inboundBuffer;
21
+ private prologueParsed;
22
+ constructor(connection: WaFakeConnection);
23
+ setHandlers(handlers: WaFakeFrameSocketHandlers): void;
24
+ sendFrame(body: Uint8Array): void;
25
+ private handleInboundBytes;
26
+ private tryParsePrologue;
27
+ private drainFrames;
28
+ }
29
+ //# sourceMappingURL=WaFakeFrameSocket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WaFakeFrameSocket.d.ts","sourceRoot":"","sources":["../../src/infra/WaFakeFrameSocket.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAS1D,MAAM,WAAW,oBAAoB;IACjC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,WAAW,EAAE,UAAU,GAAG,IAAI,CAAA;CAC1C;AAED,MAAM,WAAW,yBAAyB;IACtC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,IAAI,CAAA;IAC9D,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IAC9C,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IACrF,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;CAC5C;AAED,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,cAAc,CAAQ;gBAEX,UAAU,EAAE,gBAAgB;IASxC,WAAW,CAAC,QAAQ,EAAE,yBAAyB,GAAG,IAAI;IAItD,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAYxC,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,gBAAgB;IAuCxB,OAAO,CAAC,WAAW;CAmBtB"}
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ /** WhatsApp frame codec (prologue + 3-byte length-prefixed frames). */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.WaFakeFrameSocket = void 0;
5
+ const PROLOGUE_W = 0x57;
6
+ const PROLOGUE_A = 0x41;
7
+ const ROUTING_MAGIC = 0xed;
8
+ const VERSION_HEADER_LENGTH = 4;
9
+ const FRAME_LENGTH_PREFIX_BYTES = 3;
10
+ const MAX_FRAME_LENGTH = 1 << 24;
11
+ class WaFakeFrameSocket {
12
+ constructor(connection) {
13
+ this.handlers = {};
14
+ this.inboundBuffer = new Uint8Array(0);
15
+ this.prologueParsed = false;
16
+ this.connection = connection;
17
+ this.connection.setHandlers({
18
+ onFrame: (bytes) => this.handleInboundBytes(bytes),
19
+ onClose: (info) => this.handlers.onClose?.(info),
20
+ onError: (error) => this.handlers.onError?.(error)
21
+ });
22
+ }
23
+ setHandlers(handlers) {
24
+ this.handlers = handlers;
25
+ }
26
+ sendFrame(body) {
27
+ if (body.byteLength >= MAX_FRAME_LENGTH) {
28
+ throw new Error(`frame too large: ${body.byteLength} bytes`);
29
+ }
30
+ const out = new Uint8Array(FRAME_LENGTH_PREFIX_BYTES + body.byteLength);
31
+ out[0] = (body.byteLength >> 16) & 0xff;
32
+ out[1] = (body.byteLength >> 8) & 0xff;
33
+ out[2] = body.byteLength & 0xff;
34
+ out.set(body, FRAME_LENGTH_PREFIX_BYTES);
35
+ this.connection.sendFrame(out);
36
+ }
37
+ handleInboundBytes(chunk) {
38
+ try {
39
+ this.inboundBuffer = concatBytes(this.inboundBuffer, chunk);
40
+ if (!this.prologueParsed) {
41
+ if (!this.tryParsePrologue()) {
42
+ return;
43
+ }
44
+ }
45
+ this.drainFrames();
46
+ }
47
+ catch (error) {
48
+ this.handlers.onError?.(error instanceof Error ? error : new Error(String(error)));
49
+ }
50
+ }
51
+ tryParsePrologue() {
52
+ const buffer = this.inboundBuffer;
53
+ let offset = 0;
54
+ let routingInfo = null;
55
+ if (buffer.byteLength === 0) {
56
+ return false;
57
+ }
58
+ if (buffer[0] === ROUTING_MAGIC) {
59
+ if (buffer.byteLength < 4) {
60
+ return false;
61
+ }
62
+ const routingLen = (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
63
+ if (buffer.byteLength < 4 + routingLen + VERSION_HEADER_LENGTH) {
64
+ return false;
65
+ }
66
+ routingInfo = buffer.slice(4, 4 + routingLen);
67
+ offset = 4 + routingLen;
68
+ }
69
+ else if (buffer.byteLength < VERSION_HEADER_LENGTH) {
70
+ return false;
71
+ }
72
+ const versionStart = offset;
73
+ const w = buffer[versionStart];
74
+ const a = buffer[versionStart + 1];
75
+ if (w !== PROLOGUE_W || a !== PROLOGUE_A) {
76
+ throw new Error(`invalid prologue magic: expected "WA", got ${hex(w)} ${hex(a)}`);
77
+ }
78
+ const protocolVersion = buffer[versionStart + 2];
79
+ const dictVersion = buffer[versionStart + 3];
80
+ offset = versionStart + VERSION_HEADER_LENGTH;
81
+ this.inboundBuffer = buffer.slice(offset);
82
+ this.prologueParsed = true;
83
+ this.handlers.onPrologue?.({ protocolVersion, dictVersion, routingInfo });
84
+ return true;
85
+ }
86
+ drainFrames() {
87
+ while (true) {
88
+ const buffer = this.inboundBuffer;
89
+ if (buffer.byteLength < FRAME_LENGTH_PREFIX_BYTES) {
90
+ return;
91
+ }
92
+ const length = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
93
+ if (length >= MAX_FRAME_LENGTH) {
94
+ throw new Error(`frame too large: ${length} bytes`);
95
+ }
96
+ const total = FRAME_LENGTH_PREFIX_BYTES + length;
97
+ if (buffer.byteLength < total) {
98
+ return;
99
+ }
100
+ const body = buffer.slice(FRAME_LENGTH_PREFIX_BYTES, total);
101
+ this.inboundBuffer = buffer.slice(total);
102
+ this.handlers.onFrame?.(body);
103
+ }
104
+ }
105
+ }
106
+ exports.WaFakeFrameSocket = WaFakeFrameSocket;
107
+ function concatBytes(a, b) {
108
+ if (a.byteLength === 0)
109
+ return b;
110
+ if (b.byteLength === 0)
111
+ return a;
112
+ const out = new Uint8Array(a.byteLength + b.byteLength);
113
+ out.set(a, 0);
114
+ out.set(b, a.byteLength);
115
+ return out;
116
+ }
117
+ function hex(byte) {
118
+ if (byte === undefined)
119
+ return 'undefined';
120
+ return `0x${byte.toString(16).padStart(2, '0')}`;
121
+ }
122
+ //# sourceMappingURL=WaFakeFrameSocket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WaFakeFrameSocket.js","sourceRoot":"","sources":["../../src/infra/WaFakeFrameSocket.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /** HTTPS listener used by fake media upload/download flows. */
2
+ import type { WaFakeHttpRequestHandler } from './WaFakeWsServer';
3
+ export interface WaFakeMediaHttpsServerListenInfo {
4
+ readonly host: string;
5
+ readonly port: number;
6
+ }
7
+ export declare class WaFakeMediaHttpsServer {
8
+ private server;
9
+ private listenInfo;
10
+ private requestHandler;
11
+ setRequestHandler(handler: WaFakeHttpRequestHandler | null): void;
12
+ listen(host?: string, port?: number): Promise<WaFakeMediaHttpsServerListenInfo>;
13
+ close(): Promise<void>;
14
+ get info(): WaFakeMediaHttpsServerListenInfo | null;
15
+ }
16
+ //# sourceMappingURL=WaFakeMediaHttpsServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WaFakeMediaHttpsServer.d.ts","sourceRoot":"","sources":["../../src/infra/WaFakeMediaHttpsServer.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAK/D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAA;AAqDhE,MAAM,WAAW,gCAAgC;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACxB;AAED,qBAAa,sBAAsB;IAC/B,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,UAAU,CAAgD;IAClE,OAAO,CAAC,cAAc,CAAwC;IAEvD,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,GAAG,IAAI;IAI3D,MAAM,CAAC,IAAI,SAAc,EAAE,IAAI,SAAI,GAAG,OAAO,CAAC,gCAAgC,CAAC;IAqD/E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAYnC,IAAW,IAAI,IAAI,gCAAgC,GAAG,IAAI,CAEzD;CACJ"}
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ /** HTTPS listener used by fake media upload/download flows. */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.WaFakeMediaHttpsServer = void 0;
5
+ const node_https_1 = require("node:https");
6
+ const FAKE_MEDIA_TLS_KEY_PEM = `-----BEGIN PRIVATE KEY-----
7
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC3xTRqB/wZbz/w
8
+ pQgcOfCfizS0MrtVR0ulBa1vK4OlU1FXJNC0dtTKLs/jMWNqwYWXxSoGEHHfhUIS
9
+ PgZ08nauCJs83ZFAQC1Es1sN1R32YokPmKOCTHHh8f5/uX3h5oUD/xr3gwOVs4c2
10
+ ISmk1OTmp77KolxZXHOnlnHweO6DK0CqfT+53RzKj5rz4d7inyMk5ctk+JjHZd8e
11
+ q46e4MH4ZWPM+ehwRwgWMQ2E1bFjVQsBMvtAkUxOEx+B2/Cys6jEUFo/ABkQxXt+
12
+ InqWnYKHbPOToKmpPxDjT54OpVZs4IRtbkTrgEMMz3/c5g4XamGUHLqkI0GBESK2
13
+ 16STZettAgMBAAECggEAAr6CDGOfMMzRkdyeWyKosPKMIGbY+wNiSSbsabim4BO3
14
+ LkLQgSK1d3fF3+KrDj6/DUJUti2/oZEKGoKwUn6T14BmV+7qvjX1WN8kqNsGYLXP
15
+ XFB0jinpkf6XhPKUn7olCGdwglgR28XknLBXsmG6eMK5ODgiZi0Zqng9WPCSP3Aa
16
+ 5q7iSeJF0FsbQ1OdQT3t98WhnSN9t0TzLyNUqXWDBDIrrtT3O7B7theS+3LRhodE
17
+ VFROogp4hfo6pBNweki08uFD250OP6iGpYsE0xY6NIfyebGS2iBmbDKQmMkWLdf0
18
+ mSlvYoksnDan4tJMiXAbb39wLdJEa+x98Qzxq0iJyQKBgQDeBQSgVd7j99W0bdzo
19
+ fnDgnjJS606UrWID/RyTEIMfq5Jf2sM2vTJ2/w4X1JoUxxQCJbFmoJs9RXn52XUa
20
+ 3/GaUbr3akUVjMb93JlbWTQVoKipMM6HGCee4rj69qdsmA8iJrnloGFpymLThcfm
21
+ xZB535vbG3DrYRM8MH/crDQH2QKBgQDT5YlXskOxx/iVxpko4uacIBqHnPGbCPnK
22
+ LXMaa5vrjGgWNK0ajj+0MFdpEl+HXC7ZDISmSRKExrMDaWkjoXzXhxz1BmHVdN3O
23
+ lOZY6gY+WeQUPn2sfqROBAV7B66LmRjbLdK9kwqrD3nhED6XWR+ZuXaH0dMQ2UMe
24
+ T9E1ixr3tQKBgQChrYvR6taWsosYioy9bh5rJCjHg33E/YIMH41odzTVok7EqP1R
25
+ 5nNSfqhXqEXQbazfZ22Jq9mAxBBwZvBFcuFxHKWHuQa4C715buTqxcoNGeLY2qb7
26
+ cBaiOL62W1pO1Wjn2MW1N5bYwD45hQmuvx5X8gOAirovXpDwWu0x2OFG+QKBgAxE
27
+ U4kiJs0Z+IgjMSauzA7pxN9o9Iu3H07XBrzW0fX28OeoMQVCiumRit3oVGNvsL6b
28
+ /OnrfQj2v9JIve90H9gSWFjO/8bttxGIiTVIhwgBCDUr0Pa1dimWDgMrVK18NXYq
29
+ 1vJmms2AXdvrptP4Mt4hYH1IZmGpUjtk/4WMAgmpAoGAKJXzDPY5ll9Ebjz28u3W
30
+ sPZdIz90rpRIBnyDC/AwtEzliU2PkuGpqe1ZJaP6cmPTxf/Bv8hfUMXknURpOShE
31
+ Uusyt3/4dGRMY+XXKuTPMZA8sbIEatA2z2e6oBoyj9avzEKAwDsReuPyyX6BubTx
32
+ rLSyj/PpCngrQw7YXsQc6Wc=
33
+ -----END PRIVATE KEY-----
34
+ `;
35
+ const FAKE_MEDIA_TLS_CERT_PEM = `-----BEGIN CERTIFICATE-----
36
+ MIIDGTCCAgGgAwIBAgIUCb8Qbq/uzK9W14G057lmny5p4kIwDQYJKoZIhvcNAQEL
37
+ BQAwGzEZMBcGA1UEAwwQZmFrZS1tZWRpYS5sb2NhbDAgFw0yNjA0MDgyMjAzMDRa
38
+ GA8yMTI2MDMxNTIyMDMwNFowGzEZMBcGA1UEAwwQZmFrZS1tZWRpYS5sb2NhbDCC
39
+ ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALfFNGoH/BlvP/ClCBw58J+L
40
+ NLQyu1VHS6UFrW8rg6VTUVck0LR21Mouz+MxY2rBhZfFKgYQcd+FQhI+BnTydq4I
41
+ mzzdkUBALUSzWw3VHfZiiQ+Yo4JMceHx/n+5feHmhQP/GveDA5WzhzYhKaTU5Oan
42
+ vsqiXFlcc6eWcfB47oMrQKp9P7ndHMqPmvPh3uKfIyTly2T4mMdl3x6rjp7gwfhl
43
+ Y8z56HBHCBYxDYTVsWNVCwEy+0CRTE4TH4Hb8LKzqMRQWj8AGRDFe34iepadgods
44
+ 85Ogqak/EONPng6lVmzghG1uROuAQwzPf9zmDhdqYZQcuqQjQYERIrbXpJNl620C
45
+ AwEAAaNTMFEwHQYDVR0OBBYEFG3DX82mLaatjTwwspHIj2pOD8CnMB8GA1UdIwQY
46
+ MBaAFG3DX82mLaatjTwwspHIj2pOD8CnMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
47
+ hvcNAQELBQADggEBAEqIu6mXgvSrGyQxRp6cJVg5OhBpwxH/V0IFe2H7xPBxreDS
48
+ e9yb/ESLRFxpfeWhLXOBEsOGbrF8HvZ0zNTHW+MtIkJB/hhYVzDJyhEpf9jWvpaM
49
+ H6CyzWIZgrXMmyeh0WkmVWoYyvlQrz9yJP63VfzCTCO6YBo02S+kKAyJiM9l8ZW5
50
+ 8vALhsyrGSMDnxQSixdc4L/Migam1LHxqwApzDvTdfXNiqjWEmfbw7sQKjd8EHad
51
+ KxNzgzzCRBSkeLe9YoXxLkKRvYeBM/xiv0AVp/ABedHj0xj3ybvvdjowui1uCBip
52
+ BoMF3OiuOeaTubj+tDzpZcauS4L+OyUPjsKqFoM=
53
+ -----END CERTIFICATE-----
54
+ `;
55
+ class WaFakeMediaHttpsServer {
56
+ constructor() {
57
+ this.server = null;
58
+ this.listenInfo = null;
59
+ this.requestHandler = null;
60
+ }
61
+ setRequestHandler(handler) {
62
+ this.requestHandler = handler;
63
+ }
64
+ async listen(host = '127.0.0.1', port = 0) {
65
+ if (this.server) {
66
+ throw new Error('fake media https server is already listening');
67
+ }
68
+ const server = (0, node_https_1.createServer)({
69
+ key: FAKE_MEDIA_TLS_KEY_PEM,
70
+ cert: FAKE_MEDIA_TLS_CERT_PEM
71
+ }, (req, res) => {
72
+ const handler = this.requestHandler;
73
+ if (!handler) {
74
+ res.statusCode = 404;
75
+ res.end();
76
+ return;
77
+ }
78
+ try {
79
+ const result = handler(req, res);
80
+ if (result instanceof Promise) {
81
+ result.catch((error) => {
82
+ if (!res.headersSent) {
83
+ res.statusCode = 500;
84
+ }
85
+ res.end(error instanceof Error ? error.message : String(error));
86
+ });
87
+ }
88
+ }
89
+ catch (error) {
90
+ if (!res.headersSent) {
91
+ res.statusCode = 500;
92
+ }
93
+ res.end(error instanceof Error ? error.message : String(error));
94
+ }
95
+ });
96
+ await new Promise((resolve, reject) => {
97
+ const onError = (error) => {
98
+ server.off('listening', onListening);
99
+ reject(error);
100
+ };
101
+ const onListening = () => {
102
+ server.off('error', onError);
103
+ resolve();
104
+ };
105
+ server.once('error', onError);
106
+ server.once('listening', onListening);
107
+ server.listen(port, host);
108
+ });
109
+ const address = server.address();
110
+ this.server = server;
111
+ this.listenInfo = { host: address.address, port: address.port };
112
+ return this.listenInfo;
113
+ }
114
+ async close() {
115
+ const server = this.server;
116
+ if (!server)
117
+ return;
118
+ await new Promise((resolve, reject) => {
119
+ server.close((error) => (error ? reject(error) : resolve()));
120
+ });
121
+ // Force any keep-alive sockets to close so the test process can exit.
122
+ server.closeAllConnections?.();
123
+ this.server = null;
124
+ this.listenInfo = null;
125
+ }
126
+ get info() {
127
+ return this.listenInfo;
128
+ }
129
+ }
130
+ exports.WaFakeMediaHttpsServer = WaFakeMediaHttpsServer;
131
+ //# sourceMappingURL=WaFakeMediaHttpsServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WaFakeMediaHttpsServer.js","sourceRoot":"","sources":["../../src/infra/WaFakeMediaHttpsServer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /** Responder-side Noise handshake primitives for fake server pipelines. */
2
+ import { type CryptoKey } from '../transport/crypto';
3
+ export interface WaFakeNoiseHandshakeFinishKeys {
4
+ readonly recvKey: CryptoKey;
5
+ readonly sendKey: CryptoKey;
6
+ readonly recvKeyBytes: Uint8Array;
7
+ readonly sendKeyBytes: Uint8Array;
8
+ }
9
+ export declare class WaFakeNoiseHandshake {
10
+ private hash;
11
+ private chainingKey;
12
+ private cipherKey;
13
+ private nonceCounter;
14
+ start(name: Uint8Array, prologue: Uint8Array): Promise<void>;
15
+ authenticate(data: Uint8Array): Promise<void>;
16
+ mixIntoKey(input: Uint8Array): Promise<void>;
17
+ encrypt(plaintext: Uint8Array): Promise<Uint8Array>;
18
+ decrypt(ciphertext: Uint8Array): Promise<Uint8Array>;
19
+ /** Derives transport keys (`first -> recv`, `second -> send` for responder role). */
20
+ finish(): Promise<WaFakeNoiseHandshakeFinishKeys>;
21
+ private buildNonceIv;
22
+ }
23
+ //# sourceMappingURL=WaFakeNoiseHandshake.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WaFakeNoiseHandshake.d.ts","sourceRoot":"","sources":["../../src/infra/WaFakeNoiseHandshake.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAE3E,OAAO,EAGH,KAAK,SAAS,EAIjB,MAAM,qBAAqB,CAAA;AAI5B,MAAM,WAAW,8BAA8B;IAC3C,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAA;IAC3B,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAA;IACjC,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAA;CACpC;AAED,qBAAa,oBAAoB;IAC7B,OAAO,CAAC,IAAI,CAAoB;IAChC,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,YAAY,CAAI;IAEX,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAS5D,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAO7C,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAO5C,OAAO,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAWnD,OAAO,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAWjE,qFAAqF;IACxE,MAAM,IAAI,OAAO,CAAC,8BAA8B,CAAC;IAc9D,OAAO,CAAC,YAAY;CAMvB"}