@hbmodsofc/baileys 1.7.8 → 2.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/LICENSE +1 -1
- package/WAProto/index.js +157084 -24729
- package/lib/Defaults/baileys-version.json +3 -0
- package/lib/Defaults/index.d.ts +8 -12
- package/lib/Defaults/index.js +124 -90
- package/lib/Defaults/phonenumber-mcc.json +223 -0
- package/lib/Signal/Group/group_cipher.d.ts +1 -0
- package/lib/Signal/Group/group_cipher.js +39 -28
- package/lib/Signal/Group/queue-job.d.ts +1 -0
- package/lib/Signal/Group/queue-job.js +57 -0
- package/lib/Signal/Group/sender-chain-key.d.ts +1 -1
- package/lib/Signal/Group/sender-chain-key.js +2 -9
- package/lib/Signal/Group/sender-key-distribution-message.js +3 -3
- package/lib/Signal/Group/sender-key-message.js +3 -3
- package/lib/Signal/Group/sender-key-state.d.ts +4 -4
- package/lib/Signal/Group/sender-key-state.js +16 -47
- package/lib/Signal/libsignal.d.ts +3 -7
- package/lib/Signal/libsignal.js +39 -224
- package/lib/Socket/Client/{types.d.ts → abstract-socket-client.d.ts} +3 -1
- package/lib/Socket/Client/index.d.ts +3 -2
- package/lib/Socket/Client/index.js +3 -2
- package/lib/Socket/Client/mobile-socket-client.d.ts +13 -0
- package/lib/Socket/Client/mobile-socket-client.js +65 -0
- package/lib/Socket/Client/{websocket.d.ts → web-socket-client.d.ts} +1 -1
- package/lib/Socket/Client/{websocket.js → web-socket-client.js} +16 -10
- package/lib/Socket/business.d.ts +78 -94
- package/lib/Socket/business.js +11 -130
- package/lib/Socket/chats.d.ts +233 -63
- package/lib/Socket/chats.js +184 -234
- package/lib/Socket/groups.d.ts +41 -62
- package/lib/Socket/groups.js +64 -76
- package/lib/Socket/hbmods.d.ts +253 -0
- package/lib/Socket/hbmods.js +1 -0
- package/lib/Socket/index.d.ts +83 -129
- package/lib/Socket/index.js +6 -13
- package/lib/Socket/messages-recv.d.ts +48 -59
- package/lib/Socket/messages-recv.js +371 -516
- package/lib/Socket/messages-send.d.ts +67 -86
- package/lib/Socket/messages-send.js +1 -1091
- package/lib/Socket/newsletter.d.ts +64 -76
- package/lib/Socket/newsletter.js +1 -184
- package/lib/Socket/registration.d.ts +267 -0
- package/lib/Socket/registration.js +166 -0
- package/lib/Socket/socket.d.ts +13 -19
- package/lib/Socket/socket.js +1 -805
- package/lib/Socket/usync.d.ts +36 -0
- package/lib/Socket/usync.js +70 -0
- package/lib/Types/Auth.d.ts +10 -4
- package/lib/Types/Call.d.ts +1 -1
- package/lib/Types/Chat.d.ts +9 -29
- package/lib/Types/Chat.js +1 -7
- package/lib/Types/Contact.d.ts +1 -5
- package/lib/Types/Events.d.ts +14 -55
- package/lib/Types/GroupMetadata.d.ts +5 -15
- package/lib/Types/Label.d.ts +0 -11
- package/lib/Types/Label.js +1 -1
- package/lib/Types/LabelAssociation.js +1 -1
- package/lib/Types/Message.d.ts +49 -75
- package/lib/Types/Message.js +7 -10
- package/lib/Types/Newsletter.d.ts +98 -129
- package/lib/Types/Newsletter.js +38 -33
- package/lib/Types/Product.d.ts +1 -1
- package/lib/Types/Signal.d.ts +1 -29
- package/lib/Types/Socket.d.ts +22 -48
- package/lib/Types/State.d.ts +2 -13
- package/lib/Types/State.js +0 -12
- package/lib/Types/USync.d.ts +1 -1
- package/lib/Types/index.d.ts +3 -10
- package/lib/Types/index.js +2 -2
- package/lib/Utils/auth-utils.d.ts +3 -3
- package/lib/Utils/auth-utils.js +102 -378
- package/lib/Utils/baileys-event-stream.js +1 -1
- package/lib/Utils/business.d.ts +2 -2
- package/lib/Utils/business.js +13 -19
- package/lib/Utils/chat-utils.d.ts +22 -21
- package/lib/Utils/chat-utils.js +154 -201
- package/lib/Utils/crypto.d.ts +19 -18
- package/lib/Utils/crypto.js +37 -78
- package/lib/Utils/decode-wa-message.d.ts +7 -34
- package/lib/Utils/decode-wa-message.js +66 -138
- package/lib/Utils/event-buffer.d.ts +8 -6
- package/lib/Utils/event-buffer.js +43 -81
- package/lib/Utils/generics.d.ts +27 -27
- package/lib/Utils/generics.js +133 -128
- package/lib/Utils/history.d.ts +5 -9
- package/lib/Utils/history.js +23 -17
- package/lib/Utils/index.d.ts +0 -2
- package/lib/Utils/index.js +0 -2
- package/lib/Utils/link-preview.d.ts +4 -4
- package/lib/Utils/link-preview.js +12 -40
- package/lib/Utils/logger.d.ts +3 -11
- package/lib/Utils/lt-hash.d.ts +8 -8
- package/lib/Utils/lt-hash.js +24 -23
- package/lib/Utils/make-mutex.d.ts +2 -2
- package/lib/Utils/make-mutex.js +2 -3
- package/lib/Utils/messages-media.d.ts +41 -37
- package/lib/Utils/messages-media.js +368 -252
- package/lib/Utils/messages.d.ts +15 -13
- package/lib/Utils/messages.js +261 -274
- package/lib/Utils/noise-handler.d.ts +15 -13
- package/lib/Utils/noise-handler.js +26 -20
- package/lib/Utils/process-message.d.ts +8 -9
- package/lib/Utils/process-message.js +93 -157
- package/lib/Utils/signal.d.ts +5 -6
- package/lib/Utils/signal.js +29 -37
- package/lib/Utils/use-multi-file-auth-state.d.ts +2 -1
- package/lib/Utils/use-multi-file-auth-state.js +7 -12
- package/lib/Utils/validate-connection.d.ts +6 -5
- package/lib/Utils/validate-connection.js +97 -39
- package/lib/WABinary/constants.d.ts +27 -24
- package/lib/WABinary/constants.js +13 -1276
- package/lib/WABinary/decode.d.ts +4 -3
- package/lib/WABinary/decode.js +14 -28
- package/lib/WABinary/encode.d.ts +2 -1
- package/lib/WABinary/encode.js +147 -134
- package/lib/WABinary/generic-utils.d.ts +7 -4
- package/lib/WABinary/generic-utils.js +125 -40
- package/lib/WABinary/jid-utils.d.ts +8 -13
- package/lib/WABinary/jid-utils.js +16 -27
- package/lib/WAM/BinaryInfo.d.ts +11 -2
- package/lib/WAM/constants.d.ts +2 -3
- package/lib/WAM/constants.js +2359 -2252
- package/lib/WAM/encode.d.ts +2 -1
- package/lib/WAM/encode.js +11 -8
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +2 -2
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +4 -3
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +2 -2
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +5 -5
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +2 -2
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +5 -5
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +2 -2
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +6 -5
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +2 -2
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +1 -1
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +3 -4
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +3 -11
- package/lib/WAUSync/USyncQuery.d.ts +2 -2
- package/lib/WAUSync/USyncQuery.js +15 -19
- package/lib/WAUSync/USyncUser.d.ts +5 -5
- package/lib/WAUSync/index.d.ts +1 -1
- package/lib/WAUSync/index.js +1 -1
- package/package.json +102 -104
- package/lib/Signal/lid-mapping.d.ts +0 -26
- package/lib/Signal/lid-mapping.js +0 -146
- package/lib/Socket/communities.d.ts +0 -232
- package/lib/Socket/communities.js +0 -402
- package/lib/Socket/mex.d.ts +0 -2
- package/lib/Socket/mex.js +0 -45
- package/lib/Types/Bussines.d.ts +0 -24
- package/lib/Types/Bussines.js +0 -2
- package/lib/Utils/lidToJid-test.d.ts +0 -11
- package/lib/Utils/lidToJid-test.js +0 -27
- package/lib/Utils/message-retry-manager.d.ts +0 -81
- package/lib/Utils/message-retry-manager.js +0 -152
- /package/lib/Socket/Client/{types.js → abstract-socket-client.js} +0 -0
|
@@ -4,7 +4,7 @@ export declare class SenderChainKey {
|
|
|
4
4
|
private readonly CHAIN_KEY_SEED;
|
|
5
5
|
private readonly iteration;
|
|
6
6
|
private readonly chainKey;
|
|
7
|
-
constructor(iteration: number, chainKey:
|
|
7
|
+
constructor(iteration: number, chainKey: any);
|
|
8
8
|
getIteration(): number;
|
|
9
9
|
getSenderMessageKey(): SenderMessageKey;
|
|
10
10
|
getNext(): SenderChainKey;
|
|
@@ -8,18 +8,11 @@ class SenderChainKey {
|
|
|
8
8
|
this.MESSAGE_KEY_SEED = Buffer.from([0x01]);
|
|
9
9
|
this.CHAIN_KEY_SEED = Buffer.from([0x02]);
|
|
10
10
|
this.iteration = iteration;
|
|
11
|
-
if (Buffer
|
|
11
|
+
if (chainKey instanceof Buffer) {
|
|
12
12
|
this.chainKey = chainKey;
|
|
13
13
|
}
|
|
14
|
-
else if (chainKey instanceof Uint8Array) {
|
|
15
|
-
this.chainKey = Buffer.from(chainKey);
|
|
16
|
-
}
|
|
17
|
-
else if (chainKey && typeof chainKey === 'object') {
|
|
18
|
-
// backported from @MartinSchere (#1741)
|
|
19
|
-
this.chainKey = Buffer.from(Object.values(chainKey)); // temp fix // backported from @MartinSchere (#1741)
|
|
20
|
-
}
|
|
21
14
|
else {
|
|
22
|
-
this.chainKey = Buffer.
|
|
15
|
+
this.chainKey = Buffer.from(chainKey || []);
|
|
23
16
|
}
|
|
24
17
|
}
|
|
25
18
|
getIteration() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SenderKeyDistributionMessage = void 0;
|
|
4
|
-
const
|
|
4
|
+
const WAProto_1 = require("../../../WAProto");
|
|
5
5
|
const ciphertext_message_1 = require("./ciphertext-message");
|
|
6
6
|
class SenderKeyDistributionMessage extends ciphertext_message_1.CiphertextMessage {
|
|
7
7
|
constructor(id, iteration, chainKey, signatureKey, serialized) {
|
|
@@ -9,7 +9,7 @@ class SenderKeyDistributionMessage extends ciphertext_message_1.CiphertextMessag
|
|
|
9
9
|
if (serialized) {
|
|
10
10
|
try {
|
|
11
11
|
const message = serialized.slice(1);
|
|
12
|
-
const distributionMessage =
|
|
12
|
+
const distributionMessage = WAProto_1.proto.SenderKeyDistributionMessage.decode(message).toJSON();
|
|
13
13
|
this.serialized = serialized;
|
|
14
14
|
this.id = distributionMessage.id;
|
|
15
15
|
this.iteration = distributionMessage.iteration;
|
|
@@ -32,7 +32,7 @@ class SenderKeyDistributionMessage extends ciphertext_message_1.CiphertextMessag
|
|
|
32
32
|
this.iteration = iteration;
|
|
33
33
|
this.chainKey = chainKey;
|
|
34
34
|
this.signatureKey = signatureKey;
|
|
35
|
-
const message =
|
|
35
|
+
const message = WAProto_1.proto.SenderKeyDistributionMessage.encode(WAProto_1.proto.SenderKeyDistributionMessage.create({
|
|
36
36
|
id,
|
|
37
37
|
iteration,
|
|
38
38
|
chainKey,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SenderKeyMessage = void 0;
|
|
4
4
|
const curve_1 = require("libsignal/src/curve");
|
|
5
|
-
const
|
|
5
|
+
const WAProto_1 = require("../../../WAProto");
|
|
6
6
|
const ciphertext_message_1 = require("./ciphertext-message");
|
|
7
7
|
class SenderKeyMessage extends ciphertext_message_1.CiphertextMessage {
|
|
8
8
|
constructor(keyId, iteration, ciphertext, signatureKey, serialized) {
|
|
@@ -12,7 +12,7 @@ class SenderKeyMessage extends ciphertext_message_1.CiphertextMessage {
|
|
|
12
12
|
const version = serialized[0];
|
|
13
13
|
const message = serialized.slice(1, serialized.length - this.SIGNATURE_LENGTH);
|
|
14
14
|
const signature = serialized.slice(-1 * this.SIGNATURE_LENGTH);
|
|
15
|
-
const senderKeyMessage =
|
|
15
|
+
const senderKeyMessage = WAProto_1.proto.SenderKeyMessage.decode(message).toJSON();
|
|
16
16
|
this.serialized = serialized;
|
|
17
17
|
this.messageVersion = (version & 0xff) >> 4;
|
|
18
18
|
this.keyId = senderKeyMessage.id;
|
|
@@ -26,7 +26,7 @@ class SenderKeyMessage extends ciphertext_message_1.CiphertextMessage {
|
|
|
26
26
|
else {
|
|
27
27
|
const version = (((this.CURRENT_VERSION << 4) | this.CURRENT_VERSION) & 0xff) % 256;
|
|
28
28
|
const ciphertextBuffer = Buffer.from(ciphertext);
|
|
29
|
-
const message =
|
|
29
|
+
const message = WAProto_1.proto.SenderKeyMessage.encode(WAProto_1.proto.SenderKeyMessage.create({
|
|
30
30
|
id: keyId,
|
|
31
31
|
iteration: iteration,
|
|
32
32
|
ciphertext: ciphertextBuffer
|
|
@@ -21,10 +21,10 @@ interface SenderKeyStateStructure {
|
|
|
21
21
|
export declare class SenderKeyState {
|
|
22
22
|
private readonly MAX_MESSAGE_KEYS;
|
|
23
23
|
private readonly senderKeyStateStructure;
|
|
24
|
-
constructor(id?: number | null, iteration?: number | null, chainKey?: Uint8Array | null
|
|
25
|
-
public: Uint8Array
|
|
26
|
-
private: Uint8Array
|
|
27
|
-
} | null, signatureKeyPublic?: Uint8Array |
|
|
24
|
+
constructor(id?: number | null, iteration?: number | null, chainKey?: Uint8Array | null, signatureKeyPair?: {
|
|
25
|
+
public: Uint8Array;
|
|
26
|
+
private: Uint8Array;
|
|
27
|
+
} | null, signatureKeyPublic?: Uint8Array | null, signatureKeyPrivate?: Uint8Array | null, senderKeyStateStructure?: SenderKeyStateStructure | null);
|
|
28
28
|
getKeyId(): number;
|
|
29
29
|
getSenderChainKey(): SenderChainKey;
|
|
30
30
|
setSenderChainKey(chainKey: SenderChainKey): void;
|
|
@@ -6,22 +6,8 @@ const sender_message_key_1 = require("./sender-message-key");
|
|
|
6
6
|
class SenderKeyState {
|
|
7
7
|
constructor(id, iteration, chainKey, signatureKeyPair, signatureKeyPublic, signatureKeyPrivate, senderKeyStateStructure) {
|
|
8
8
|
this.MAX_MESSAGE_KEYS = 2000;
|
|
9
|
-
const toBuffer = (val) => {
|
|
10
|
-
if (!val)
|
|
11
|
-
return Buffer.alloc(0);
|
|
12
|
-
if (typeof val === 'string')
|
|
13
|
-
return Buffer.from(val, 'base64');
|
|
14
|
-
if (val instanceof Uint8Array || Array.isArray(val))
|
|
15
|
-
return Buffer.from(val);
|
|
16
|
-
return Buffer.alloc(0);
|
|
17
|
-
};
|
|
18
9
|
if (senderKeyStateStructure) {
|
|
19
|
-
this.senderKeyStateStructure =
|
|
20
|
-
...senderKeyStateStructure,
|
|
21
|
-
senderMessageKeys: Array.isArray(senderKeyStateStructure.senderMessageKeys)
|
|
22
|
-
? senderKeyStateStructure.senderMessageKeys
|
|
23
|
-
: []
|
|
24
|
-
};
|
|
10
|
+
this.senderKeyStateStructure = senderKeyStateStructure;
|
|
25
11
|
}
|
|
26
12
|
else {
|
|
27
13
|
if (signatureKeyPair) {
|
|
@@ -31,12 +17,17 @@ class SenderKeyState {
|
|
|
31
17
|
chainKey = typeof chainKey === 'string' ? Buffer.from(chainKey, 'base64') : chainKey;
|
|
32
18
|
const senderChainKeyStructure = {
|
|
33
19
|
iteration: iteration || 0,
|
|
34
|
-
seed: chainKey
|
|
20
|
+
seed: chainKey || Buffer.alloc(0)
|
|
35
21
|
};
|
|
36
22
|
const signingKeyStructure = {
|
|
37
|
-
public:
|
|
38
|
-
|
|
23
|
+
public: typeof signatureKeyPublic === 'string'
|
|
24
|
+
? Buffer.from(signatureKeyPublic, 'base64')
|
|
25
|
+
: signatureKeyPublic || Buffer.alloc(0)
|
|
39
26
|
};
|
|
27
|
+
if (signatureKeyPrivate) {
|
|
28
|
+
signingKeyStructure.private =
|
|
29
|
+
typeof signatureKeyPrivate === 'string' ? Buffer.from(signatureKeyPrivate, 'base64') : signatureKeyPrivate;
|
|
30
|
+
}
|
|
40
31
|
this.senderKeyStateStructure = {
|
|
41
32
|
senderKeyId: id || 0,
|
|
42
33
|
senderChainKey: senderChainKeyStructure,
|
|
@@ -58,45 +49,23 @@ class SenderKeyState {
|
|
|
58
49
|
};
|
|
59
50
|
}
|
|
60
51
|
getSigningKeyPublic() {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (key instanceof Uint8Array) {
|
|
65
|
-
key = Buffer.from(key);
|
|
66
|
-
}
|
|
67
|
-
else if (typeof key === 'string') {
|
|
68
|
-
key = Buffer.from(key, 'base64');
|
|
69
|
-
}
|
|
70
|
-
else if (key && typeof key === 'object') {
|
|
71
|
-
return Buffer.from(Object.values(key)); // temp fix // inspired by @MartinSchere 's #1741
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
key = Buffer.from(key || []);
|
|
75
|
-
}
|
|
52
|
+
const publicKey = this.senderKeyStateStructure.senderSigningKey.public;
|
|
53
|
+
if (publicKey instanceof Buffer) {
|
|
54
|
+
return publicKey;
|
|
76
55
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const fixed = Buffer.alloc(33);
|
|
80
|
-
fixed[0] = 0x05;
|
|
81
|
-
publicKey.copy(fixed, 1);
|
|
82
|
-
return fixed;
|
|
56
|
+
else if (typeof publicKey === 'string') {
|
|
57
|
+
return Buffer.from(publicKey, 'base64');
|
|
83
58
|
}
|
|
84
|
-
return publicKey;
|
|
59
|
+
return Buffer.from(publicKey || []);
|
|
85
60
|
}
|
|
86
61
|
getSigningKeyPrivate() {
|
|
87
62
|
const privateKey = this.senderKeyStateStructure.senderSigningKey.private;
|
|
88
63
|
if (!privateKey) {
|
|
89
64
|
return undefined;
|
|
90
65
|
}
|
|
91
|
-
if (Buffer
|
|
66
|
+
if (privateKey instanceof Buffer) {
|
|
92
67
|
return privateKey;
|
|
93
68
|
}
|
|
94
|
-
else if (privateKey instanceof Uint8Array) {
|
|
95
|
-
return Buffer.from(privateKey);
|
|
96
|
-
}
|
|
97
|
-
else if (privateKey && typeof privateKey === 'object') {
|
|
98
|
-
return Buffer.from(Object.values(privateKey)); // temp fix // inspired by @MartinSchere 's #1741
|
|
99
|
-
}
|
|
100
69
|
else if (typeof privateKey === 'string') {
|
|
101
70
|
return Buffer.from(privateKey, 'base64');
|
|
102
71
|
}
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
export declare function makeLibSignalRepository(auth: SignalAuthState
|
|
4
|
-
jid: string;
|
|
5
|
-
exists: boolean;
|
|
6
|
-
lid: string;
|
|
7
|
-
}[] | undefined>): SignalRepositoryWithLIDStore;
|
|
1
|
+
import { SignalAuthState } from '../Types';
|
|
2
|
+
import { SignalRepository } from '../Types/Signal';
|
|
3
|
+
export declare function makeLibSignalRepository(auth: SignalAuthState): SignalRepository;
|
package/lib/Signal/libsignal.js
CHANGED
|
@@ -34,34 +34,19 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.makeLibSignalRepository = makeLibSignalRepository;
|
|
37
|
-
/* @ts-ignore */
|
|
38
37
|
const libsignal = __importStar(require("libsignal"));
|
|
39
38
|
const Utils_1 = require("../Utils");
|
|
40
39
|
const WABinary_1 = require("../WABinary");
|
|
41
40
|
const sender_key_name_1 = require("./Group/sender-key-name");
|
|
42
41
|
const sender_key_record_1 = require("./Group/sender-key-record");
|
|
43
42
|
const Group_1 = require("./Group");
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const storage = signalStorage(auth, lidMapping);
|
|
48
|
-
const parsedKeys = auth.keys;
|
|
49
|
-
function isLikelySyncMessage(addr) {
|
|
50
|
-
const key = addr.toString();
|
|
51
|
-
// Only bypass for WhatsApp system addresses, not regular user contacts
|
|
52
|
-
// Be very specific about sync service patterns
|
|
53
|
-
return (key.includes('@lid.whatsapp.net') || // WhatsApp system messages
|
|
54
|
-
key.includes('@broadcast') || // Broadcast messages
|
|
55
|
-
key.includes('@newsletter'));
|
|
56
|
-
}
|
|
57
|
-
const repository = {
|
|
43
|
+
function makeLibSignalRepository(auth) {
|
|
44
|
+
const storage = signalStorage(auth);
|
|
45
|
+
return {
|
|
58
46
|
decryptGroupMessage({ group, authorJid, msg }) {
|
|
59
47
|
const senderName = jidToSignalSenderKeyName(group, authorJid);
|
|
60
48
|
const cipher = new Group_1.GroupCipher(storage, senderName);
|
|
61
|
-
|
|
62
|
-
return parsedKeys.transaction(async () => {
|
|
63
|
-
return cipher.decrypt(msg);
|
|
64
|
-
}, group);
|
|
49
|
+
return cipher.decrypt(msg);
|
|
65
50
|
},
|
|
66
51
|
async processSenderKeyDistributionMessage({ item, authorJid }) {
|
|
67
52
|
const builder = new Group_1.GroupSessionBuilder(storage);
|
|
@@ -75,240 +60,70 @@ function makeLibSignalRepository(auth, onWhatsAppFunc) {
|
|
|
75
60
|
if (!senderKey) {
|
|
76
61
|
await storage.storeSenderKey(senderName, new sender_key_record_1.SenderKeyRecord());
|
|
77
62
|
}
|
|
78
|
-
|
|
79
|
-
const { [senderNameStr]: senderKey } = await auth.keys.get('sender-key', [senderNameStr]);
|
|
80
|
-
if (!senderKey) {
|
|
81
|
-
await storage.storeSenderKey(senderName, new sender_key_record_1.SenderKeyRecord());
|
|
82
|
-
}
|
|
83
|
-
await builder.process(senderName, senderMsg);
|
|
84
|
-
}, item.groupId);
|
|
63
|
+
await builder.process(senderName, senderMsg);
|
|
85
64
|
},
|
|
86
65
|
async decryptMessage({ jid, type, ciphertext }) {
|
|
87
66
|
const addr = jidToSignalProtocolAddress(jid);
|
|
88
67
|
const session = new libsignal.SessionCipher(storage, addr);
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return result;
|
|
100
|
-
}
|
|
101
|
-
if (isLikelySyncMessage(addr)) {
|
|
102
|
-
// If it's a sync message, we can skip the transaction
|
|
103
|
-
// as it is likely to be a system message that doesn't require strict atomicity
|
|
104
|
-
return await doDecrypt();
|
|
68
|
+
let result;
|
|
69
|
+
switch (type) {
|
|
70
|
+
case 'pkmsg':
|
|
71
|
+
result = await session.decryptPreKeyWhisperMessage(ciphertext);
|
|
72
|
+
break;
|
|
73
|
+
case 'msg':
|
|
74
|
+
result = await session.decryptWhisperMessage(ciphertext);
|
|
75
|
+
break;
|
|
76
|
+
default:
|
|
77
|
+
throw new Error(`Unknown message type: ${type}`);
|
|
105
78
|
}
|
|
106
|
-
|
|
107
|
-
// For regular messages, we use a transaction to ensure atomicity
|
|
108
|
-
return parsedKeys.transaction(async () => {
|
|
109
|
-
return await doDecrypt();
|
|
110
|
-
}, jid);
|
|
79
|
+
return result;
|
|
111
80
|
},
|
|
112
81
|
async encryptMessage({ jid, data }) {
|
|
113
|
-
|
|
114
|
-
let encryptionJid = jid;
|
|
115
|
-
// Check for LID mapping and use it if session exists
|
|
116
|
-
if (jid.includes('@s.whatsapp.net')) {
|
|
117
|
-
const lidForPN = await lidMapping.getLIDForPN(jid);
|
|
118
|
-
if (lidForPN?.includes('@lid')) {
|
|
119
|
-
const lidAddr = jidToSignalProtocolAddress(lidForPN);
|
|
120
|
-
const { [lidAddr.toString()]: lidSession } = await auth.keys.get('session', [lidAddr.toString()]);
|
|
121
|
-
if (lidSession) {
|
|
122
|
-
// LID session exists, use it
|
|
123
|
-
encryptionJid = lidForPN;
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
// Try to migrate if PN session exists
|
|
127
|
-
const pnAddr = jidToSignalProtocolAddress(jid);
|
|
128
|
-
const { [pnAddr.toString()]: pnSession } = await auth.keys.get('session', [pnAddr.toString()]);
|
|
129
|
-
if (pnSession) {
|
|
130
|
-
// Migrate PN to LID
|
|
131
|
-
await repository.migrateSession([jid], lidForPN);
|
|
132
|
-
encryptionJid = lidForPN;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
const addr = jidToSignalProtocolAddress(encryptionJid);
|
|
82
|
+
const addr = jidToSignalProtocolAddress(jid);
|
|
138
83
|
const cipher = new libsignal.SessionCipher(storage, addr);
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const type = sigType === 3 ? 'pkmsg' : 'msg';
|
|
143
|
-
return { type, ciphertext: Buffer.from(body, 'binary') };
|
|
144
|
-
}, jid);
|
|
84
|
+
const { type: sigType, body } = await cipher.encrypt(data);
|
|
85
|
+
const type = sigType === 3 ? 'pkmsg' : 'msg';
|
|
86
|
+
return { type, ciphertext: Buffer.from(body, 'binary') };
|
|
145
87
|
},
|
|
146
88
|
async encryptGroupMessage({ group, meId, data }) {
|
|
147
89
|
const senderName = jidToSignalSenderKeyName(group, meId);
|
|
148
90
|
const builder = new Group_1.GroupSessionBuilder(storage);
|
|
149
91
|
const senderNameStr = senderName.toString();
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
};
|
|
162
|
-
}, group);
|
|
92
|
+
const { [senderNameStr]: senderKey } = await auth.keys.get('sender-key', [senderNameStr]);
|
|
93
|
+
if (!senderKey) {
|
|
94
|
+
await storage.storeSenderKey(senderName, new sender_key_record_1.SenderKeyRecord());
|
|
95
|
+
}
|
|
96
|
+
const senderKeyDistributionMessage = await builder.create(senderName);
|
|
97
|
+
const session = new Group_1.GroupCipher(storage, senderName);
|
|
98
|
+
const ciphertext = await session.encrypt(data);
|
|
99
|
+
return {
|
|
100
|
+
ciphertext,
|
|
101
|
+
senderKeyDistributionMessage: senderKeyDistributionMessage.serialize()
|
|
102
|
+
};
|
|
163
103
|
},
|
|
164
104
|
async injectE2ESession({ jid, session }) {
|
|
165
105
|
const cipher = new libsignal.SessionBuilder(storage, jidToSignalProtocolAddress(jid));
|
|
166
|
-
|
|
167
|
-
await cipher.initOutgoing(session);
|
|
168
|
-
}, jid);
|
|
106
|
+
await cipher.initOutgoing(session);
|
|
169
107
|
},
|
|
170
108
|
jidToSignalProtocolAddress(jid) {
|
|
171
109
|
return jidToSignalProtocolAddress(jid).toString();
|
|
172
|
-
},
|
|
173
|
-
// Optimized direct access to LID mapping store
|
|
174
|
-
lidMapping,
|
|
175
|
-
async validateSession(jid) {
|
|
176
|
-
try {
|
|
177
|
-
const addr = jidToSignalProtocolAddress(jid);
|
|
178
|
-
const session = await storage.loadSession(addr.toString());
|
|
179
|
-
if (!session) {
|
|
180
|
-
return { exists: false, reason: 'no session' };
|
|
181
|
-
}
|
|
182
|
-
if (!session.haveOpenSession()) {
|
|
183
|
-
return { exists: false, reason: 'no open session' };
|
|
184
|
-
}
|
|
185
|
-
return { exists: true };
|
|
186
|
-
}
|
|
187
|
-
catch (error) {
|
|
188
|
-
return { exists: false, reason: 'validation error' };
|
|
189
|
-
}
|
|
190
|
-
},
|
|
191
|
-
async deleteSession(jids) {
|
|
192
|
-
if (!jids.length)
|
|
193
|
-
return;
|
|
194
|
-
// Convert JIDs to signal addresses and prepare for bulk deletion
|
|
195
|
-
const sessionUpdates = {};
|
|
196
|
-
jids.forEach(jid => {
|
|
197
|
-
const addr = jidToSignalProtocolAddress(jid);
|
|
198
|
-
sessionUpdates[addr.toString()] = null;
|
|
199
|
-
});
|
|
200
|
-
// Single transaction for all deletions
|
|
201
|
-
return parsedKeys.transaction(async () => {
|
|
202
|
-
await auth.keys.set({ session: sessionUpdates });
|
|
203
|
-
}, `delete-${jids.length}-sessions`);
|
|
204
|
-
},
|
|
205
|
-
async migrateSession(fromJids, toJid) {
|
|
206
|
-
if (!fromJids.length || !toJid.includes('@lid'))
|
|
207
|
-
return { migrated: 0, skipped: 0, total: 0 };
|
|
208
|
-
// Filter valid PN JIDs
|
|
209
|
-
const validJids = fromJids.filter(jid => jid.includes('@s.whatsapp.net'));
|
|
210
|
-
if (!validJids.length)
|
|
211
|
-
return { migrated: 0, skipped: 0, total: fromJids.length };
|
|
212
|
-
// Single optimized transaction for all migrations
|
|
213
|
-
return parsedKeys.transaction(async () => {
|
|
214
|
-
// 1. Batch store all LID mappings
|
|
215
|
-
const mappings = validJids.map(jid => ({
|
|
216
|
-
lid: (0, WABinary_1.transferDevice)(jid, toJid),
|
|
217
|
-
pn: jid
|
|
218
|
-
}));
|
|
219
|
-
await lidMapping.storeLIDPNMappings(mappings);
|
|
220
|
-
// 2. Prepare migration operations
|
|
221
|
-
const migrationOps = validJids.map(jid => {
|
|
222
|
-
const lidWithDevice = (0, WABinary_1.transferDevice)(jid, toJid);
|
|
223
|
-
const fromDecoded = (0, WABinary_1.jidDecode)(jid);
|
|
224
|
-
const toDecoded = (0, WABinary_1.jidDecode)(lidWithDevice);
|
|
225
|
-
return {
|
|
226
|
-
fromJid: jid,
|
|
227
|
-
toJid: lidWithDevice,
|
|
228
|
-
pnUser: fromDecoded.user,
|
|
229
|
-
lidUser: toDecoded.user,
|
|
230
|
-
deviceId: fromDecoded.device || 0,
|
|
231
|
-
fromAddr: jidToSignalProtocolAddress(jid),
|
|
232
|
-
toAddr: jidToSignalProtocolAddress(lidWithDevice)
|
|
233
|
-
};
|
|
234
|
-
});
|
|
235
|
-
// 3. Batch check which LID sessions already exist
|
|
236
|
-
const lidAddrs = migrationOps.map(op => op.toAddr.toString());
|
|
237
|
-
const existingSessions = await auth.keys.get('session', lidAddrs);
|
|
238
|
-
// 4. Filter out sessions that already have LID sessions
|
|
239
|
-
const opsToMigrate = migrationOps.filter(op => !existingSessions[op.toAddr.toString()]);
|
|
240
|
-
const skippedCount = migrationOps.length - opsToMigrate.length;
|
|
241
|
-
if (!opsToMigrate.length) {
|
|
242
|
-
return { migrated: 0, skipped: skippedCount, total: validJids.length };
|
|
243
|
-
}
|
|
244
|
-
// 5. Execute all migrations in parallel
|
|
245
|
-
await Promise.all(opsToMigrate.map(async (op) => {
|
|
246
|
-
const fromSession = await storage.loadSession(op.fromAddr.toString());
|
|
247
|
-
if (fromSession?.haveOpenSession()) {
|
|
248
|
-
// Copy session to LID address
|
|
249
|
-
const sessionBytes = fromSession.serialize();
|
|
250
|
-
const copiedSession = libsignal.SessionRecord.deserialize(sessionBytes);
|
|
251
|
-
await storage.storeSession(op.toAddr.toString(), copiedSession);
|
|
252
|
-
// Delete PN session
|
|
253
|
-
await auth.keys.set({ session: { [op.fromAddr.toString()]: null } });
|
|
254
|
-
}
|
|
255
|
-
}));
|
|
256
|
-
return { migrated: opsToMigrate.length, skipped: skippedCount, total: validJids.length };
|
|
257
|
-
}, `migrate-${validJids.length}-sessions-${(0, WABinary_1.jidDecode)(toJid)?.user}`);
|
|
258
|
-
},
|
|
259
|
-
async encryptMessageWithWire({ encryptionJid, wireJid, data }) {
|
|
260
|
-
const result = await repository.encryptMessage({ jid: encryptionJid, data });
|
|
261
|
-
return { ...result, wireJid };
|
|
262
110
|
}
|
|
263
111
|
};
|
|
264
|
-
return repository;
|
|
265
112
|
}
|
|
266
113
|
const jidToSignalProtocolAddress = (jid) => {
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
if (!user) {
|
|
270
|
-
throw new Error(`JID decoded but user is empty: "${jid}" -> user: "${user}", server: "${server}", device: ${device}`);
|
|
271
|
-
}
|
|
272
|
-
// LID addresses get _1 suffix for Signal protocol
|
|
273
|
-
const signalUser = server === 'lid' ? `${user}_1` : user;
|
|
274
|
-
const finalDevice = device || 0;
|
|
275
|
-
return new libsignal.ProtocolAddress(signalUser, finalDevice);
|
|
114
|
+
const { user, device } = (0, WABinary_1.jidDecode)(jid);
|
|
115
|
+
return new libsignal.ProtocolAddress(user, device || 0);
|
|
276
116
|
};
|
|
277
117
|
const jidToSignalSenderKeyName = (group, user) => {
|
|
278
118
|
return new sender_key_name_1.SenderKeyName(group, jidToSignalProtocolAddress(user));
|
|
279
119
|
};
|
|
280
|
-
function signalStorage({ creds, keys }
|
|
120
|
+
function signalStorage({ creds, keys }) {
|
|
281
121
|
return {
|
|
282
122
|
loadSession: async (id) => {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
if (id.includes('.') && !id.includes('_1')) {
|
|
287
|
-
// This is a PN signal address format (e.g., "1234567890.0")
|
|
288
|
-
// Convert back to JID to check for LID mapping
|
|
289
|
-
const parts = id.split('.');
|
|
290
|
-
const device = parts[1] || '0';
|
|
291
|
-
const pnJid = device === '0' ? `${parts[0]}@s.whatsapp.net` : `${parts[0]}:${device}@s.whatsapp.net`;
|
|
292
|
-
const lidForPN = await lidMapping.getLIDForPN(pnJid);
|
|
293
|
-
if (lidForPN?.includes('@lid')) {
|
|
294
|
-
const lidAddr = jidToSignalProtocolAddress(lidForPN);
|
|
295
|
-
const lidId = lidAddr.toString();
|
|
296
|
-
// Check if LID session exists
|
|
297
|
-
const { [lidId]: lidSession } = await keys.get('session', [lidId]);
|
|
298
|
-
if (lidSession) {
|
|
299
|
-
actualId = lidId;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
const { [actualId]: sess } = await keys.get('session', [actualId]);
|
|
304
|
-
if (sess) {
|
|
305
|
-
return libsignal.SessionRecord.deserialize(sess);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
catch (e) {
|
|
309
|
-
return null;
|
|
123
|
+
const { [id]: sess } = await keys.get('session', [id]);
|
|
124
|
+
if (sess) {
|
|
125
|
+
return libsignal.SessionRecord.deserialize(sess);
|
|
310
126
|
}
|
|
311
|
-
return null;
|
|
312
127
|
},
|
|
313
128
|
storeSession: async (id, session) => {
|
|
314
129
|
await keys.set({ session: { [id]: session.serialize() } });
|
|
@@ -352,7 +167,7 @@ function signalStorage({ creds, keys }, lidMapping) {
|
|
|
352
167
|
const { signedIdentityKey } = creds;
|
|
353
168
|
return {
|
|
354
169
|
privKey: Buffer.from(signedIdentityKey.private),
|
|
355
|
-
pubKey:
|
|
170
|
+
pubKey: (0, Utils_1.generateSignalPubKey)(signedIdentityKey.public)
|
|
356
171
|
};
|
|
357
172
|
}
|
|
358
173
|
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
1
3
|
import { EventEmitter } from 'events';
|
|
2
4
|
import { URL } from 'url';
|
|
3
|
-
import
|
|
5
|
+
import { SocketConfig } from '../../Types';
|
|
4
6
|
export declare abstract class AbstractSocketClient extends EventEmitter {
|
|
5
7
|
url: URL;
|
|
6
8
|
config: SocketConfig;
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
1
|
+
export * from './abstract-socket-client';
|
|
2
|
+
export * from './mobile-socket-client';
|
|
3
|
+
export * from './web-socket-client';
|
|
@@ -14,5 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./
|
|
18
|
-
__exportStar(require("./
|
|
17
|
+
__exportStar(require("./abstract-socket-client"), exports);
|
|
18
|
+
__exportStar(require("./mobile-socket-client"), exports);
|
|
19
|
+
__exportStar(require("./web-socket-client"), exports);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Socket } from 'net';
|
|
3
|
+
import { AbstractSocketClient } from './abstract-socket-client';
|
|
4
|
+
export declare class MobileSocketClient extends AbstractSocketClient {
|
|
5
|
+
protected socket: Socket | null;
|
|
6
|
+
get isOpen(): boolean;
|
|
7
|
+
get isClosed(): boolean;
|
|
8
|
+
get isClosing(): boolean;
|
|
9
|
+
get isConnecting(): boolean;
|
|
10
|
+
connect(): Promise<void>;
|
|
11
|
+
close(): Promise<void>;
|
|
12
|
+
send(str: string | Uint8Array, cb?: (err?: Error) => void): boolean;
|
|
13
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MobileSocketClient = void 0;
|
|
4
|
+
const net_1 = require("net");
|
|
5
|
+
const abstract_socket_client_1 = require("./abstract-socket-client");
|
|
6
|
+
class MobileSocketClient extends abstract_socket_client_1.AbstractSocketClient {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(...arguments);
|
|
9
|
+
this.socket = null;
|
|
10
|
+
}
|
|
11
|
+
get isOpen() {
|
|
12
|
+
var _a;
|
|
13
|
+
return ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.readyState) === 'open';
|
|
14
|
+
}
|
|
15
|
+
get isClosed() {
|
|
16
|
+
var _a;
|
|
17
|
+
return this.socket === null || ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.readyState) === 'closed';
|
|
18
|
+
}
|
|
19
|
+
get isClosing() {
|
|
20
|
+
var _a;
|
|
21
|
+
return this.socket === null || ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.readyState) === 'closed';
|
|
22
|
+
}
|
|
23
|
+
get isConnecting() {
|
|
24
|
+
var _a;
|
|
25
|
+
return ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.readyState) === 'opening';
|
|
26
|
+
}
|
|
27
|
+
async connect() {
|
|
28
|
+
var _a;
|
|
29
|
+
if (this.socket) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (this.config.agent) {
|
|
33
|
+
throw new Error('There are not support for proxy agent for mobile connection');
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
this.socket = (0, net_1.connect)({
|
|
37
|
+
host: this.url.hostname,
|
|
38
|
+
port: Number(this.url.port) || 443
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
this.socket.setMaxListeners(0);
|
|
42
|
+
const events = ['close', 'connect', 'data', 'drain', 'end', 'error', 'lookup', 'ready', 'timeout'];
|
|
43
|
+
for (const event of events) {
|
|
44
|
+
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.on(event, (...args) => this.emit(event, ...args));
|
|
45
|
+
}
|
|
46
|
+
this.socket.on('data', (...args) => this.emit('message', ...args));
|
|
47
|
+
this.socket.on('ready', (...args) => this.emit('open', ...args));
|
|
48
|
+
}
|
|
49
|
+
async close() {
|
|
50
|
+
if (!this.socket) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
return new Promise(resolve => {
|
|
54
|
+
this.socket.end(resolve);
|
|
55
|
+
this.socket = null;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
send(str, cb) {
|
|
59
|
+
if (this.socket === null) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
return this.socket.write(str, undefined, cb);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.MobileSocketClient = MobileSocketClient;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import WebSocket from 'ws';
|
|
2
|
-
import { AbstractSocketClient } from './
|
|
2
|
+
import { AbstractSocketClient } from './abstract-socket-client';
|
|
3
3
|
export declare class WebSocketClient extends AbstractSocketClient {
|
|
4
4
|
protected socket: WebSocket | null;
|
|
5
5
|
get isOpen(): boolean;
|