@zapo-js/fake-server 0.3.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 +96 -8
- package/dist/api/AppStateSyncManager.d.ts +0 -1
- package/dist/api/AppStateSyncManager.js +0 -1
- package/dist/api/FakePairingDriver.d.ts +0 -1
- package/dist/api/FakePairingDriver.js +0 -1
- package/dist/api/FakePeer.d.ts +77 -4
- package/dist/api/FakePeer.js +208 -2
- package/dist/api/FakeServerSession.d.ts +67 -0
- package/dist/api/FakeServerSession.js +293 -0
- package/dist/api/FakeWaServer.d.ts +77 -31
- package/dist/api/FakeWaServer.js +140 -259
- package/dist/api/PreKeyDispenser.d.ts +0 -1
- package/dist/api/PreKeyDispenser.js +0 -1
- package/dist/api/Scenario.d.ts +0 -1
- package/dist/api/Scenario.js +0 -1
- package/dist/api/ServerRegistries.d.ts +0 -1
- package/dist/api/ServerRegistries.js +0 -1
- package/dist/api/iq-handlers.d.ts +1 -1
- package/dist/api/iq-handlers.js +23 -1
- package/dist/{cli.d.ts → bin.d.ts} +0 -1
- package/dist/bin.js +296 -0
- package/dist/esm/api/AppStateSyncManager.js +146 -0
- package/dist/esm/api/FakePairingDriver.js +31 -0
- package/dist/esm/api/FakePeer.js +610 -0
- package/dist/esm/api/FakeServerSession.js +287 -0
- package/dist/esm/api/FakeWaServer.js +528 -0
- package/dist/esm/api/PreKeyDispenser.js +93 -0
- package/dist/esm/api/Scenario.js +32 -0
- package/dist/esm/api/ServerRegistries.js +261 -0
- package/dist/esm/api/iq-handlers.js +515 -0
- package/dist/{cli.js → esm/bin.js} +70 -25
- package/dist/esm/index.js +26 -0
- package/dist/esm/infra/WaFakeConnection.js +49 -0
- package/dist/esm/infra/WaFakeConnectionPipeline.js +235 -0
- package/dist/esm/infra/WaFakeFrameSocket.js +117 -0
- package/dist/esm/infra/WaFakeMediaHttpsServer.js +126 -0
- package/dist/esm/infra/WaFakeNoiseHandshake.js +67 -0
- package/dist/esm/infra/WaFakeTransport.js +31 -0
- package/dist/esm/infra/WaFakeWsServer.js +96 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/protocol/auth/cert-chain.js +50 -0
- package/dist/esm/protocol/auth/client-payload-validate.js +55 -0
- package/dist/esm/protocol/auth/fake-primary-device.js +47 -0
- package/dist/esm/protocol/auth/pair-device.js +87 -0
- package/dist/esm/protocol/auth/success-node.js +26 -0
- package/dist/esm/protocol/iq/abprops.js +30 -0
- package/dist/esm/protocol/iq/appstate-sync.js +146 -0
- package/dist/esm/protocol/iq/business.js +59 -0
- package/dist/esm/protocol/iq/dirty-bits.js +19 -0
- package/dist/esm/protocol/iq/group-ops.js +154 -0
- package/dist/esm/protocol/iq/newsletter.js +14 -0
- package/dist/esm/protocol/iq/prekey-fetch.js +88 -0
- package/dist/esm/protocol/iq/privacy-token.js +26 -0
- package/dist/esm/protocol/iq/privacy.js +123 -0
- package/dist/esm/protocol/iq/profile.js +72 -0
- package/dist/esm/protocol/iq/router.js +117 -0
- package/dist/esm/protocol/iq/usync.js +64 -0
- package/dist/esm/protocol/push/app-state-key-share.js +26 -0
- package/dist/esm/protocol/push/call-failure.js +27 -0
- package/dist/esm/protocol/push/chatstate.js +23 -0
- package/dist/esm/protocol/push/error-stanza.js +13 -0
- package/dist/esm/protocol/push/history-sync.js +111 -0
- package/dist/esm/protocol/push/message.js +38 -0
- package/dist/esm/protocol/push/notification.js +29 -0
- package/dist/esm/protocol/push/presence.js +14 -0
- package/dist/esm/protocol/push/receipt.js +21 -0
- package/dist/esm/protocol/signal/fake-app-state-crypto.js +196 -0
- package/dist/esm/protocol/signal/fake-peer-double-ratchet.js +398 -0
- package/dist/esm/protocol/signal/fake-peer-group-recv-session.js +120 -0
- package/dist/esm/protocol/signal/fake-peer-identity.js +8 -0
- package/dist/esm/protocol/signal/fake-peer-key-bundle.js +25 -0
- package/dist/esm/protocol/signal/fake-sender-key.js +83 -0
- package/dist/esm/protocol/signal/prekey-upload.js +107 -0
- package/dist/esm/protocol/stream/stream-error.js +56 -0
- package/dist/esm/state/fake-app-state-collection.js +134 -0
- package/dist/esm/state/fake-media-store.js +53 -0
- package/dist/esm/transport/codec.js +8 -0
- package/dist/esm/transport/crypto.js +8 -0
- package/dist/esm/transport/protos.js +7 -0
- package/dist/esm/transport/util.js +8 -0
- package/dist/index.d.ts +2 -3
- package/dist/index.js +2 -2
- package/dist/infra/WaFakeConnection.d.ts +0 -1
- package/dist/infra/WaFakeConnection.js +0 -1
- package/dist/infra/WaFakeConnectionPipeline.d.ts +10 -3
- package/dist/infra/WaFakeConnectionPipeline.js +47 -32
- package/dist/infra/WaFakeFrameSocket.d.ts +0 -1
- package/dist/infra/WaFakeFrameSocket.js +0 -1
- package/dist/infra/WaFakeMediaHttpsServer.d.ts +0 -1
- package/dist/infra/WaFakeMediaHttpsServer.js +0 -1
- package/dist/infra/WaFakeNoiseHandshake.d.ts +8 -10
- package/dist/infra/WaFakeNoiseHandshake.js +19 -24
- package/dist/infra/WaFakeTransport.d.ts +2 -4
- package/dist/infra/WaFakeTransport.js +2 -1
- package/dist/infra/WaFakeWsServer.d.ts +0 -1
- package/dist/infra/WaFakeWsServer.js +0 -1
- package/dist/protocol/auth/cert-chain.d.ts +4 -1
- package/dist/protocol/auth/cert-chain.js +13 -3
- package/dist/protocol/auth/client-payload-validate.d.ts +0 -1
- package/dist/protocol/auth/client-payload-validate.js +0 -1
- package/dist/protocol/auth/fake-primary-device.d.ts +0 -1
- package/dist/protocol/auth/fake-primary-device.js +1 -3
- package/dist/protocol/auth/pair-device.d.ts +0 -1
- package/dist/protocol/auth/pair-device.js +4 -16
- package/dist/protocol/auth/success-node.d.ts +0 -1
- package/dist/protocol/auth/success-node.js +0 -1
- package/dist/protocol/iq/abprops.d.ts +0 -1
- package/dist/protocol/iq/abprops.js +0 -1
- package/dist/protocol/iq/appstate-sync.d.ts +0 -1
- package/dist/protocol/iq/appstate-sync.js +0 -1
- package/dist/protocol/iq/business.d.ts +0 -1
- package/dist/protocol/iq/business.js +0 -1
- package/dist/protocol/iq/dirty-bits.d.ts +0 -1
- package/dist/protocol/iq/dirty-bits.js +0 -1
- package/dist/protocol/iq/group-ops.d.ts +0 -1
- package/dist/protocol/iq/group-ops.js +0 -1
- package/dist/protocol/iq/newsletter.d.ts +0 -1
- package/dist/protocol/iq/newsletter.js +0 -1
- package/dist/protocol/iq/prekey-fetch.d.ts +0 -1
- package/dist/protocol/iq/prekey-fetch.js +0 -1
- package/dist/protocol/iq/privacy-token.d.ts +0 -1
- package/dist/protocol/iq/privacy-token.js +0 -1
- package/dist/protocol/iq/privacy.d.ts +0 -1
- package/dist/protocol/iq/privacy.js +15 -16
- package/dist/protocol/iq/profile.d.ts +0 -1
- package/dist/protocol/iq/profile.js +0 -1
- package/dist/protocol/iq/router.d.ts +7 -2
- package/dist/protocol/iq/router.js +8 -3
- package/dist/protocol/iq/usync.d.ts +0 -1
- package/dist/protocol/iq/usync.js +0 -1
- package/dist/protocol/push/app-state-key-share.d.ts +0 -1
- package/dist/protocol/push/app-state-key-share.js +0 -1
- package/dist/protocol/push/call-failure.d.ts +0 -1
- package/dist/protocol/push/call-failure.js +0 -1
- package/dist/protocol/push/chatstate.d.ts +0 -1
- package/dist/protocol/push/chatstate.js +0 -1
- package/dist/protocol/push/error-stanza.d.ts +0 -1
- package/dist/protocol/push/error-stanza.js +0 -1
- package/dist/protocol/push/history-sync.d.ts +0 -1
- package/dist/protocol/push/history-sync.js +0 -1
- package/dist/protocol/push/message.d.ts +0 -1
- package/dist/protocol/push/message.js +0 -1
- package/dist/protocol/push/notification.d.ts +0 -1
- package/dist/protocol/push/notification.js +0 -1
- package/dist/protocol/push/presence.d.ts +0 -1
- package/dist/protocol/push/presence.js +0 -1
- package/dist/protocol/push/receipt.d.ts +0 -1
- package/dist/protocol/push/receipt.js +0 -1
- package/dist/protocol/signal/fake-app-state-crypto.d.ts +7 -9
- package/dist/protocol/signal/fake-app-state-crypto.js +31 -33
- package/dist/protocol/signal/fake-peer-double-ratchet.d.ts +0 -1
- package/dist/protocol/signal/fake-peer-double-ratchet.js +23 -28
- package/dist/protocol/signal/fake-peer-group-recv-session.d.ts +0 -1
- package/dist/protocol/signal/fake-peer-group-recv-session.js +6 -10
- package/dist/protocol/signal/fake-peer-identity.d.ts +0 -1
- package/dist/protocol/signal/fake-peer-identity.js +0 -1
- package/dist/protocol/signal/fake-peer-key-bundle.d.ts +0 -1
- package/dist/protocol/signal/fake-peer-key-bundle.js +0 -1
- package/dist/protocol/signal/fake-sender-key.d.ts +0 -1
- package/dist/protocol/signal/fake-sender-key.js +5 -9
- package/dist/protocol/signal/prekey-upload.d.ts +0 -1
- package/dist/protocol/signal/prekey-upload.js +0 -1
- package/dist/protocol/stream/stream-error.d.ts +0 -1
- package/dist/protocol/stream/stream-error.js +0 -1
- package/dist/state/fake-app-state-collection.d.ts +0 -1
- package/dist/state/fake-app-state-collection.js +0 -1
- package/dist/state/fake-media-store.d.ts +0 -1
- package/dist/state/fake-media-store.js +2 -2
- package/dist/transport/codec.d.ts +2 -3
- package/dist/transport/codec.js +2 -3
- package/dist/transport/crypto.d.ts +5 -7
- package/dist/transport/crypto.js +6 -11
- package/dist/transport/protos.d.ts +2 -4
- package/dist/transport/protos.js +2 -4
- package/dist/transport/util.d.ts +8 -0
- package/dist/transport/util.js +16 -0
- package/package.json +26 -6
- package/dist/api/AppStateSyncManager.d.ts.map +0 -1
- package/dist/api/AppStateSyncManager.js.map +0 -1
- package/dist/api/FakePairingDriver.d.ts.map +0 -1
- package/dist/api/FakePairingDriver.js.map +0 -1
- package/dist/api/FakePeer.d.ts.map +0 -1
- package/dist/api/FakePeer.js.map +0 -1
- package/dist/api/FakeWaServer.d.ts.map +0 -1
- package/dist/api/FakeWaServer.js.map +0 -1
- package/dist/api/PreKeyDispenser.d.ts.map +0 -1
- package/dist/api/PreKeyDispenser.js.map +0 -1
- package/dist/api/Scenario.d.ts.map +0 -1
- package/dist/api/Scenario.js.map +0 -1
- package/dist/api/ServerRegistries.d.ts.map +0 -1
- package/dist/api/ServerRegistries.js.map +0 -1
- package/dist/api/iq-handlers.d.ts.map +0 -1
- package/dist/api/iq-handlers.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/infra/WaFakeConnection.d.ts.map +0 -1
- package/dist/infra/WaFakeConnection.js.map +0 -1
- package/dist/infra/WaFakeConnectionPipeline.d.ts.map +0 -1
- package/dist/infra/WaFakeConnectionPipeline.js.map +0 -1
- package/dist/infra/WaFakeFrameSocket.d.ts.map +0 -1
- package/dist/infra/WaFakeFrameSocket.js.map +0 -1
- package/dist/infra/WaFakeMediaHttpsServer.d.ts.map +0 -1
- package/dist/infra/WaFakeMediaHttpsServer.js.map +0 -1
- package/dist/infra/WaFakeNoiseHandshake.d.ts.map +0 -1
- package/dist/infra/WaFakeNoiseHandshake.js.map +0 -1
- package/dist/infra/WaFakeTransport.d.ts.map +0 -1
- package/dist/infra/WaFakeTransport.js.map +0 -1
- package/dist/infra/WaFakeWsServer.d.ts.map +0 -1
- package/dist/infra/WaFakeWsServer.js.map +0 -1
- package/dist/protocol/auth/cert-chain.d.ts.map +0 -1
- package/dist/protocol/auth/cert-chain.js.map +0 -1
- package/dist/protocol/auth/client-payload-validate.d.ts.map +0 -1
- package/dist/protocol/auth/client-payload-validate.js.map +0 -1
- package/dist/protocol/auth/fake-primary-device.d.ts.map +0 -1
- package/dist/protocol/auth/fake-primary-device.js.map +0 -1
- package/dist/protocol/auth/pair-device.d.ts.map +0 -1
- package/dist/protocol/auth/pair-device.js.map +0 -1
- package/dist/protocol/auth/success-node.d.ts.map +0 -1
- package/dist/protocol/auth/success-node.js.map +0 -1
- package/dist/protocol/iq/abprops.d.ts.map +0 -1
- package/dist/protocol/iq/abprops.js.map +0 -1
- package/dist/protocol/iq/appstate-sync.d.ts.map +0 -1
- package/dist/protocol/iq/appstate-sync.js.map +0 -1
- package/dist/protocol/iq/business.d.ts.map +0 -1
- package/dist/protocol/iq/business.js.map +0 -1
- package/dist/protocol/iq/dirty-bits.d.ts.map +0 -1
- package/dist/protocol/iq/dirty-bits.js.map +0 -1
- package/dist/protocol/iq/group-ops.d.ts.map +0 -1
- package/dist/protocol/iq/group-ops.js.map +0 -1
- package/dist/protocol/iq/newsletter.d.ts.map +0 -1
- package/dist/protocol/iq/newsletter.js.map +0 -1
- package/dist/protocol/iq/prekey-fetch.d.ts.map +0 -1
- package/dist/protocol/iq/prekey-fetch.js.map +0 -1
- package/dist/protocol/iq/privacy-token.d.ts.map +0 -1
- package/dist/protocol/iq/privacy-token.js.map +0 -1
- package/dist/protocol/iq/privacy.d.ts.map +0 -1
- package/dist/protocol/iq/privacy.js.map +0 -1
- package/dist/protocol/iq/profile.d.ts.map +0 -1
- package/dist/protocol/iq/profile.js.map +0 -1
- package/dist/protocol/iq/router.d.ts.map +0 -1
- package/dist/protocol/iq/router.js.map +0 -1
- package/dist/protocol/iq/usync.d.ts.map +0 -1
- package/dist/protocol/iq/usync.js.map +0 -1
- package/dist/protocol/push/app-state-key-share.d.ts.map +0 -1
- package/dist/protocol/push/app-state-key-share.js.map +0 -1
- package/dist/protocol/push/call-failure.d.ts.map +0 -1
- package/dist/protocol/push/call-failure.js.map +0 -1
- package/dist/protocol/push/chatstate.d.ts.map +0 -1
- package/dist/protocol/push/chatstate.js.map +0 -1
- package/dist/protocol/push/error-stanza.d.ts.map +0 -1
- package/dist/protocol/push/error-stanza.js.map +0 -1
- package/dist/protocol/push/history-sync.d.ts.map +0 -1
- package/dist/protocol/push/history-sync.js.map +0 -1
- package/dist/protocol/push/message.d.ts.map +0 -1
- package/dist/protocol/push/message.js.map +0 -1
- package/dist/protocol/push/notification.d.ts.map +0 -1
- package/dist/protocol/push/notification.js.map +0 -1
- package/dist/protocol/push/presence.d.ts.map +0 -1
- package/dist/protocol/push/presence.js.map +0 -1
- package/dist/protocol/push/receipt.d.ts.map +0 -1
- package/dist/protocol/push/receipt.js.map +0 -1
- package/dist/protocol/signal/fake-app-state-crypto.d.ts.map +0 -1
- package/dist/protocol/signal/fake-app-state-crypto.js.map +0 -1
- package/dist/protocol/signal/fake-peer-double-ratchet.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-double-ratchet.js.map +0 -1
- package/dist/protocol/signal/fake-peer-group-recv-session.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-group-recv-session.js.map +0 -1
- package/dist/protocol/signal/fake-peer-identity.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-identity.js.map +0 -1
- package/dist/protocol/signal/fake-peer-key-bundle.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-key-bundle.js.map +0 -1
- package/dist/protocol/signal/fake-peer-recv-session.d.ts +0 -60
- package/dist/protocol/signal/fake-peer-recv-session.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-recv-session.js +0 -284
- package/dist/protocol/signal/fake-peer-recv-session.js.map +0 -1
- package/dist/protocol/signal/fake-peer-session.d.ts +0 -87
- package/dist/protocol/signal/fake-peer-session.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-session.js +0 -207
- package/dist/protocol/signal/fake-peer-session.js.map +0 -1
- package/dist/protocol/signal/fake-sender-key.d.ts.map +0 -1
- package/dist/protocol/signal/fake-sender-key.js.map +0 -1
- package/dist/protocol/signal/prekey-upload.d.ts.map +0 -1
- package/dist/protocol/signal/prekey-upload.js.map +0 -1
- package/dist/protocol/stream/stream-error.d.ts.map +0 -1
- package/dist/protocol/stream/stream-error.js.map +0 -1
- package/dist/state/fake-app-state-collection.d.ts.map +0 -1
- package/dist/state/fake-app-state-collection.js.map +0 -1
- package/dist/state/fake-media-store.d.ts.map +0 -1
- package/dist/state/fake-media-store.js.map +0 -1
- package/dist/transport/codec.d.ts.map +0 -1
- package/dist/transport/codec.js.map +0 -1
- package/dist/transport/crypto.d.ts.map +0 -1
- package/dist/transport/crypto.js.map +0 -1
- package/dist/transport/index.d.ts +0 -4
- package/dist/transport/index.d.ts.map +0 -1
- package/dist/transport/index.js +0 -20
- package/dist/transport/index.js.map +0 -1
- package/dist/transport/protos.d.ts.map +0 -1
- package/dist/transport/protos.js.map +0 -1
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import { type FakeNoiseRootCa } from '../protocol/auth/cert-chain';
|
|
3
3
|
import { type ParsedClientPayload } from '../protocol/auth/client-payload-validate';
|
|
4
4
|
import { buildSuccessNode } from '../protocol/auth/success-node';
|
|
5
|
-
import { type WaFakeIqRouter } from '../protocol/iq/router';
|
|
6
5
|
import { type BinaryNode } from '../transport/codec';
|
|
7
6
|
import { type SignalKeyPair } from '../transport/crypto';
|
|
8
7
|
import type { WaFakeConnection } from './WaFakeConnection';
|
|
@@ -10,7 +9,12 @@ export interface WaFakeConnectionPipelineConfig {
|
|
|
10
9
|
readonly connection: WaFakeConnection;
|
|
11
10
|
readonly rootCa: FakeNoiseRootCa;
|
|
12
11
|
readonly serverStaticKeyPair: SignalKeyPair;
|
|
13
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Routes an inbound IQ against the session this connection is bound to.
|
|
14
|
+
* The server resolves the session per connection, so the pipeline stays
|
|
15
|
+
* unaware of session identity.
|
|
16
|
+
*/
|
|
17
|
+
readonly routeIq: (iq: BinaryNode) => Promise<BinaryNode | null>;
|
|
14
18
|
readonly successNodeAttributes?: Parameters<typeof buildSuccessNode>[0];
|
|
15
19
|
}
|
|
16
20
|
export interface WaFakeConnectionPipelineEvents {
|
|
@@ -33,9 +37,12 @@ export declare class WaFakeConnectionPipeline {
|
|
|
33
37
|
private events;
|
|
34
38
|
private state;
|
|
35
39
|
private chain;
|
|
40
|
+
private authenticatedPayload;
|
|
36
41
|
constructor(config: WaFakeConnectionPipelineConfig);
|
|
37
42
|
setEvents(events: WaFakeConnectionPipelineEvents): void;
|
|
38
43
|
isAuthenticated(): boolean;
|
|
44
|
+
/** Parsed ClientPayload of the authenticated connection; null before auth. */
|
|
45
|
+
get clientPayload(): ParsedClientPayload | null;
|
|
39
46
|
sendStanza(node: BinaryNode): Promise<void>;
|
|
40
47
|
private onPrologue;
|
|
41
48
|
private scheduleFrame;
|
|
@@ -45,7 +52,7 @@ export declare class WaFakeConnectionPipeline {
|
|
|
45
52
|
/** Server-side IK path used when the client already cached our static key. */
|
|
46
53
|
private handleIkClientHello;
|
|
47
54
|
private handleClientFinish;
|
|
55
|
+
private completeAuthentication;
|
|
48
56
|
private handleAuthenticatedFrame;
|
|
49
57
|
private fail;
|
|
50
58
|
}
|
|
51
|
-
//# sourceMappingURL=WaFakeConnectionPipeline.d.ts.map
|
|
@@ -19,6 +19,7 @@ class WaFakeConnectionPipeline {
|
|
|
19
19
|
this.events = {};
|
|
20
20
|
this.state = { kind: 'awaiting_prologue' };
|
|
21
21
|
this.chain = Promise.resolve();
|
|
22
|
+
this.authenticatedPayload = null;
|
|
22
23
|
this.config = config;
|
|
23
24
|
this.frameSocket = new WaFakeFrameSocket_1.WaFakeFrameSocket(config.connection);
|
|
24
25
|
this.frameSocket.setHandlers({
|
|
@@ -37,6 +38,10 @@ class WaFakeConnectionPipeline {
|
|
|
37
38
|
isAuthenticated() {
|
|
38
39
|
return this.state.kind === 'authenticated';
|
|
39
40
|
}
|
|
41
|
+
/** Parsed ClientPayload of the authenticated connection; null before auth. */
|
|
42
|
+
get clientPayload() {
|
|
43
|
+
return this.authenticatedPayload;
|
|
44
|
+
}
|
|
40
45
|
async sendStanza(node) {
|
|
41
46
|
if (this.state.kind !== 'authenticated') {
|
|
42
47
|
throw new Error(`cannot send stanza while pipeline is in state "${this.state.kind}"`);
|
|
@@ -92,18 +97,18 @@ class WaFakeConnectionPipeline {
|
|
|
92
97
|
}
|
|
93
98
|
async handleXxClientHello(clientEphemeralPub) {
|
|
94
99
|
const handshake = new WaFakeNoiseHandshake_1.WaFakeNoiseHandshake();
|
|
95
|
-
|
|
96
|
-
|
|
100
|
+
handshake.start(NOISE_XX_NAME, PROLOGUE);
|
|
101
|
+
handshake.authenticate(clientEphemeralPub);
|
|
97
102
|
const serverEphemeral = await crypto_1.X25519.generateKeyPair();
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const encryptedServerStatic =
|
|
101
|
-
|
|
103
|
+
handshake.authenticate(serverEphemeral.pubKey);
|
|
104
|
+
handshake.mixIntoKey(await crypto_1.X25519.scalarMult(serverEphemeral.privKey, clientEphemeralPub));
|
|
105
|
+
const encryptedServerStatic = handshake.encrypt(this.config.serverStaticKeyPair.pubKey);
|
|
106
|
+
handshake.mixIntoKey(await crypto_1.X25519.scalarMult(this.config.serverStaticKeyPair.privKey, clientEphemeralPub));
|
|
102
107
|
const certChain = await (0, cert_chain_1.buildFakeCertChain)({
|
|
103
108
|
root: this.config.rootCa,
|
|
104
109
|
leafKey: this.config.serverStaticKeyPair.pubKey
|
|
105
110
|
});
|
|
106
|
-
const encryptedCertPayload =
|
|
111
|
+
const encryptedCertPayload = handshake.encrypt(certChain.encoded);
|
|
107
112
|
const serverHello = protos_1.proto.HandshakeMessage.encode({
|
|
108
113
|
serverHello: {
|
|
109
114
|
ephemeral: serverEphemeral.pubKey,
|
|
@@ -128,23 +133,27 @@ class WaFakeConnectionPipeline {
|
|
|
128
133
|
const encryptedClientStatic = clientHello.static;
|
|
129
134
|
const encryptedClientPayload = clientHello.payload;
|
|
130
135
|
const handshake = new WaFakeNoiseHandshake_1.WaFakeNoiseHandshake();
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const clientStaticKey =
|
|
136
|
-
|
|
137
|
-
const clientPayloadBytes =
|
|
136
|
+
handshake.start(NOISE_IK_NAME, PROLOGUE);
|
|
137
|
+
handshake.authenticate(this.config.serverStaticKeyPair.pubKey);
|
|
138
|
+
handshake.authenticate(clientEphemeralPub);
|
|
139
|
+
handshake.mixIntoKey(await crypto_1.X25519.scalarMult(this.config.serverStaticKeyPair.privKey, clientEphemeralPub));
|
|
140
|
+
const clientStaticKey = handshake.decrypt(encryptedClientStatic);
|
|
141
|
+
handshake.mixIntoKey(await crypto_1.X25519.scalarMult(this.config.serverStaticKeyPair.privKey, clientStaticKey));
|
|
142
|
+
const clientPayloadBytes = handshake.decrypt(encryptedClientPayload);
|
|
138
143
|
const clientPayload = (0, client_payload_validate_1.parseClientPayload)(clientPayloadBytes);
|
|
139
144
|
const serverEphemeral = await crypto_1.X25519.generateKeyPair();
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
145
|
+
handshake.authenticate(serverEphemeral.pubKey);
|
|
146
|
+
const [dhEphem, dhStatic] = await Promise.all([
|
|
147
|
+
crypto_1.X25519.scalarMult(serverEphemeral.privKey, clientEphemeralPub),
|
|
148
|
+
crypto_1.X25519.scalarMult(serverEphemeral.privKey, clientStaticKey)
|
|
149
|
+
]);
|
|
150
|
+
handshake.mixIntoKey(dhEphem);
|
|
151
|
+
handshake.mixIntoKey(dhStatic);
|
|
143
152
|
const certChain = await (0, cert_chain_1.buildFakeCertChain)({
|
|
144
153
|
root: this.config.rootCa,
|
|
145
154
|
leafKey: this.config.serverStaticKeyPair.pubKey
|
|
146
155
|
});
|
|
147
|
-
const encryptedCertPayload =
|
|
156
|
+
const encryptedCertPayload = handshake.encrypt(certChain.encoded);
|
|
148
157
|
const serverHello = protos_1.proto.HandshakeMessage.encode({
|
|
149
158
|
serverHello: {
|
|
150
159
|
ephemeral: serverEphemeral.pubKey,
|
|
@@ -152,14 +161,7 @@ class WaFakeConnectionPipeline {
|
|
|
152
161
|
}
|
|
153
162
|
}).finish();
|
|
154
163
|
this.frameSocket.sendFrame(serverHello);
|
|
155
|
-
|
|
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 });
|
|
164
|
+
await this.completeAuthentication(handshake, clientPayload, clientStaticKey);
|
|
163
165
|
}
|
|
164
166
|
async handleClientFinish(frame, handshake, serverEphemeralKeyPair) {
|
|
165
167
|
const parsed = protos_1.proto.HandshakeMessage.decode(frame);
|
|
@@ -167,17 +169,31 @@ class WaFakeConnectionPipeline {
|
|
|
167
169
|
if (!clientFinish?.static || !clientFinish.payload) {
|
|
168
170
|
throw new Error('ClientFinish missing static/payload');
|
|
169
171
|
}
|
|
170
|
-
const clientStaticKey =
|
|
171
|
-
|
|
172
|
-
const clientPayloadBytes =
|
|
172
|
+
const clientStaticKey = handshake.decrypt(clientFinish.static);
|
|
173
|
+
handshake.mixIntoKey(await crypto_1.X25519.scalarMult(serverEphemeralKeyPair.privKey, clientStaticKey));
|
|
174
|
+
const clientPayloadBytes = handshake.decrypt(clientFinish.payload);
|
|
173
175
|
const clientPayload = (0, client_payload_validate_1.parseClientPayload)(clientPayloadBytes);
|
|
174
|
-
|
|
176
|
+
await this.completeAuthentication(handshake, clientPayload, clientStaticKey);
|
|
177
|
+
}
|
|
178
|
+
async completeAuthentication(handshake, clientPayload, clientStaticKey) {
|
|
179
|
+
const keys = handshake.finish();
|
|
175
180
|
const transport = new WaFakeTransport_1.WaFakeTransport({
|
|
176
181
|
recvKey: keys.recvKey,
|
|
177
182
|
sendKey: keys.sendKey
|
|
178
183
|
});
|
|
179
184
|
this.state = { kind: 'authenticated', transport };
|
|
185
|
+
this.authenticatedPayload = clientPayload;
|
|
180
186
|
await this.sendStanza((0, success_node_1.buildSuccessNode)(this.config.successNodeAttributes));
|
|
187
|
+
if (clientPayload.kind === 'login') {
|
|
188
|
+
// Real WA drains offline messages after login and closes the
|
|
189
|
+
// drain with this bulletin. Baileys-family clients buffer their
|
|
190
|
+
// events until it arrives, so send it eagerly with count=0.
|
|
191
|
+
await this.sendStanza({
|
|
192
|
+
tag: 'ib',
|
|
193
|
+
attrs: { from: 's.whatsapp.net' },
|
|
194
|
+
content: [{ tag: 'offline', attrs: { count: '0' } }]
|
|
195
|
+
});
|
|
196
|
+
}
|
|
181
197
|
this.events.onAuthenticated?.({ clientPayload, clientStaticKey });
|
|
182
198
|
}
|
|
183
199
|
async handleAuthenticatedFrame(frame, transport) {
|
|
@@ -185,7 +201,7 @@ class WaFakeConnectionPipeline {
|
|
|
185
201
|
const node = await (0, codec_1.decodeBinaryNodeStanza)(stanzaBytes);
|
|
186
202
|
this.events.onStanza?.(node);
|
|
187
203
|
if (node.tag === 'iq') {
|
|
188
|
-
const response = await this.config.
|
|
204
|
+
const response = await this.config.routeIq(node);
|
|
189
205
|
if (response !== null) {
|
|
190
206
|
await this.sendStanza(response);
|
|
191
207
|
}
|
|
@@ -221,4 +237,3 @@ class WaFakeConnectionPipeline {
|
|
|
221
237
|
}
|
|
222
238
|
}
|
|
223
239
|
exports.WaFakeConnectionPipeline = WaFakeConnectionPipeline;
|
|
224
|
-
//# sourceMappingURL=WaFakeConnectionPipeline.js.map
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/** Responder-side Noise handshake primitives for fake server pipelines. */
|
|
2
|
-
import { type CryptoKey } from '../transport/crypto';
|
|
3
2
|
export interface WaFakeNoiseHandshakeFinishKeys {
|
|
4
|
-
readonly recvKey:
|
|
5
|
-
readonly sendKey:
|
|
3
|
+
readonly recvKey: Uint8Array;
|
|
4
|
+
readonly sendKey: Uint8Array;
|
|
6
5
|
readonly recvKeyBytes: Uint8Array;
|
|
7
6
|
readonly sendKeyBytes: Uint8Array;
|
|
8
7
|
}
|
|
@@ -11,13 +10,12 @@ export declare class WaFakeNoiseHandshake {
|
|
|
11
10
|
private chainingKey;
|
|
12
11
|
private cipherKey;
|
|
13
12
|
private nonceCounter;
|
|
14
|
-
start(name: Uint8Array, prologue: Uint8Array):
|
|
15
|
-
authenticate(data: Uint8Array):
|
|
16
|
-
mixIntoKey(input: Uint8Array):
|
|
17
|
-
encrypt(plaintext: Uint8Array):
|
|
18
|
-
decrypt(ciphertext: Uint8Array):
|
|
13
|
+
start(name: Uint8Array, prologue: Uint8Array): void;
|
|
14
|
+
authenticate(data: Uint8Array): void;
|
|
15
|
+
mixIntoKey(input: Uint8Array): void;
|
|
16
|
+
encrypt(plaintext: Uint8Array): Uint8Array;
|
|
17
|
+
decrypt(ciphertext: Uint8Array): Uint8Array;
|
|
19
18
|
/** Derives transport keys (`first -> recv`, `second -> send` for responder role). */
|
|
20
|
-
finish():
|
|
19
|
+
finish(): WaFakeNoiseHandshakeFinishKeys;
|
|
21
20
|
private buildNonceIv;
|
|
22
21
|
}
|
|
23
|
-
//# sourceMappingURL=WaFakeNoiseHandshake.d.ts.map
|
|
@@ -11,56 +11,52 @@ class WaFakeNoiseHandshake {
|
|
|
11
11
|
this.cipherKey = null;
|
|
12
12
|
this.nonceCounter = 0;
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
const initialHash = name.byteLength === 32 ? name :
|
|
14
|
+
start(name, prologue) {
|
|
15
|
+
const initialHash = name.byteLength === 32 ? name : (0, crypto_1.sha256)(name);
|
|
16
16
|
this.hash = initialHash;
|
|
17
17
|
this.chainingKey = initialHash;
|
|
18
|
-
this.cipherKey =
|
|
18
|
+
this.cipherKey = initialHash;
|
|
19
19
|
this.nonceCounter = 0;
|
|
20
|
-
|
|
20
|
+
this.authenticate(prologue);
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
authenticate(data) {
|
|
23
23
|
const concatenated = new Uint8Array(this.hash.byteLength + data.byteLength);
|
|
24
24
|
concatenated.set(this.hash, 0);
|
|
25
25
|
concatenated.set(data, this.hash.byteLength);
|
|
26
|
-
this.hash =
|
|
26
|
+
this.hash = (0, crypto_1.sha256)(concatenated);
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
const [nextChainingKey, nextCipherMaterial] =
|
|
28
|
+
mixIntoKey(input) {
|
|
29
|
+
const [nextChainingKey, nextCipherMaterial] = (0, crypto_1.hkdfSplit)(input, this.chainingKey, EMPTY);
|
|
30
30
|
this.chainingKey = nextChainingKey;
|
|
31
|
-
this.cipherKey =
|
|
31
|
+
this.cipherKey = nextCipherMaterial;
|
|
32
32
|
this.nonceCounter = 0;
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
encrypt(plaintext) {
|
|
35
35
|
if (!this.cipherKey) {
|
|
36
36
|
throw new Error('noise handshake encrypt called before key was derived');
|
|
37
37
|
}
|
|
38
38
|
const iv = this.buildNonceIv();
|
|
39
39
|
this.nonceCounter += 1;
|
|
40
|
-
const ciphertext =
|
|
41
|
-
|
|
40
|
+
const ciphertext = (0, crypto_1.aesGcmEncrypt)(this.cipherKey, iv, plaintext, this.hash);
|
|
41
|
+
this.authenticate(ciphertext);
|
|
42
42
|
return ciphertext;
|
|
43
43
|
}
|
|
44
|
-
|
|
44
|
+
decrypt(ciphertext) {
|
|
45
45
|
if (!this.cipherKey) {
|
|
46
46
|
throw new Error('noise handshake decrypt called before key was derived');
|
|
47
47
|
}
|
|
48
48
|
const iv = this.buildNonceIv();
|
|
49
49
|
this.nonceCounter += 1;
|
|
50
|
-
const plaintext =
|
|
51
|
-
|
|
50
|
+
const plaintext = (0, crypto_1.aesGcmDecrypt)(this.cipherKey, iv, ciphertext, this.hash);
|
|
51
|
+
this.authenticate(ciphertext);
|
|
52
52
|
return plaintext;
|
|
53
53
|
}
|
|
54
54
|
/** Derives transport keys (`first -> recv`, `second -> send` for responder role). */
|
|
55
|
-
|
|
56
|
-
const [first, second] =
|
|
57
|
-
const [recvKey, sendKey] = await Promise.all([
|
|
58
|
-
(0, crypto_1.importAesGcmKey)(first, ['decrypt']),
|
|
59
|
-
(0, crypto_1.importAesGcmKey)(second, ['encrypt'])
|
|
60
|
-
]);
|
|
55
|
+
finish() {
|
|
56
|
+
const [first, second] = (0, crypto_1.hkdfSplit)(EMPTY, this.chainingKey, EMPTY);
|
|
61
57
|
return {
|
|
62
|
-
recvKey,
|
|
63
|
-
sendKey,
|
|
58
|
+
recvKey: first,
|
|
59
|
+
sendKey: second,
|
|
64
60
|
recvKeyBytes: first,
|
|
65
61
|
sendKeyBytes: second
|
|
66
62
|
};
|
|
@@ -73,4 +69,3 @@ class WaFakeNoiseHandshake {
|
|
|
73
69
|
}
|
|
74
70
|
}
|
|
75
71
|
exports.WaFakeNoiseHandshake = WaFakeNoiseHandshake;
|
|
76
|
-
//# sourceMappingURL=WaFakeNoiseHandshake.js.map
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
/** Post-handshake Noise transport (AES-GCM with direction-specific counters). */
|
|
2
|
-
import { type CryptoKey } from '../transport/crypto';
|
|
3
2
|
export declare class WaFakeTransport {
|
|
4
3
|
private readonly recvKey;
|
|
5
4
|
private readonly sendKey;
|
|
6
5
|
private sendCounter;
|
|
7
6
|
private recvCounter;
|
|
8
7
|
constructor(keys: {
|
|
9
|
-
readonly recvKey:
|
|
10
|
-
readonly sendKey:
|
|
8
|
+
readonly recvKey: Uint8Array;
|
|
9
|
+
readonly sendKey: Uint8Array;
|
|
11
10
|
});
|
|
12
11
|
encryptFrame(plaintext: Uint8Array): Promise<Uint8Array>;
|
|
13
12
|
decryptFrame(ciphertext: Uint8Array): Promise<Uint8Array>;
|
|
14
13
|
}
|
|
15
|
-
//# sourceMappingURL=WaFakeTransport.d.ts.map
|
|
@@ -10,11 +10,13 @@ class WaFakeTransport {
|
|
|
10
10
|
this.recvKey = keys.recvKey;
|
|
11
11
|
this.sendKey = keys.sendKey;
|
|
12
12
|
}
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
13
14
|
async encryptFrame(plaintext) {
|
|
14
15
|
const nonce = buildAesGcmNonce(this.sendCounter);
|
|
15
16
|
this.sendCounter += 1;
|
|
16
17
|
return (0, crypto_1.aesGcmEncrypt)(this.sendKey, nonce, plaintext);
|
|
17
18
|
}
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
18
20
|
async decryptFrame(ciphertext) {
|
|
19
21
|
const nonce = buildAesGcmNonce(this.recvCounter);
|
|
20
22
|
this.recvCounter += 1;
|
|
@@ -31,4 +33,3 @@ function buildAesGcmNonce(counter) {
|
|
|
31
33
|
view.setUint32(8, counter, false);
|
|
32
34
|
return nonce;
|
|
33
35
|
}
|
|
34
|
-
//# sourceMappingURL=WaFakeTransport.js.map
|
|
@@ -12,7 +12,10 @@ export interface BuildFakeCertChainInput {
|
|
|
12
12
|
readonly leafKey: Uint8Array;
|
|
13
13
|
readonly intermediateSerial?: number;
|
|
14
14
|
readonly leafSerial?: number;
|
|
15
|
+
/** Unix seconds. Defaults to 24h before build time. */
|
|
16
|
+
readonly notBefore?: number;
|
|
17
|
+
/** Unix seconds. Defaults to 10 years after build time. */
|
|
18
|
+
readonly notAfter?: number;
|
|
15
19
|
}
|
|
16
20
|
export declare function generateFakeNoiseRootCa(): Promise<FakeNoiseRootCa>;
|
|
17
21
|
export declare function buildFakeCertChain(input: BuildFakeCertChainInput): Promise<FakeCertChainResult>;
|
|
18
|
-
//# sourceMappingURL=cert-chain.d.ts.map
|
|
@@ -5,6 +5,8 @@ exports.generateFakeNoiseRootCa = generateFakeNoiseRootCa;
|
|
|
5
5
|
exports.buildFakeCertChain = buildFakeCertChain;
|
|
6
6
|
const crypto_1 = require("../../transport/crypto");
|
|
7
7
|
const protos_1 = require("../../transport/protos");
|
|
8
|
+
const WA_CERT_NOT_BEFORE_BACKDATE_SECONDS = 86400;
|
|
9
|
+
const WA_CERT_NOT_AFTER_LIFETIME_SECONDS = 315360000;
|
|
8
10
|
async function generateFakeNoiseRootCa() {
|
|
9
11
|
const keyPair = await crypto_1.X25519.generateKeyPair();
|
|
10
12
|
return {
|
|
@@ -16,17 +18,26 @@ async function generateFakeNoiseRootCa() {
|
|
|
16
18
|
async function buildFakeCertChain(input) {
|
|
17
19
|
const intermediateSerial = input.intermediateSerial ?? 1;
|
|
18
20
|
const leafSerial = input.leafSerial ?? 2;
|
|
21
|
+
// Strict clients (e.g. whatsmeow) enforce the validity window; leaving
|
|
22
|
+
// notBefore/notAfter unset decodes as 0 (1970) and reads as expired.
|
|
23
|
+
const nowSeconds = Math.floor(Date.now() / 1000);
|
|
24
|
+
const notBefore = input.notBefore ?? nowSeconds - WA_CERT_NOT_BEFORE_BACKDATE_SECONDS;
|
|
25
|
+
const notAfter = input.notAfter ?? nowSeconds + WA_CERT_NOT_AFTER_LIFETIME_SECONDS;
|
|
19
26
|
const intermediateKeyPair = await crypto_1.X25519.generateKeyPair();
|
|
20
27
|
const intermediateDetails = protos_1.proto.CertChain.NoiseCertificate.Details.encode({
|
|
21
28
|
serial: intermediateSerial,
|
|
22
29
|
issuerSerial: input.root.serial,
|
|
23
|
-
key: intermediateKeyPair.pubKey
|
|
30
|
+
key: intermediateKeyPair.pubKey,
|
|
31
|
+
notBefore,
|
|
32
|
+
notAfter
|
|
24
33
|
}).finish();
|
|
25
34
|
const intermediateSignature = await (0, crypto_1.xeddsaSign)(input.root.privateKey, intermediateDetails);
|
|
26
35
|
const leafDetails = protos_1.proto.CertChain.NoiseCertificate.Details.encode({
|
|
27
36
|
serial: leafSerial,
|
|
28
37
|
issuerSerial: intermediateSerial,
|
|
29
|
-
key: input.leafKey
|
|
38
|
+
key: input.leafKey,
|
|
39
|
+
notBefore,
|
|
40
|
+
notAfter
|
|
30
41
|
}).finish();
|
|
31
42
|
const leafSignature = await (0, crypto_1.xeddsaSign)(intermediateKeyPair.privKey, leafDetails);
|
|
32
43
|
const encoded = protos_1.proto.CertChain.encode({
|
|
@@ -41,4 +52,3 @@ async function buildFakeCertChain(input) {
|
|
|
41
52
|
}).finish();
|
|
42
53
|
return { encoded };
|
|
43
54
|
}
|
|
44
|
-
//# sourceMappingURL=cert-chain.js.map
|
|
@@ -30,8 +30,7 @@ async function buildAdvSignedDeviceIdentity(input) {
|
|
|
30
30
|
accountSignatureKey,
|
|
31
31
|
accountSignature
|
|
32
32
|
}).finish();
|
|
33
|
-
const
|
|
34
|
-
const hmac = await (0, crypto_1.hmacSign)(hmacKey, signedIdentity);
|
|
33
|
+
const hmac = (0, crypto_1.hmacSha256Sign)(input.advSecretKey, signedIdentity);
|
|
35
34
|
const wrapped = protos_1.proto.ADVSignedDeviceIdentityHMAC.encode({
|
|
36
35
|
details: signedIdentity,
|
|
37
36
|
hmac
|
|
@@ -50,4 +49,3 @@ function concatBytes(parts) {
|
|
|
50
49
|
}
|
|
51
50
|
return out;
|
|
52
51
|
}
|
|
53
|
-
//# sourceMappingURL=fake-primary-device.js.map
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
exports.buildPairDeviceIq = buildPairDeviceIq;
|
|
5
5
|
exports.buildPairSuccessIq = buildPairSuccessIq;
|
|
6
6
|
exports.parsePairingQrString = parsePairingQrString;
|
|
7
|
+
const util_1 = require("../../transport/util");
|
|
7
8
|
function buildPairDeviceIq(input) {
|
|
8
9
|
if (input.refs.length !== 6) {
|
|
9
10
|
throw new Error(`pair-device requires exactly 6 refs, got ${input.refs.length}`);
|
|
@@ -83,22 +84,9 @@ function parsePairingQrString(qr) {
|
|
|
83
84
|
const ref = parts.slice(0, parts.length - 4).join(',');
|
|
84
85
|
return {
|
|
85
86
|
ref,
|
|
86
|
-
noisePublicKey:
|
|
87
|
-
identityPublicKey:
|
|
88
|
-
advSecretKey:
|
|
87
|
+
noisePublicKey: (0, util_1.decodeBase64Url)(noisePubB64, 'qr.noisePublicKey'),
|
|
88
|
+
identityPublicKey: (0, util_1.decodeBase64Url)(identityPubB64, 'qr.identityPublicKey'),
|
|
89
|
+
advSecretKey: (0, util_1.decodeBase64Url)(advSecretB64, 'qr.advSecretKey'),
|
|
89
90
|
platform
|
|
90
91
|
};
|
|
91
92
|
}
|
|
92
|
-
function base64Decode(input) {
|
|
93
|
-
let normalized = input.replace(/-/g, '+').replace(/_/g, '/');
|
|
94
|
-
const remainder = normalized.length % 4;
|
|
95
|
-
if (remainder === 2)
|
|
96
|
-
normalized += '==';
|
|
97
|
-
else if (remainder === 3)
|
|
98
|
-
normalized += '=';
|
|
99
|
-
else if (remainder === 1) {
|
|
100
|
-
throw new Error(`invalid base64 string length: ${input.length}`);
|
|
101
|
-
}
|
|
102
|
-
return new Uint8Array(Buffer.from(normalized, 'base64'));
|
|
103
|
-
}
|
|
104
|
-
//# sourceMappingURL=pair-device.js.map
|
|
@@ -10,4 +10,3 @@ export interface FakeBusinessProfile {
|
|
|
10
10
|
}
|
|
11
11
|
export declare function buildBusinessProfileResult(iq: BinaryNode, profiles: readonly FakeBusinessProfile[]): BinaryNode;
|
|
12
12
|
export declare function parseGetBusinessProfileIq(iq: BinaryNode): readonly string[] | null;
|
|
13
|
-
//# sourceMappingURL=business.d.ts.map
|