@zapo-js/fake-server 0.3.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/api/AppStateSyncManager.d.ts +0 -1
- package/dist/api/AppStateSyncManager.js +0 -1
- package/dist/api/FakePairingDriver.d.ts +0 -1
- package/dist/api/FakePairingDriver.js +0 -1
- package/dist/api/FakePeer.d.ts +77 -4
- package/dist/api/FakePeer.js +201 -1
- package/dist/api/FakeWaServer.d.ts +11 -1
- package/dist/api/FakeWaServer.js +34 -2
- package/dist/api/PreKeyDispenser.d.ts +0 -1
- package/dist/api/PreKeyDispenser.js +0 -1
- package/dist/api/Scenario.d.ts +0 -1
- package/dist/api/Scenario.js +0 -1
- package/dist/api/ServerRegistries.d.ts +0 -1
- package/dist/api/ServerRegistries.js +0 -1
- package/dist/api/iq-handlers.d.ts +0 -1
- package/dist/api/iq-handlers.js +0 -1
- package/dist/{cli.d.ts → bin.d.ts} +0 -1
- package/dist/{cli.js → bin.js} +1 -2
- package/dist/esm/api/AppStateSyncManager.js +146 -0
- package/dist/esm/api/FakePairingDriver.js +31 -0
- package/dist/esm/api/FakePeer.js +604 -0
- package/dist/esm/api/FakeWaServer.js +680 -0
- package/dist/esm/api/PreKeyDispenser.js +93 -0
- package/dist/esm/api/Scenario.js +32 -0
- package/dist/esm/api/ServerRegistries.js +261 -0
- package/dist/esm/api/iq-handlers.js +492 -0
- package/dist/esm/bin.js +246 -0
- package/dist/esm/index.js +26 -0
- package/dist/esm/infra/WaFakeConnection.js +49 -0
- package/dist/esm/infra/WaFakeConnectionPipeline.js +223 -0
- package/dist/esm/infra/WaFakeFrameSocket.js +117 -0
- package/dist/esm/infra/WaFakeMediaHttpsServer.js +126 -0
- package/dist/esm/infra/WaFakeNoiseHandshake.js +67 -0
- package/dist/esm/infra/WaFakeTransport.js +31 -0
- package/dist/esm/infra/WaFakeWsServer.js +96 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/protocol/auth/cert-chain.js +39 -0
- package/dist/esm/protocol/auth/client-payload-validate.js +55 -0
- package/dist/esm/protocol/auth/fake-primary-device.js +47 -0
- package/dist/esm/protocol/auth/pair-device.js +87 -0
- package/dist/esm/protocol/auth/success-node.js +26 -0
- package/dist/esm/protocol/iq/abprops.js +30 -0
- package/dist/esm/protocol/iq/appstate-sync.js +146 -0
- package/dist/esm/protocol/iq/business.js +59 -0
- package/dist/esm/protocol/iq/dirty-bits.js +19 -0
- package/dist/esm/protocol/iq/group-ops.js +154 -0
- package/dist/esm/protocol/iq/newsletter.js +14 -0
- package/dist/esm/protocol/iq/prekey-fetch.js +88 -0
- package/dist/esm/protocol/iq/privacy-token.js +26 -0
- package/dist/esm/protocol/iq/privacy.js +123 -0
- package/dist/esm/protocol/iq/profile.js +72 -0
- package/dist/esm/protocol/iq/router.js +111 -0
- package/dist/esm/protocol/iq/usync.js +64 -0
- package/dist/esm/protocol/push/app-state-key-share.js +26 -0
- package/dist/esm/protocol/push/call-failure.js +27 -0
- package/dist/esm/protocol/push/chatstate.js +23 -0
- package/dist/esm/protocol/push/error-stanza.js +13 -0
- package/dist/esm/protocol/push/history-sync.js +111 -0
- package/dist/esm/protocol/push/message.js +38 -0
- package/dist/esm/protocol/push/notification.js +29 -0
- package/dist/esm/protocol/push/presence.js +14 -0
- package/dist/esm/protocol/push/receipt.js +21 -0
- package/dist/esm/protocol/signal/fake-app-state-crypto.js +196 -0
- package/dist/esm/protocol/signal/fake-peer-double-ratchet.js +398 -0
- package/dist/esm/protocol/signal/fake-peer-group-recv-session.js +120 -0
- package/dist/esm/protocol/signal/fake-peer-identity.js +8 -0
- package/dist/esm/protocol/signal/fake-peer-key-bundle.js +25 -0
- package/dist/esm/protocol/signal/fake-sender-key.js +83 -0
- package/dist/esm/protocol/signal/prekey-upload.js +107 -0
- package/dist/esm/protocol/stream/stream-error.js +56 -0
- package/dist/esm/state/fake-app-state-collection.js +134 -0
- package/dist/esm/state/fake-media-store.js +53 -0
- package/dist/esm/transport/codec.js +8 -0
- package/dist/esm/transport/crypto.js +8 -0
- package/dist/esm/transport/protos.js +7 -0
- package/dist/esm/transport/util.js +8 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/infra/WaFakeConnection.d.ts +0 -1
- package/dist/infra/WaFakeConnection.js +0 -1
- package/dist/infra/WaFakeConnectionPipeline.d.ts +0 -1
- package/dist/infra/WaFakeConnectionPipeline.js +27 -24
- package/dist/infra/WaFakeFrameSocket.d.ts +0 -1
- package/dist/infra/WaFakeFrameSocket.js +0 -1
- package/dist/infra/WaFakeMediaHttpsServer.d.ts +0 -1
- package/dist/infra/WaFakeMediaHttpsServer.js +0 -1
- package/dist/infra/WaFakeNoiseHandshake.d.ts +8 -10
- package/dist/infra/WaFakeNoiseHandshake.js +19 -24
- package/dist/infra/WaFakeTransport.d.ts +2 -4
- package/dist/infra/WaFakeTransport.js +2 -1
- package/dist/infra/WaFakeWsServer.d.ts +0 -1
- package/dist/infra/WaFakeWsServer.js +0 -1
- package/dist/protocol/auth/cert-chain.d.ts +0 -1
- package/dist/protocol/auth/cert-chain.js +0 -1
- package/dist/protocol/auth/client-payload-validate.d.ts +0 -1
- package/dist/protocol/auth/client-payload-validate.js +0 -1
- package/dist/protocol/auth/fake-primary-device.d.ts +0 -1
- package/dist/protocol/auth/fake-primary-device.js +1 -3
- package/dist/protocol/auth/pair-device.d.ts +0 -1
- package/dist/protocol/auth/pair-device.js +4 -16
- package/dist/protocol/auth/success-node.d.ts +0 -1
- package/dist/protocol/auth/success-node.js +0 -1
- package/dist/protocol/iq/abprops.d.ts +0 -1
- package/dist/protocol/iq/abprops.js +0 -1
- package/dist/protocol/iq/appstate-sync.d.ts +0 -1
- package/dist/protocol/iq/appstate-sync.js +0 -1
- package/dist/protocol/iq/business.d.ts +0 -1
- package/dist/protocol/iq/business.js +0 -1
- package/dist/protocol/iq/dirty-bits.d.ts +0 -1
- package/dist/protocol/iq/dirty-bits.js +0 -1
- package/dist/protocol/iq/group-ops.d.ts +0 -1
- package/dist/protocol/iq/group-ops.js +0 -1
- package/dist/protocol/iq/newsletter.d.ts +0 -1
- package/dist/protocol/iq/newsletter.js +0 -1
- package/dist/protocol/iq/prekey-fetch.d.ts +0 -1
- package/dist/protocol/iq/prekey-fetch.js +0 -1
- package/dist/protocol/iq/privacy-token.d.ts +0 -1
- package/dist/protocol/iq/privacy-token.js +0 -1
- package/dist/protocol/iq/privacy.d.ts +0 -1
- package/dist/protocol/iq/privacy.js +15 -16
- package/dist/protocol/iq/profile.d.ts +0 -1
- package/dist/protocol/iq/profile.js +0 -1
- package/dist/protocol/iq/router.d.ts +0 -1
- package/dist/protocol/iq/router.js +0 -1
- package/dist/protocol/iq/usync.d.ts +0 -1
- package/dist/protocol/iq/usync.js +0 -1
- package/dist/protocol/push/app-state-key-share.d.ts +0 -1
- package/dist/protocol/push/app-state-key-share.js +0 -1
- package/dist/protocol/push/call-failure.d.ts +0 -1
- package/dist/protocol/push/call-failure.js +0 -1
- package/dist/protocol/push/chatstate.d.ts +0 -1
- package/dist/protocol/push/chatstate.js +0 -1
- package/dist/protocol/push/error-stanza.d.ts +0 -1
- package/dist/protocol/push/error-stanza.js +0 -1
- package/dist/protocol/push/history-sync.d.ts +0 -1
- package/dist/protocol/push/history-sync.js +0 -1
- package/dist/protocol/push/message.d.ts +0 -1
- package/dist/protocol/push/message.js +0 -1
- package/dist/protocol/push/notification.d.ts +0 -1
- package/dist/protocol/push/notification.js +0 -1
- package/dist/protocol/push/presence.d.ts +0 -1
- package/dist/protocol/push/presence.js +0 -1
- package/dist/protocol/push/receipt.d.ts +0 -1
- package/dist/protocol/push/receipt.js +0 -1
- package/dist/protocol/signal/fake-app-state-crypto.d.ts +7 -9
- package/dist/protocol/signal/fake-app-state-crypto.js +31 -33
- package/dist/protocol/signal/fake-peer-double-ratchet.d.ts +0 -1
- package/dist/protocol/signal/fake-peer-double-ratchet.js +23 -28
- package/dist/protocol/signal/fake-peer-group-recv-session.d.ts +0 -1
- package/dist/protocol/signal/fake-peer-group-recv-session.js +6 -10
- package/dist/protocol/signal/fake-peer-identity.d.ts +0 -1
- package/dist/protocol/signal/fake-peer-identity.js +0 -1
- package/dist/protocol/signal/fake-peer-key-bundle.d.ts +0 -1
- package/dist/protocol/signal/fake-peer-key-bundle.js +0 -1
- package/dist/protocol/signal/fake-sender-key.d.ts +0 -1
- package/dist/protocol/signal/fake-sender-key.js +5 -9
- package/dist/protocol/signal/prekey-upload.d.ts +0 -1
- package/dist/protocol/signal/prekey-upload.js +0 -1
- package/dist/protocol/stream/stream-error.d.ts +0 -1
- package/dist/protocol/stream/stream-error.js +0 -1
- package/dist/state/fake-app-state-collection.d.ts +0 -1
- package/dist/state/fake-app-state-collection.js +0 -1
- package/dist/state/fake-media-store.d.ts +0 -1
- package/dist/state/fake-media-store.js +2 -2
- package/dist/transport/codec.d.ts +2 -3
- package/dist/transport/codec.js +2 -3
- package/dist/transport/crypto.d.ts +5 -7
- package/dist/transport/crypto.js +6 -11
- package/dist/transport/protos.d.ts +2 -4
- package/dist/transport/protos.js +2 -4
- package/dist/transport/util.d.ts +8 -0
- package/dist/transport/util.js +15 -0
- package/package.json +21 -6
- package/dist/api/AppStateSyncManager.d.ts.map +0 -1
- package/dist/api/AppStateSyncManager.js.map +0 -1
- package/dist/api/FakePairingDriver.d.ts.map +0 -1
- package/dist/api/FakePairingDriver.js.map +0 -1
- package/dist/api/FakePeer.d.ts.map +0 -1
- package/dist/api/FakePeer.js.map +0 -1
- package/dist/api/FakeWaServer.d.ts.map +0 -1
- package/dist/api/FakeWaServer.js.map +0 -1
- package/dist/api/PreKeyDispenser.d.ts.map +0 -1
- package/dist/api/PreKeyDispenser.js.map +0 -1
- package/dist/api/Scenario.d.ts.map +0 -1
- package/dist/api/Scenario.js.map +0 -1
- package/dist/api/ServerRegistries.d.ts.map +0 -1
- package/dist/api/ServerRegistries.js.map +0 -1
- package/dist/api/iq-handlers.d.ts.map +0 -1
- package/dist/api/iq-handlers.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/infra/WaFakeConnection.d.ts.map +0 -1
- package/dist/infra/WaFakeConnection.js.map +0 -1
- package/dist/infra/WaFakeConnectionPipeline.d.ts.map +0 -1
- package/dist/infra/WaFakeConnectionPipeline.js.map +0 -1
- package/dist/infra/WaFakeFrameSocket.d.ts.map +0 -1
- package/dist/infra/WaFakeFrameSocket.js.map +0 -1
- package/dist/infra/WaFakeMediaHttpsServer.d.ts.map +0 -1
- package/dist/infra/WaFakeMediaHttpsServer.js.map +0 -1
- package/dist/infra/WaFakeNoiseHandshake.d.ts.map +0 -1
- package/dist/infra/WaFakeNoiseHandshake.js.map +0 -1
- package/dist/infra/WaFakeTransport.d.ts.map +0 -1
- package/dist/infra/WaFakeTransport.js.map +0 -1
- package/dist/infra/WaFakeWsServer.d.ts.map +0 -1
- package/dist/infra/WaFakeWsServer.js.map +0 -1
- package/dist/protocol/auth/cert-chain.d.ts.map +0 -1
- package/dist/protocol/auth/cert-chain.js.map +0 -1
- package/dist/protocol/auth/client-payload-validate.d.ts.map +0 -1
- package/dist/protocol/auth/client-payload-validate.js.map +0 -1
- package/dist/protocol/auth/fake-primary-device.d.ts.map +0 -1
- package/dist/protocol/auth/fake-primary-device.js.map +0 -1
- package/dist/protocol/auth/pair-device.d.ts.map +0 -1
- package/dist/protocol/auth/pair-device.js.map +0 -1
- package/dist/protocol/auth/success-node.d.ts.map +0 -1
- package/dist/protocol/auth/success-node.js.map +0 -1
- package/dist/protocol/iq/abprops.d.ts.map +0 -1
- package/dist/protocol/iq/abprops.js.map +0 -1
- package/dist/protocol/iq/appstate-sync.d.ts.map +0 -1
- package/dist/protocol/iq/appstate-sync.js.map +0 -1
- package/dist/protocol/iq/business.d.ts.map +0 -1
- package/dist/protocol/iq/business.js.map +0 -1
- package/dist/protocol/iq/dirty-bits.d.ts.map +0 -1
- package/dist/protocol/iq/dirty-bits.js.map +0 -1
- package/dist/protocol/iq/group-ops.d.ts.map +0 -1
- package/dist/protocol/iq/group-ops.js.map +0 -1
- package/dist/protocol/iq/newsletter.d.ts.map +0 -1
- package/dist/protocol/iq/newsletter.js.map +0 -1
- package/dist/protocol/iq/prekey-fetch.d.ts.map +0 -1
- package/dist/protocol/iq/prekey-fetch.js.map +0 -1
- package/dist/protocol/iq/privacy-token.d.ts.map +0 -1
- package/dist/protocol/iq/privacy-token.js.map +0 -1
- package/dist/protocol/iq/privacy.d.ts.map +0 -1
- package/dist/protocol/iq/privacy.js.map +0 -1
- package/dist/protocol/iq/profile.d.ts.map +0 -1
- package/dist/protocol/iq/profile.js.map +0 -1
- package/dist/protocol/iq/router.d.ts.map +0 -1
- package/dist/protocol/iq/router.js.map +0 -1
- package/dist/protocol/iq/usync.d.ts.map +0 -1
- package/dist/protocol/iq/usync.js.map +0 -1
- package/dist/protocol/push/app-state-key-share.d.ts.map +0 -1
- package/dist/protocol/push/app-state-key-share.js.map +0 -1
- package/dist/protocol/push/call-failure.d.ts.map +0 -1
- package/dist/protocol/push/call-failure.js.map +0 -1
- package/dist/protocol/push/chatstate.d.ts.map +0 -1
- package/dist/protocol/push/chatstate.js.map +0 -1
- package/dist/protocol/push/error-stanza.d.ts.map +0 -1
- package/dist/protocol/push/error-stanza.js.map +0 -1
- package/dist/protocol/push/history-sync.d.ts.map +0 -1
- package/dist/protocol/push/history-sync.js.map +0 -1
- package/dist/protocol/push/message.d.ts.map +0 -1
- package/dist/protocol/push/message.js.map +0 -1
- package/dist/protocol/push/notification.d.ts.map +0 -1
- package/dist/protocol/push/notification.js.map +0 -1
- package/dist/protocol/push/presence.d.ts.map +0 -1
- package/dist/protocol/push/presence.js.map +0 -1
- package/dist/protocol/push/receipt.d.ts.map +0 -1
- package/dist/protocol/push/receipt.js.map +0 -1
- package/dist/protocol/signal/fake-app-state-crypto.d.ts.map +0 -1
- package/dist/protocol/signal/fake-app-state-crypto.js.map +0 -1
- package/dist/protocol/signal/fake-peer-double-ratchet.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-double-ratchet.js.map +0 -1
- package/dist/protocol/signal/fake-peer-group-recv-session.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-group-recv-session.js.map +0 -1
- package/dist/protocol/signal/fake-peer-identity.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-identity.js.map +0 -1
- package/dist/protocol/signal/fake-peer-key-bundle.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-key-bundle.js.map +0 -1
- package/dist/protocol/signal/fake-peer-recv-session.d.ts +0 -60
- package/dist/protocol/signal/fake-peer-recv-session.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-recv-session.js +0 -284
- package/dist/protocol/signal/fake-peer-recv-session.js.map +0 -1
- package/dist/protocol/signal/fake-peer-session.d.ts +0 -87
- package/dist/protocol/signal/fake-peer-session.d.ts.map +0 -1
- package/dist/protocol/signal/fake-peer-session.js +0 -207
- package/dist/protocol/signal/fake-peer-session.js.map +0 -1
- package/dist/protocol/signal/fake-sender-key.d.ts.map +0 -1
- package/dist/protocol/signal/fake-sender-key.js.map +0 -1
- package/dist/protocol/signal/prekey-upload.d.ts.map +0 -1
- package/dist/protocol/signal/prekey-upload.js.map +0 -1
- package/dist/protocol/stream/stream-error.d.ts.map +0 -1
- package/dist/protocol/stream/stream-error.js.map +0 -1
- package/dist/state/fake-app-state-collection.d.ts.map +0 -1
- package/dist/state/fake-app-state-collection.js.map +0 -1
- package/dist/state/fake-media-store.d.ts.map +0 -1
- package/dist/state/fake-media-store.js.map +0 -1
- package/dist/transport/codec.d.ts.map +0 -1
- package/dist/transport/codec.js.map +0 -1
- package/dist/transport/crypto.d.ts.map +0 -1
- package/dist/transport/crypto.js.map +0 -1
- package/dist/transport/index.d.ts +0 -4
- package/dist/transport/index.d.ts.map +0 -1
- package/dist/transport/index.js +0 -20
- package/dist/transport/index.js.map +0 -1
- package/dist/transport/protos.d.ts.map +0 -1
- package/dist/transport/protos.js.map +0 -1
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { buildServerSyncNotification } from '../protocol/iq/appstate-sync.js';
|
|
2
|
+
import { FakeAppStateCrypto } from '../protocol/signal/fake-app-state-crypto.js';
|
|
3
|
+
import { proto } from '../transport/protos.js';
|
|
4
|
+
function toHex(bytes) {
|
|
5
|
+
let out = '';
|
|
6
|
+
for (let index = 0; index < bytes.byteLength; index += 1) {
|
|
7
|
+
const value = bytes[index];
|
|
8
|
+
out += value < 16 ? `0${value.toString(16)}` : value.toString(16);
|
|
9
|
+
}
|
|
10
|
+
return out;
|
|
11
|
+
}
|
|
12
|
+
export class AppStateSyncManager {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.appStateCollectionProviders = new Map();
|
|
15
|
+
this.appStateSyncKeysByKeyId = new Map();
|
|
16
|
+
this.appStateCrypto = new FakeAppStateCrypto();
|
|
17
|
+
this.outboundMutationListeners = new Set();
|
|
18
|
+
}
|
|
19
|
+
registerAppStateSyncKey(keyId, keyData) {
|
|
20
|
+
this.appStateSyncKeysByKeyId.set(toHex(keyId), keyData);
|
|
21
|
+
}
|
|
22
|
+
onOutboundAppStateMutation(listener) {
|
|
23
|
+
this.outboundMutationListeners.add(listener);
|
|
24
|
+
return () => {
|
|
25
|
+
this.outboundMutationListeners.delete(listener);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
expectAppStateMutation(predicate, timeoutMs = 15000) {
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
const timer = setTimeout(() => {
|
|
31
|
+
unsubscribe();
|
|
32
|
+
reject(new Error(`expectAppStateMutation timed out after ${timeoutMs}ms`));
|
|
33
|
+
}, timeoutMs);
|
|
34
|
+
const unsubscribe = this.onOutboundAppStateMutation((mutation) => {
|
|
35
|
+
if (!predicate(mutation))
|
|
36
|
+
return;
|
|
37
|
+
clearTimeout(timer);
|
|
38
|
+
unsubscribe();
|
|
39
|
+
resolve(mutation);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
provideAppStateCollection(name, provider) {
|
|
44
|
+
this.appStateCollectionProviders.set(name, provider);
|
|
45
|
+
return () => {
|
|
46
|
+
this.appStateCollectionProviders.delete(name);
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
async pushServerSyncNotification(pipeline, input) {
|
|
50
|
+
await pipeline.sendStanza(buildServerSyncNotification(input));
|
|
51
|
+
}
|
|
52
|
+
async consumeOutboundAppStatePatches(iq) {
|
|
53
|
+
if (!Array.isArray(iq.content))
|
|
54
|
+
return;
|
|
55
|
+
const sync = iq.content.find((child) => child.tag === 'sync');
|
|
56
|
+
if (!sync || !Array.isArray(sync.content))
|
|
57
|
+
return;
|
|
58
|
+
for (const collectionNode of sync.content) {
|
|
59
|
+
if (collectionNode.tag !== 'collection')
|
|
60
|
+
continue;
|
|
61
|
+
if (!Array.isArray(collectionNode.content))
|
|
62
|
+
continue;
|
|
63
|
+
const collectionName = collectionNode.attrs.name;
|
|
64
|
+
if (!collectionName)
|
|
65
|
+
continue;
|
|
66
|
+
for (const patchNode of collectionNode.content) {
|
|
67
|
+
if (patchNode.tag !== 'patch')
|
|
68
|
+
continue;
|
|
69
|
+
const patchBytes = patchNode.content;
|
|
70
|
+
if (!(patchBytes instanceof Uint8Array))
|
|
71
|
+
continue;
|
|
72
|
+
try {
|
|
73
|
+
const decoded = proto.SyncdPatch.decode(patchBytes);
|
|
74
|
+
const keyId = decoded.keyId?.id;
|
|
75
|
+
if (!keyId)
|
|
76
|
+
continue;
|
|
77
|
+
const keyData = this.appStateSyncKeysByKeyId.get(toHex(keyId));
|
|
78
|
+
if (!keyData)
|
|
79
|
+
continue;
|
|
80
|
+
const rawVersion = decoded.version?.version;
|
|
81
|
+
let patchVersion = 0;
|
|
82
|
+
if (typeof rawVersion === 'number') {
|
|
83
|
+
patchVersion = rawVersion;
|
|
84
|
+
}
|
|
85
|
+
else if (rawVersion !== null &&
|
|
86
|
+
rawVersion !== undefined &&
|
|
87
|
+
typeof rawVersion.toNumber === 'function') {
|
|
88
|
+
patchVersion = rawVersion.toNumber();
|
|
89
|
+
}
|
|
90
|
+
for (const mutation of decoded.mutations ?? []) {
|
|
91
|
+
const operationCode = mutation.operation;
|
|
92
|
+
if (operationCode === null || operationCode === undefined)
|
|
93
|
+
continue;
|
|
94
|
+
const record = mutation.record;
|
|
95
|
+
if (!record)
|
|
96
|
+
continue;
|
|
97
|
+
const indexMac = record.index?.blob;
|
|
98
|
+
const valueBlob = record.value?.blob;
|
|
99
|
+
if (!indexMac || !valueBlob)
|
|
100
|
+
continue;
|
|
101
|
+
const operation = operationCode === proto.SyncdMutation.SyncdOperation.REMOVE
|
|
102
|
+
? 'remove'
|
|
103
|
+
: 'set';
|
|
104
|
+
const decrypted = await this.appStateCrypto.decryptMutation({
|
|
105
|
+
operation,
|
|
106
|
+
keyId,
|
|
107
|
+
keyData,
|
|
108
|
+
indexMac,
|
|
109
|
+
valueBlob
|
|
110
|
+
});
|
|
111
|
+
let action;
|
|
112
|
+
try {
|
|
113
|
+
const parsed = JSON.parse(decrypted.index);
|
|
114
|
+
if (Array.isArray(parsed) && typeof parsed[0] === 'string') {
|
|
115
|
+
action = parsed[0];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// Ignore malformed index payloads; mutation capture still proceeds.
|
|
120
|
+
}
|
|
121
|
+
const captured = {
|
|
122
|
+
collection: collectionName,
|
|
123
|
+
operation,
|
|
124
|
+
index: decrypted.index,
|
|
125
|
+
action,
|
|
126
|
+
version: decrypted.version,
|
|
127
|
+
value: decrypted.value,
|
|
128
|
+
patchVersion
|
|
129
|
+
};
|
|
130
|
+
for (const listener of this.outboundMutationListeners) {
|
|
131
|
+
try {
|
|
132
|
+
listener(captured);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// Listener failures are best-effort.
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// Ignore malformed/undecryptable patches.
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Runs the server side of the QR pairing flow. */
|
|
2
|
+
import { buildAdvSignedDeviceIdentity, generateFakePrimaryDevice } from '../protocol/auth/fake-primary-device.js';
|
|
3
|
+
import { buildPairDeviceIq, buildPairSuccessIq } from '../protocol/auth/pair-device.js';
|
|
4
|
+
import { randomBytesAsync } from '../transport/crypto.js';
|
|
5
|
+
export class FakePairingDriver {
|
|
6
|
+
constructor(options, deps) {
|
|
7
|
+
this.primary = null;
|
|
8
|
+
this.options = options;
|
|
9
|
+
this.deps = deps;
|
|
10
|
+
}
|
|
11
|
+
async run() {
|
|
12
|
+
this.primary = this.options.primary ?? (await generateFakePrimaryDevice());
|
|
13
|
+
const refs = await Promise.all(Array.from({ length: 6 }, () => randomBytesAsync(16)));
|
|
14
|
+
const pairDeviceIq = buildPairDeviceIq({ refs });
|
|
15
|
+
await this.deps.pipeline.sendStanza(pairDeviceIq);
|
|
16
|
+
const waitForAck = this.deps.waitForPairDeviceAck?.(pairDeviceIq.attrs.id) ?? Promise.resolve();
|
|
17
|
+
const [material] = await Promise.all([this.deps.companionMaterialResolver(), waitForAck]);
|
|
18
|
+
const { deviceIdentityBytes } = await buildAdvSignedDeviceIdentity({
|
|
19
|
+
primary: this.primary,
|
|
20
|
+
advSecretKey: material.advSecretKey,
|
|
21
|
+
companionIdentityPublicKey: material.identityPublicKey,
|
|
22
|
+
companionDeviceId: this.options.companionDeviceId ?? 1
|
|
23
|
+
});
|
|
24
|
+
await this.deps.pipeline.sendStanza(buildPairSuccessIq({
|
|
25
|
+
deviceJid: this.options.deviceJid,
|
|
26
|
+
deviceLid: this.options.deviceLid,
|
|
27
|
+
platform: this.options.platform ?? 'IOS',
|
|
28
|
+
deviceIdentityBytes
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
}
|