@pontalabs/baileys 1.0.6 → 1.0.8
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/README.md +839 -267
- package/WAProto/GenerateStatics.sh +4 -3
- package/WAProto/WAProto.proto +511 -1215
- package/WAProto/index.d.ts +55 -14017
- package/WAProto/index.js +29 -97689
- package/lib/Defaults/index.d.ts +74 -72
- package/lib/Defaults/index.js +108 -94
- package/lib/Signal/Group/ciphertext-message.d.ts +7 -8
- package/lib/Signal/Group/ciphertext-message.js +16 -9
- package/lib/Signal/Group/group-session-builder.d.ts +13 -11
- package/lib/Signal/Group/group-session-builder.js +61 -19
- package/lib/Signal/Group/group_cipher.d.ts +16 -14
- package/lib/Signal/Group/group_cipher.js +70 -41
- package/lib/Signal/Group/index.d.ts +11 -12
- package/lib/Signal/Group/index.js +61 -12
- package/lib/Signal/Group/keyhelper.d.ts +14 -9
- package/lib/Signal/Group/keyhelper.js +58 -10
- package/lib/Signal/Group/sender-chain-key.d.ts +13 -13
- package/lib/Signal/Group/sender-chain-key.js +34 -13
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -16
- package/lib/Signal/Group/sender-key-distribution-message.js +36 -28
- package/lib/Signal/Group/sender-key-message.d.ts +18 -18
- package/lib/Signal/Group/sender-key-message.js +45 -38
- package/lib/Signal/Group/sender-key-name.d.ts +15 -14
- package/lib/Signal/Group/sender-key-name.js +31 -20
- package/lib/Signal/Group/sender-key-record.d.ts +25 -24
- package/lib/Signal/Group/sender-key-record.js +35 -18
- package/lib/Signal/Group/sender-key-state.d.ts +34 -29
- package/lib/Signal/Group/sender-key-state.js +100 -37
- package/lib/Signal/Group/sender-message-key.d.ts +10 -11
- package/lib/Signal/Group/sender-message-key.js +22 -15
- package/lib/Signal/libsignal.d.ts +8 -5
- package/lib/Signal/libsignal.js +142 -288
- package/lib/Signal/lid-mapping.d.ts +28 -23
- package/lib/Signal/lid-mapping.js +184 -277
- package/lib/Socket/Client/index.d.ts +2 -3
- package/lib/Socket/Client/index.js +22 -3
- package/lib/Socket/Client/types.d.ts +15 -15
- package/lib/Socket/Client/types.js +15 -8
- package/lib/Socket/Client/websocket.d.ts +12 -12
- package/lib/Socket/Client/websocket.js +37 -29
- package/lib/Socket/business.d.ts +178 -208
- package/lib/Socket/business.js +127 -91
- package/lib/Socket/chats.d.ts +93 -120
- package/lib/Socket/chats.js +652 -727
- package/lib/Socket/community.js +10 -2
- package/lib/Socket/groups.d.ts +111 -143
- package/lib/Socket/groups.js +186 -165
- package/lib/Socket/index.d.ts +183 -252
- package/lib/Socket/index.js +18 -38
- package/lib/Socket/messages-recv.d.ts +167 -196
- package/lib/Socket/messages-recv.js +1567 -1443
- package/lib/Socket/messages-send.d.ts +158 -192
- package/lib/Socket/messages-send.js +1208 -1102
- package/lib/Socket/newsletter.d.ts +138 -163
- package/lib/Socket/newsletter.js +249 -153
- package/lib/Socket/socket.d.ts +36 -50
- package/lib/Socket/socket.js +820 -749
- package/lib/Store/index.d.ts +4 -4
- package/lib/Store/index.js +24 -4
- package/lib/Store/make-in-memory-store.d.ts +104 -44
- package/lib/Store/make-in-memory-store.js +213 -199
- package/lib/Store/make-ordered-dictionary.d.ts +12 -13
- package/lib/Store/make-ordered-dictionary.js +45 -38
- package/lib/Store/object-repository.d.ts +10 -11
- package/lib/Store/object-repository.js +16 -9
- package/lib/Types/Auth.d.ts +97 -93
- package/lib/Types/Auth.js +3 -2
- package/lib/Types/Bussines.js +3 -2
- package/lib/Types/Call.d.ts +13 -14
- package/lib/Types/Call.js +3 -2
- package/lib/Types/Chat.d.ts +97 -78
- package/lib/Types/Chat.js +9 -8
- package/lib/Types/Contact.d.ts +9 -12
- package/lib/Types/Contact.js +3 -2
- package/lib/Types/Events.d.ts +176 -206
- package/lib/Types/Events.js +3 -2
- package/lib/Types/GroupMetadata.d.ts +48 -53
- package/lib/Types/GroupMetadata.js +3 -2
- package/lib/Types/Label.d.ts +14 -13
- package/lib/Types/Label.js +30 -24
- package/lib/Types/LabelAssociation.d.ts +20 -15
- package/lib/Types/LabelAssociation.js +12 -6
- package/lib/Types/Message.d.ts +412 -248
- package/lib/Types/Message.js +19 -17
- package/lib/Types/Product.d.ts +71 -58
- package/lib/Types/Product.js +3 -2
- package/lib/Types/Signal.d.ts +82 -71
- package/lib/Types/Signal.js +3 -2
- package/lib/Types/Socket.d.ts +81 -76
- package/lib/Types/Socket.js +3 -3
- package/lib/Types/State.d.ts +19 -75
- package/lib/Types/State.js +14 -56
- package/lib/Types/USync.d.ts +8 -8
- package/lib/Types/USync.js +3 -2
- package/lib/Types/index.d.ts +62 -47
- package/lib/Types/index.js +50 -26
- package/lib/Utils/auth-utils.d.ts +10 -13
- package/lib/Utils/auth-utils.js +472 -213
- package/lib/Utils/business.d.ts +20 -14
- package/lib/Utils/business.js +134 -110
- package/lib/Utils/chat-utils.d.ts +70 -88
- package/lib/Utils/chat-utils.js +403 -466
- package/lib/Utils/crypto.d.ts +46 -27
- package/lib/Utils/crypto.js +188 -117
- package/lib/Utils/decode-wa-message.d.ts +45 -58
- package/lib/Utils/decode-wa-message.js +311 -212
- package/lib/Utils/event-buffer.d.ts +17 -14
- package/lib/Utils/event-buffer.js +296 -321
- package/lib/Utils/generics.d.ts +92 -66
- package/lib/Utils/generics.js +436 -270
- package/lib/Utils/history.d.ts +23 -24
- package/lib/Utils/history.js +76 -106
- package/lib/Utils/index.d.ts +21 -24
- package/lib/Utils/index.js +41 -24
- package/lib/Utils/link-preview.d.ts +14 -12
- package/lib/Utils/link-preview.js +75 -40
- package/lib/Utils/logger.d.ts +11 -10
- package/lib/Utils/logger.js +7 -3
- package/lib/Utils/lt-hash.d.ts +14 -8
- package/lib/Utils/lt-hash.js +53 -3
- package/lib/Utils/make-mutex.d.ts +7 -7
- package/lib/Utils/make-mutex.js +44 -28
- package/lib/Utils/message-retry-manager.d.ts +88 -115
- package/lib/Utils/message-retry-manager.js +160 -265
- package/lib/Utils/messages-media.d.ts +107 -105
- package/lib/Utils/messages-media.js +619 -548
- package/lib/Utils/messages.d.ts +66 -52
- package/lib/Utils/messages.js +1558 -1730
- package/lib/Utils/noise-handler.d.ts +18 -18
- package/lib/Utils/noise-handler.js +130 -176
- package/lib/Utils/process-message.d.ts +32 -43
- package/lib/Utils/process-message.js +282 -484
- package/lib/Utils/rich-message-utils.js +724 -1220
- package/lib/Utils/signal.d.ts +32 -37
- package/lib/Utils/signal.js +105 -140
- package/lib/Utils/use-multi-file-auth-state.d.ts +5 -5
- package/lib/Utils/use-multi-file-auth-state.js +120 -70
- package/lib/Utils/use-single-file-auth-state.d.ts +13 -11
- package/lib/Utils/use-single-file-auth-state.js +66 -92
- package/lib/Utils/validate-connection.d.ts +13 -11
- package/lib/Utils/validate-connection.js +113 -128
- package/lib/WABinary/constants.d.ts +27 -25
- package/lib/WABinary/constants.js +1292 -1451
- package/lib/WABinary/decode.d.ts +9 -7
- package/lib/WABinary/decode.js +189 -163
- package/lib/WABinary/encode.d.ts +3 -3
- package/lib/WABinary/encode.js +155 -110
- package/lib/WABinary/generic-utils.d.ts +27 -14
- package/lib/WABinary/generic-utils.js +105 -177
- package/lib/WABinary/index.d.ts +5 -6
- package/lib/WABinary/index.js +25 -6
- package/lib/WABinary/jid-utils.d.ts +54 -41
- package/lib/WABinary/jid-utils.js +152 -83
- package/lib/WABinary/types.d.ts +13 -10
- package/lib/WABinary/types.js +3 -2
- package/lib/WAM/BinaryInfo.d.ts +15 -8
- package/lib/WAM/BinaryInfo.js +14 -7
- package/lib/WAM/constants.d.ts +37 -30
- package/lib/WAM/constants.js +11983 -19465
- package/lib/WAM/encode.d.ts +3 -3
- package/lib/WAM/encode.js +109 -95
- package/lib/WAM/index.d.ts +3 -4
- package/lib/WAM/index.js +23 -4
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +9 -9
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +21 -37
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +22 -19
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +26 -18
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -11
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +20 -12
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -11
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +24 -16
- package/lib/WAUSync/Protocols/index.d.ts +6 -6
- package/lib/WAUSync/Protocols/index.js +26 -6
- package/lib/WAUSync/USyncQuery.d.ts +28 -27
- package/lib/WAUSync/USyncQuery.js +62 -68
- package/lib/WAUSync/USyncUser.d.ts +10 -15
- package/lib/WAUSync/USyncUser.js +19 -20
- package/lib/WAUSync/index.d.ts +3 -4
- package/lib/WAUSync/index.js +23 -4
- package/lib/index.d.ts +12 -11
- package/lib/index.js +39 -12
- package/package.json +43 -87
- package/engine-requirements.js +0 -10
package/lib/Utils/signal.d.ts
CHANGED
|
@@ -1,47 +1,42 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
|
|
1
|
+
import { SignalRepository } from '../Types'
|
|
2
|
+
import { AuthenticationCreds, AuthenticationState, KeyPair, SignalIdentity, SignalKeyStore, SignedKeyPair } from '../Types/Auth'
|
|
3
|
+
import { BinaryNode, JidWithDevice } from '../WABinary'
|
|
4
|
+
import { USyncQueryResultList } from '../WAUSync'
|
|
5
|
+
|
|
6
|
+
export declare const createSignalIdentity: (wid: string, accountSignatureKey: Uint8Array) => SignalIdentity
|
|
7
|
+
|
|
6
8
|
export declare const getPreKeys: ({ get }: SignalKeyStore, min: number, limit: number) => Promise<{
|
|
7
|
-
[id: string]: KeyPair
|
|
8
|
-
}
|
|
9
|
+
[id: string]: KeyPair
|
|
10
|
+
}>
|
|
11
|
+
|
|
9
12
|
export declare const generateOrGetPreKeys: (creds: AuthenticationCreds, range: number) => {
|
|
10
13
|
newPreKeys: {
|
|
11
|
-
[id: number]: KeyPair
|
|
12
|
-
}
|
|
13
|
-
lastPreKeyId: number
|
|
14
|
-
preKeysRange: readonly [number, number]
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export declare const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
};
|
|
26
|
-
preKey: {
|
|
27
|
-
keyId: number;
|
|
28
|
-
publicKey: Uint8Array;
|
|
29
|
-
} | undefined;
|
|
30
|
-
} | null;
|
|
31
|
-
export declare const parseAndInjectE2ESessions: (node: BinaryNode, repository: SignalRepositoryWithLIDStore) => Promise<void>;
|
|
32
|
-
export declare const extractDeviceJids: (result: USyncQueryResultList[], myJid: string, myLid: string, excludeZeroDevices: boolean) => FullJid[];
|
|
14
|
+
[id: number]: KeyPair
|
|
15
|
+
}
|
|
16
|
+
lastPreKeyId: number
|
|
17
|
+
preKeysRange: readonly [number, number]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export declare const xmppSignedPreKey: (key: SignedKeyPair) => BinaryNode
|
|
21
|
+
|
|
22
|
+
export declare const xmppPreKey: (pair: KeyPair, id: number) => BinaryNode
|
|
23
|
+
|
|
24
|
+
export declare const parseAndInjectE2ESessions: (node: BinaryNode, repository: SignalRepository) => Promise<void>
|
|
25
|
+
|
|
26
|
+
export declare const extractDeviceJids: (result: USyncQueryResultList[], myJid: string, excludeZeroDevices: boolean) => JidWithDevice[]
|
|
27
|
+
|
|
33
28
|
/**
|
|
34
29
|
* get the next N keys for upload or processing
|
|
35
30
|
* @param count number of pre-keys to get or generate
|
|
36
31
|
*/
|
|
37
32
|
export declare const getNextPreKeys: ({ creds, keys }: AuthenticationState, count: number) => Promise<{
|
|
38
|
-
update: Partial<AuthenticationCreds
|
|
33
|
+
update: Partial<AuthenticationCreds>
|
|
39
34
|
preKeys: {
|
|
40
|
-
[id: string]: KeyPair
|
|
41
|
-
}
|
|
42
|
-
}
|
|
35
|
+
[id: string]: KeyPair
|
|
36
|
+
}
|
|
37
|
+
}>
|
|
38
|
+
|
|
43
39
|
export declare const getNextPreKeysNode: (state: AuthenticationState, count: number) => Promise<{
|
|
44
|
-
update: Partial<AuthenticationCreds
|
|
45
|
-
node: BinaryNode
|
|
46
|
-
}
|
|
47
|
-
//# sourceMappingURL=signal.d.ts.map
|
|
40
|
+
update: Partial<AuthenticationCreds>
|
|
41
|
+
node: BinaryNode
|
|
42
|
+
}>
|
package/lib/Utils/signal.js
CHANGED
|
@@ -1,201 +1,166 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export const createSignalIdentity = (wid, accountSignatureKey) => {
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
|
+
|
|
5
|
+
const lodash_1 = require("lodash")
|
|
6
|
+
const Defaults_1 = require("../Defaults")
|
|
7
|
+
const WABinary_1 = require("../WABinary")
|
|
8
|
+
const crypto_1 = require("./crypto")
|
|
9
|
+
const generics_1 = require("./generics")
|
|
10
|
+
|
|
11
|
+
const createSignalIdentity = (wid, accountSignatureKey) => {
|
|
13
12
|
return {
|
|
14
13
|
identifier: { name: wid, deviceId: 0 },
|
|
15
|
-
identifierKey: generateSignalPubKey(accountSignatureKey)
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
identifierKey: crypto_1.generateSignalPubKey(accountSignatureKey)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const getPreKeys = async ({ get }, min, limit) => {
|
|
19
|
+
const idList = []
|
|
20
20
|
for (let id = min; id < limit; id++) {
|
|
21
|
-
idList.push(id.toString())
|
|
21
|
+
idList.push(id.toString())
|
|
22
22
|
}
|
|
23
|
-
return get('pre-key', idList)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
23
|
+
return get('pre-key', idList)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const generateOrGetPreKeys = (creds, range) => {
|
|
27
|
+
const avaliable = creds.nextPreKeyId - creds.firstUnuploadedPreKeyId
|
|
28
|
+
const remaining = range - avaliable
|
|
29
|
+
const lastPreKeyId = creds.nextPreKeyId + remaining - 1
|
|
30
|
+
const newPreKeys = {}
|
|
30
31
|
if (remaining > 0) {
|
|
31
32
|
for (let i = creds.nextPreKeyId; i <= lastPreKeyId; i++) {
|
|
32
|
-
newPreKeys[i] = Curve.generateKeyPair()
|
|
33
|
+
newPreKeys[i] = crypto_1.Curve.generateKeyPair()
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
return {
|
|
36
37
|
newPreKeys,
|
|
37
38
|
lastPreKeyId,
|
|
38
|
-
preKeysRange: [creds.firstUnuploadedPreKeyId, range]
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
39
|
+
preKeysRange: [creds.firstUnuploadedPreKeyId, range],
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const xmppSignedPreKey = (key) => ({
|
|
42
44
|
tag: 'skey',
|
|
43
45
|
attrs: {},
|
|
44
46
|
content: [
|
|
45
|
-
{ tag: 'id', attrs: {}, content: encodeBigEndian(key.keyId, 3) },
|
|
47
|
+
{ tag: 'id', attrs: {}, content: generics_1.encodeBigEndian(key.keyId, 3) },
|
|
46
48
|
{ tag: 'value', attrs: {}, content: key.keyPair.public },
|
|
47
49
|
{ tag: 'signature', attrs: {}, content: key.signature }
|
|
48
50
|
]
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
const xmppPreKey = (pair, id) => ({
|
|
51
54
|
tag: 'key',
|
|
52
55
|
attrs: {},
|
|
53
56
|
content: [
|
|
54
|
-
{ tag: 'id', attrs: {}, content: encodeBigEndian(id, 3) },
|
|
57
|
+
{ tag: 'id', attrs: {}, content: generics_1.encodeBigEndian(id, 3) },
|
|
55
58
|
{ tag: 'value', attrs: {}, content: pair.public }
|
|
56
59
|
]
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const identity = getBinaryNodeChildBuffer(keysNode, 'identity');
|
|
67
|
-
const skey = getBinaryNodeChild(keysNode, 'skey');
|
|
68
|
-
if (!identity || identity.length !== 32 || !skey)
|
|
69
|
-
return null;
|
|
70
|
-
const registrationId = getBinaryNodeChildUInt(receipt, 'registration', 4);
|
|
71
|
-
if (!isValidUInt(registrationId))
|
|
72
|
-
return null;
|
|
73
|
-
const signedPubKey = getBinaryNodeChildBuffer(skey, 'value');
|
|
74
|
-
const signedSig = getBinaryNodeChildBuffer(skey, 'signature');
|
|
75
|
-
const signedKeyId = getBinaryNodeChildUInt(skey, 'id', 3);
|
|
76
|
-
if (!signedPubKey || signedPubKey.length !== 32 || !signedSig || !isValidUInt(signedKeyId)) {
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
const preKeyNode = getBinaryNodeChild(keysNode, 'key');
|
|
80
|
-
let preKey;
|
|
81
|
-
if (preKeyNode) {
|
|
82
|
-
const preKeyPub = getBinaryNodeChildBuffer(preKeyNode, 'value');
|
|
83
|
-
const preKeyId = getBinaryNodeChildUInt(preKeyNode, 'id', 3);
|
|
84
|
-
if (!preKeyPub || preKeyPub.length !== 32 || !isValidUInt(preKeyId)) {
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
preKey = { keyId: preKeyId, publicKey: generateSignalPubKey(preKeyPub) };
|
|
88
|
-
}
|
|
89
|
-
return {
|
|
90
|
-
registrationId,
|
|
91
|
-
identityKey: generateSignalPubKey(identity),
|
|
92
|
-
signedPreKey: {
|
|
93
|
-
keyId: signedKeyId,
|
|
94
|
-
publicKey: generateSignalPubKey(signedPubKey),
|
|
95
|
-
signature: signedSig
|
|
96
|
-
},
|
|
97
|
-
preKey
|
|
98
|
-
};
|
|
99
|
-
};
|
|
100
|
-
export const parseAndInjectE2ESessions = async (node, repository) => {
|
|
101
|
-
const extractKey = (key) => key
|
|
102
|
-
? {
|
|
103
|
-
keyId: getBinaryNodeChildUInt(key, 'id', 3),
|
|
104
|
-
publicKey: generateSignalPubKey(getBinaryNodeChildBuffer(key, 'value')),
|
|
105
|
-
signature: getBinaryNodeChildBuffer(key, 'signature')
|
|
106
|
-
}
|
|
107
|
-
: undefined;
|
|
108
|
-
const nodes = getBinaryNodeChildren(getBinaryNodeChild(node, 'list'), 'user');
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
const parseAndInjectE2ESessions = async (node, repository) => {
|
|
63
|
+
const extractKey = (key) => (key ? ({
|
|
64
|
+
keyId: WABinary_1.getBinaryNodeChildUInt(key, 'id', 3),
|
|
65
|
+
publicKey: crypto_1.generateSignalPubKey(WABinary_1.getBinaryNodeChildBuffer(key, 'value')),
|
|
66
|
+
signature: WABinary_1.getBinaryNodeChildBuffer(key, 'signature')
|
|
67
|
+
}) : undefined)
|
|
68
|
+
const nodes = WABinary_1.getBinaryNodeChildren(WABinary_1.getBinaryNodeChild(node, 'list'), 'user')
|
|
109
69
|
for (const node of nodes) {
|
|
110
|
-
assertNodeErrorFree(node)
|
|
70
|
+
WABinary_1.assertNodeErrorFree(node)
|
|
111
71
|
}
|
|
112
72
|
// Most of the work in repository.injectE2ESession is CPU intensive, not IO
|
|
113
73
|
// So Promise.all doesn't really help here,
|
|
114
74
|
// but blocks even loop if we're using it inside keys.transaction, and it makes it "sync" actually
|
|
115
75
|
// This way we chunk it in smaller parts and between those parts we can yield to the event loop
|
|
116
76
|
// It's rare case when you need to E2E sessions for so many users, but it's possible
|
|
117
|
-
const chunkSize = 100
|
|
118
|
-
const chunks = chunk(nodes, chunkSize)
|
|
77
|
+
const chunkSize = 100
|
|
78
|
+
const chunks = lodash_1.chunk(nodes, chunkSize)
|
|
119
79
|
for (const nodesChunk of chunks) {
|
|
120
|
-
|
|
121
|
-
const signedKey = getBinaryNodeChild(node, 'skey')
|
|
122
|
-
const key = getBinaryNodeChild(node, 'key')
|
|
123
|
-
const identity = getBinaryNodeChildBuffer(node, 'identity')
|
|
124
|
-
const jid = node.attrs.jid
|
|
125
|
-
const registrationId = getBinaryNodeChildUInt(node, 'registration', 4)
|
|
80
|
+
await Promise.all(nodesChunk.map(async (node) => {
|
|
81
|
+
const signedKey = WABinary_1.getBinaryNodeChild(node, 'skey')
|
|
82
|
+
const key = WABinary_1.getBinaryNodeChild(node, 'key')
|
|
83
|
+
const identity = WABinary_1.getBinaryNodeChildBuffer(node, 'identity')
|
|
84
|
+
const jid = node.attrs.jid
|
|
85
|
+
const registrationId = WABinary_1.getBinaryNodeChildUInt(node, 'registration', 4)
|
|
126
86
|
await repository.injectE2ESession({
|
|
127
87
|
jid,
|
|
128
88
|
session: {
|
|
129
89
|
registrationId: registrationId,
|
|
130
|
-
identityKey: generateSignalPubKey(identity),
|
|
90
|
+
identityKey: crypto_1.generateSignalPubKey(identity),
|
|
131
91
|
signedPreKey: extractKey(signedKey),
|
|
132
92
|
preKey: extractKey(key)
|
|
133
93
|
}
|
|
134
|
-
})
|
|
135
|
-
}
|
|
94
|
+
})
|
|
95
|
+
}))
|
|
136
96
|
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const extractDeviceJids = (result, myJid, excludeZeroDevices) => {
|
|
100
|
+
const { user: myUser, device: myDevice } = WABinary_1.jidDecode(myJid)
|
|
101
|
+
const extracted = []
|
|
141
102
|
for (const userResult of result) {
|
|
142
|
-
const { devices, id } = userResult
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
) {
|
|
153
|
-
if (isHosted) {
|
|
154
|
-
domainType = domainType === WAJIDDomains.LID ? WAJIDDomains.HOSTED_LID : WAJIDDomains.HOSTED;
|
|
103
|
+
const { devices, id } = userResult
|
|
104
|
+
const { user } = WABinary_1.jidDecode(id)
|
|
105
|
+
const deviceList = devices?.deviceList
|
|
106
|
+
if (Array.isArray(deviceList)) {
|
|
107
|
+
for (const { id: device, keyIndex } of deviceList) {
|
|
108
|
+
if ((!excludeZeroDevices || device !== 0) && // if zero devices are not-excluded, or device is non zero
|
|
109
|
+
(myUser !== user || myDevice !== device) && // either different user or if me user, not this device
|
|
110
|
+
(device === 0 || !!keyIndex) // ensure that "key-index" is specified for "non-zero" devices, produces a bad req otherwise
|
|
111
|
+
) {
|
|
112
|
+
extracted.push({ user, device })
|
|
155
113
|
}
|
|
156
|
-
extracted.push({
|
|
157
|
-
user,
|
|
158
|
-
device,
|
|
159
|
-
domainType,
|
|
160
|
-
server: getServerFromDomainType(server, domainType)
|
|
161
|
-
});
|
|
162
114
|
}
|
|
163
115
|
}
|
|
164
116
|
}
|
|
165
|
-
return extracted
|
|
166
|
-
}
|
|
117
|
+
return extracted
|
|
118
|
+
}
|
|
119
|
+
|
|
167
120
|
/**
|
|
168
121
|
* get the next N keys for upload or processing
|
|
169
122
|
* @param count number of pre-keys to get or generate
|
|
170
123
|
*/
|
|
171
|
-
|
|
172
|
-
const { newPreKeys, lastPreKeyId, preKeysRange } = generateOrGetPreKeys(creds, count)
|
|
124
|
+
const getNextPreKeys = async ({ creds, keys }, count) => {
|
|
125
|
+
const { newPreKeys, lastPreKeyId, preKeysRange } = generateOrGetPreKeys(creds, count)
|
|
173
126
|
const update = {
|
|
174
127
|
nextPreKeyId: Math.max(lastPreKeyId + 1, creds.nextPreKeyId),
|
|
175
128
|
firstUnuploadedPreKeyId: Math.max(creds.firstUnuploadedPreKeyId, lastPreKeyId + 1)
|
|
176
|
-
}
|
|
177
|
-
await keys.set({ 'pre-key': newPreKeys })
|
|
178
|
-
const preKeys = await getPreKeys(keys, preKeysRange[0], preKeysRange[0] + preKeysRange[1])
|
|
179
|
-
return { update, preKeys }
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const {
|
|
129
|
+
}
|
|
130
|
+
await keys.set({ 'pre-key': newPreKeys })
|
|
131
|
+
const preKeys = await getPreKeys(keys, preKeysRange[0], preKeysRange[0] + preKeysRange[1])
|
|
132
|
+
return { update, preKeys }
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const getNextPreKeysNode = async (state, count) => {
|
|
136
|
+
const { creds } = state
|
|
137
|
+
const { update, preKeys } = await getNextPreKeys(state, count)
|
|
184
138
|
const node = {
|
|
185
139
|
tag: 'iq',
|
|
186
140
|
attrs: {
|
|
187
141
|
xmlns: 'encrypt',
|
|
188
142
|
type: 'set',
|
|
189
|
-
to: S_WHATSAPP_NET
|
|
143
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
190
144
|
},
|
|
191
145
|
content: [
|
|
192
|
-
{ tag: 'registration', attrs: {}, content: encodeBigEndian(creds.registrationId) },
|
|
193
|
-
{ tag: 'type', attrs: {}, content: KEY_BUNDLE_TYPE },
|
|
146
|
+
{ tag: 'registration', attrs: {}, content: generics_1.encodeBigEndian(creds.registrationId) },
|
|
147
|
+
{ tag: 'type', attrs: {}, content: Defaults_1.KEY_BUNDLE_TYPE },
|
|
194
148
|
{ tag: 'identity', attrs: {}, content: creds.signedIdentityKey.public },
|
|
195
149
|
{ tag: 'list', attrs: {}, content: Object.keys(preKeys).map(k => xmppPreKey(preKeys[+k], +k)) },
|
|
196
150
|
xmppSignedPreKey(creds.signedPreKey)
|
|
197
151
|
]
|
|
198
|
-
}
|
|
199
|
-
return { update, node }
|
|
200
|
-
}
|
|
201
|
-
|
|
152
|
+
}
|
|
153
|
+
return { update, node }
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
module.exports = {
|
|
157
|
+
createSignalIdentity,
|
|
158
|
+
getPreKeys,
|
|
159
|
+
generateOrGetPreKeys,
|
|
160
|
+
xmppSignedPreKey,
|
|
161
|
+
xmppPreKey,
|
|
162
|
+
parseAndInjectE2ESessions,
|
|
163
|
+
extractDeviceJids,
|
|
164
|
+
getNextPreKeys,
|
|
165
|
+
getNextPreKeysNode
|
|
166
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { AuthenticationState } from '../Types'
|
|
2
|
+
|
|
2
3
|
/**
|
|
3
4
|
* stores the full authentication state in a single folder.
|
|
4
5
|
* Far more efficient than singlefileauthstate
|
|
@@ -7,7 +8,6 @@ import type { AuthenticationState } from '../Types/index.js';
|
|
|
7
8
|
* Would recommend writing an auth state for use with a proper SQL or No-SQL DB
|
|
8
9
|
* */
|
|
9
10
|
export declare const useMultiFileAuthState: (folder: string) => Promise<{
|
|
10
|
-
state: AuthenticationState
|
|
11
|
-
saveCreds: () => Promise<void
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=use-multi-file-auth-state.d.ts.map
|
|
11
|
+
state: AuthenticationState
|
|
12
|
+
saveCreds: () => Promise<void>
|
|
13
|
+
}>
|
|
@@ -1,23 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod }
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
8
|
+
|
|
9
|
+
const async_mutex_1 = __importDefault(require("async-mutex"))
|
|
10
|
+
const promises_1 = require("fs/promises")
|
|
11
|
+
const { rename: fsRename } = promises_1
|
|
12
|
+
const path_1 = require("path")
|
|
13
|
+
const WAProto_1 = require("../../WAProto")
|
|
14
|
+
const auth_utils_1 = require("./auth-utils")
|
|
15
|
+
const generics_1 = require("./generics")
|
|
7
16
|
// We need to lock files due to the fact that we are using async functions to read and write files
|
|
8
17
|
// https://github.com/WhiskeySockets/Baileys/issues/794
|
|
9
18
|
// https://github.com/nodejs/node/issues/26338
|
|
10
19
|
// Use a Map to store mutexes for each file path
|
|
11
|
-
const fileLocks = new Map()
|
|
20
|
+
const fileLocks = new Map()
|
|
21
|
+
|
|
12
22
|
// Get or create a mutex for a specific file path
|
|
13
23
|
const getFileLock = (path) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
let mutex = fileLocks.get(path)
|
|
25
|
+
if (!mutex) {
|
|
26
|
+
mutex = new async_mutex_1.Mutex()
|
|
27
|
+
fileLocks.set(path, mutex)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return mutex
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Lepas mutex dari Map begitu tidak dipakai lagi supaya tidak numpuk terus (memory leak)
|
|
34
|
+
// selama proses hidup lama (bot jalan berbulan-bulan dengan ribuan file sesi berbeda).
|
|
35
|
+
const releaseFileLock = (path) => {
|
|
36
|
+
fileLocks.delete(path)
|
|
37
|
+
}
|
|
38
|
+
|
|
21
39
|
/**
|
|
22
40
|
* stores the full authentication state in a single folder.
|
|
23
41
|
* Far more efficient than singlefileauthstate
|
|
@@ -25,97 +43,129 @@ const getFileLock = (path) => {
|
|
|
25
43
|
* Again, I wouldn't endorse this for any production level use other than perhaps a bot.
|
|
26
44
|
* Would recommend writing an auth state for use with a proper SQL or No-SQL DB
|
|
27
45
|
* */
|
|
28
|
-
|
|
46
|
+
const useMultiFileAuthState = async (folder) => {
|
|
29
47
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
48
|
const writeData = async (data, file) => {
|
|
31
|
-
const filePath = join(folder, fixFileName(file))
|
|
32
|
-
const mutex = getFileLock(filePath)
|
|
49
|
+
const filePath = path_1.join(folder, fixFileName(file))
|
|
50
|
+
const mutex = getFileLock(filePath)
|
|
33
51
|
return mutex.acquire().then(async (release) => {
|
|
34
52
|
try {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
53
|
+
// Atomic write: write to temp file then rename, agar file tidak pernah
|
|
54
|
+
// kebaca dalam kondisi setengah tertulis kalau proses mati di tengah jalan.
|
|
55
|
+
const tmpPath = filePath + '.tmp'
|
|
56
|
+
await promises_1.writeFile(tmpPath, JSON.stringify(data, generics_1.BufferJSON.replacer))
|
|
57
|
+
await fsRename(tmpPath, filePath)
|
|
58
|
+
} finally {
|
|
59
|
+
release()
|
|
60
|
+
releaseFileLock(filePath)
|
|
39
61
|
}
|
|
40
|
-
})
|
|
41
|
-
}
|
|
62
|
+
})
|
|
63
|
+
}
|
|
42
64
|
const readData = async (file) => {
|
|
65
|
+
const filePath = path_1.join(folder, fixFileName(file))
|
|
43
66
|
try {
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
return await mutex.acquire().then(async (release) => {
|
|
67
|
+
const mutex = getFileLock(filePath)
|
|
68
|
+
const data = await mutex.acquire().then(async (release) => {
|
|
47
69
|
try {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
release();
|
|
70
|
+
return await promises_1.readFile(filePath, { encoding: 'utf-8' })
|
|
71
|
+
} finally {
|
|
72
|
+
release()
|
|
73
|
+
releaseFileLock(filePath)
|
|
53
74
|
}
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
return JSON.parse(data, generics_1.BufferJSON.reviver)
|
|
78
|
+
} catch (error) {
|
|
79
|
+
// ENOENT (file belum ada) itu normal, tapi kalau isinya rusak/corrupt (JSON parse
|
|
80
|
+
// gagal) itu wajib kelihatan di log, bukan diam-diam dianggap "null"/hilang.
|
|
81
|
+
if (error?.code !== 'ENOENT') {
|
|
82
|
+
console.warn(`[useMultiFileAuthState] Gagal membaca/parse ${filePath}:`, error?.message || error)
|
|
83
|
+
}
|
|
84
|
+
return null
|
|
58
85
|
}
|
|
59
|
-
}
|
|
86
|
+
}
|
|
60
87
|
const removeData = async (file) => {
|
|
88
|
+
const filePath = path_1.join(folder, fixFileName(file))
|
|
61
89
|
try {
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
90
|
+
const mutex = getFileLock(filePath)
|
|
91
|
+
await mutex.acquire().then(async (release) => {
|
|
92
|
+
try {
|
|
93
|
+
await promises_1.unlink(filePath)
|
|
94
|
+
} finally {
|
|
95
|
+
release()
|
|
96
|
+
releaseFileLock(filePath)
|
|
67
97
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
catch { }
|
|
76
|
-
};
|
|
77
|
-
const folderInfo = await stat(folder).catch(() => { });
|
|
98
|
+
})
|
|
99
|
+
} catch {}
|
|
100
|
+
}
|
|
101
|
+
const folderInfo = await promises_1.stat(folder).catch(() => { })
|
|
78
102
|
if (folderInfo) {
|
|
79
103
|
if (!folderInfo.isDirectory()) {
|
|
80
|
-
throw new Error(`found something that is not a directory at ${folder}, either delete it or specify a different location`)
|
|
104
|
+
throw new Error(`found something that is not a directory at ${folder}, either delete it or specify a different location`)
|
|
81
105
|
}
|
|
82
106
|
}
|
|
83
107
|
else {
|
|
84
|
-
await mkdir(folder, { recursive: true })
|
|
108
|
+
await promises_1.mkdir(folder, { recursive: true })
|
|
85
109
|
}
|
|
86
|
-
const fixFileName = (file) =>
|
|
87
|
-
|
|
110
|
+
const fixFileName = (file) => {
|
|
111
|
+
return file?.replace(/\//g, '__')?.replace(/:/g, '-')
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Bersihkan file .tmp "yatim" yang tertinggal dari proses sebelumnya yang mati
|
|
115
|
+
// di tengah proses rename (atomic write). File-file ini tidak berguna dan kalau
|
|
116
|
+
// dibiarkan menumpuk, cuma buang-buang disk.
|
|
117
|
+
try {
|
|
118
|
+
const entries = await promises_1.readdir(folder)
|
|
119
|
+
await Promise.all(
|
|
120
|
+
entries
|
|
121
|
+
.filter((name) => name.endsWith('.tmp'))
|
|
122
|
+
.map((name) => promises_1.unlink(path_1.join(folder, name)).catch(() => {}))
|
|
123
|
+
)
|
|
124
|
+
} catch {}
|
|
125
|
+
|
|
126
|
+
const creds = await readData('creds.json') || auth_utils_1.initAuthCreds()
|
|
88
127
|
return {
|
|
89
128
|
state: {
|
|
90
129
|
creds,
|
|
91
130
|
keys: {
|
|
92
131
|
get: async (type, ids) => {
|
|
93
|
-
const data = {}
|
|
132
|
+
const data = {}
|
|
94
133
|
await Promise.all(ids.map(async (id) => {
|
|
95
|
-
let value = await readData(`${type}-${id}.json`)
|
|
134
|
+
let value = await readData(`${type}-${id}.json`)
|
|
96
135
|
if (type === 'app-state-sync-key' && value) {
|
|
97
|
-
value = proto.Message.AppStateSyncKeyData.fromObject(value)
|
|
136
|
+
value = WAProto_1.proto.Message.AppStateSyncKeyData.fromObject(value)
|
|
98
137
|
}
|
|
99
|
-
data[id] = value
|
|
100
|
-
}))
|
|
101
|
-
return data
|
|
138
|
+
data[id] = value
|
|
139
|
+
}))
|
|
140
|
+
return data
|
|
102
141
|
},
|
|
103
142
|
set: async (data) => {
|
|
104
|
-
const tasks = []
|
|
143
|
+
const tasks = []
|
|
105
144
|
for (const category in data) {
|
|
106
145
|
for (const id in data[category]) {
|
|
107
|
-
const value = data[category][id]
|
|
108
|
-
const file = `${category}-${id}.json
|
|
109
|
-
tasks.push(value ? writeData(value, file) : removeData(file))
|
|
146
|
+
const value = data[category][id]
|
|
147
|
+
const file = `${category}-${id}.json`
|
|
148
|
+
tasks.push(value ? writeData(value, file) : removeData(file))
|
|
110
149
|
}
|
|
111
150
|
}
|
|
112
|
-
await Promise.all(tasks)
|
|
151
|
+
await Promise.all(tasks)
|
|
113
152
|
}
|
|
114
153
|
}
|
|
115
154
|
},
|
|
155
|
+
// saveCreds sekarang selalu langsung menulis (tidak didebounce). creds.json adalah
|
|
156
|
+
// file paling kritis — kalau proses mati tepat di jendela debounce, sesi bisa hilang
|
|
157
|
+
// atau balik ke state lama sehingga semua pesan gagal didekripsi setelah reconnect.
|
|
116
158
|
saveCreds: async () => {
|
|
117
|
-
return writeData(creds, 'creds.json')
|
|
159
|
+
return writeData(creds, 'creds.json')
|
|
160
|
+
},
|
|
161
|
+
// Tetap disediakan sebagai alias untuk kompatibilitas kode lama yang memanggil
|
|
162
|
+
// saveCredsNow() secara eksplisit (misal di handler disconnect/cleanup).
|
|
163
|
+
saveCredsNow: async () => {
|
|
164
|
+
return writeData(creds, 'creds.json')
|
|
118
165
|
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
module.exports = {
|
|
170
|
+
useMultiFileAuthState
|
|
171
|
+
}
|