@nexustechpro/baileys 1.0.6 → 1.0.7
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 +2 -2
- package/lib/Signal/Group/group_cipher.js +92 -74
- package/lib/Signal/libsignal.js +151 -316
- package/lib/Socket/Client/websocket.js +59 -120
- package/lib/Socket/groups.js +16 -4
- package/lib/Socket/messages-send.js +768 -1031
- package/lib/Socket/nexus-handler.js +359 -646
- package/lib/Socket/socket.js +204 -329
- package/lib/Utils/crypto.js +20 -0
- package/lib/Utils/messages-media.js +177 -404
- package/lib/Utils/messages.js +484 -1092
- package/lib/Utils/noise-handler.js +101 -26
- package/lib/WABinary/generic-utils.js +7 -1
- package/lib/index.js +2 -2
- package/package.json +7 -1
package/README.md
CHANGED
|
@@ -1684,8 +1684,8 @@ Special thanks to:
|
|
|
1684
1684
|
|
|
1685
1685
|
## 📞 Support
|
|
1686
1686
|
|
|
1687
|
-
- **Issues**: [
|
|
1688
|
-
- **Discussions**: [
|
|
1687
|
+
- **Issues**: [Whatsapp Channel](https://whatsapp.com/channel/0029VbBK53XBvvslYeZlBe0V)
|
|
1688
|
+
- **Discussions**: [Whatsapp Channel](https://whatsapp.com/channel/0029VbBK53XBvvslYeZlBe0V)
|
|
1689
1689
|
- **NPM**: [@nexustechpro/baileys](https://www.npmjs.com/package/@nexustechpro/baileys)
|
|
1690
1690
|
|
|
1691
1691
|
---
|
|
@@ -1,82 +1,100 @@
|
|
|
1
|
-
import { decrypt, encrypt } from 'libsignal/src/crypto.js'
|
|
2
|
-
import { SenderKeyMessage } from './sender-key-message.js'
|
|
3
|
-
import { SenderKeyName } from './sender-key-name.js'
|
|
4
|
-
import { SenderKeyRecord } from './sender-key-record.js'
|
|
5
|
-
import { SenderKeyState } from './sender-key-state.js'
|
|
1
|
+
import { decrypt, encrypt } from 'libsignal/src/crypto.js'
|
|
2
|
+
import { SenderKeyMessage } from './sender-key-message.js'
|
|
3
|
+
import { SenderKeyName } from './sender-key-name.js'
|
|
4
|
+
import { SenderKeyRecord } from './sender-key-record.js'
|
|
5
|
+
import { SenderKeyState } from './sender-key-state.js'
|
|
6
|
+
|
|
6
7
|
export class GroupCipher {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
constructor(senderKeyStore, senderKeyName) {
|
|
9
|
+
this.senderKeyStore = senderKeyStore
|
|
10
|
+
this.senderKeyName = senderKeyName
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async encrypt(paddedPlaintext) {
|
|
14
|
+
const record = await this.senderKeyStore.loadSenderKey(this.senderKeyName)
|
|
15
|
+
if (!record) throw new Error('No SenderKeyRecord found')
|
|
16
|
+
const state = record.getSenderKeyState()
|
|
17
|
+
if (!state) throw new Error('No session to encrypt')
|
|
18
|
+
const iteration = state.getSenderChainKey().getIteration()
|
|
19
|
+
const senderKey = this.getSenderKey(state, iteration === 0 ? 0 : iteration + 1)
|
|
20
|
+
const ciphertext = await this.getCipherText(senderKey.getIv(), senderKey.getCipherKey(), paddedPlaintext)
|
|
21
|
+
const msg = new SenderKeyMessage(state.getKeyId(), senderKey.getIteration(), ciphertext, state.getSigningKeyPrivate())
|
|
22
|
+
await this.senderKeyStore.storeSenderKey(this.senderKeyName, record)
|
|
23
|
+
return msg.serialize()
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async decrypt(senderKeyMessageBytes) {
|
|
27
|
+
let record = await this.senderKeyStore.loadSenderKey(this.senderKeyName)
|
|
28
|
+
if (!record) throw new Error('No SenderKeyRecord - requesting new session')
|
|
29
|
+
|
|
30
|
+
const msg = new SenderKeyMessage(null, null, null, null, senderKeyMessageBytes)
|
|
31
|
+
let state = record.getSenderKeyState(msg.getKeyId())
|
|
32
|
+
|
|
33
|
+
if (!state) {
|
|
34
|
+
const allStates = record.getSenderKeyStates?.() || []
|
|
35
|
+
if (allStates.length > 0) {
|
|
36
|
+
state = allStates[allStates.length - 1]
|
|
37
|
+
} else {
|
|
38
|
+
throw new Error(`No session found - keyId: ${msg.getKeyId()}`)
|
|
39
|
+
}
|
|
10
40
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const senderKeyState = record.getSenderKeyState();
|
|
17
|
-
if (!senderKeyState) {
|
|
18
|
-
throw new Error('No session to encrypt message');
|
|
19
|
-
}
|
|
20
|
-
const iteration = senderKeyState.getSenderChainKey().getIteration();
|
|
21
|
-
const senderKey = this.getSenderKey(senderKeyState, iteration === 0 ? 0 : iteration + 1);
|
|
22
|
-
const ciphertext = await this.getCipherText(senderKey.getIv(), senderKey.getCipherKey(), paddedPlaintext);
|
|
23
|
-
const senderKeyMessage = new SenderKeyMessage(senderKeyState.getKeyId(), senderKey.getIteration(), ciphertext, senderKeyState.getSigningKeyPrivate());
|
|
24
|
-
await this.senderKeyStore.storeSenderKey(this.senderKeyName, record);
|
|
25
|
-
return senderKeyMessage.serialize();
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
msg.verifySignature(state.getSigningKeyPublic())
|
|
44
|
+
} catch (e) {
|
|
45
|
+
throw new Error('Signature verification failed')
|
|
26
46
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
throw new Error('No session found to decrypt message');
|
|
36
|
-
}
|
|
37
|
-
senderKeyMessage.verifySignature(senderKeyState.getSigningKeyPublic());
|
|
38
|
-
const senderKey = this.getSenderKey(senderKeyState, senderKeyMessage.getIteration());
|
|
39
|
-
const plaintext = await this.getPlainText(senderKey.getIv(), senderKey.getCipherKey(), senderKeyMessage.getCipherText());
|
|
40
|
-
await this.senderKeyStore.storeSenderKey(this.senderKeyName, record);
|
|
41
|
-
return plaintext;
|
|
47
|
+
|
|
48
|
+
const senderKey = this.getSenderKey(state, msg.getIteration())
|
|
49
|
+
const plaintext = await this.getPlainText(senderKey.getIv(), senderKey.getCipherKey(), msg.getCipherText())
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
await this.senderKeyStore.storeSenderKey(this.senderKeyName, record)
|
|
53
|
+
} catch (e) {
|
|
54
|
+
// Non-critical: decryption succeeded
|
|
42
55
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
while (senderChainKey.getIteration() < iteration) {
|
|
59
|
-
senderKeyState.addSenderMessageKey(senderChainKey.getSenderMessageKey());
|
|
60
|
-
senderChainKey = senderChainKey.getNext();
|
|
61
|
-
}
|
|
62
|
-
senderKeyState.setSenderChainKey(senderChainKey.getNext());
|
|
63
|
-
return senderChainKey.getSenderMessageKey();
|
|
56
|
+
|
|
57
|
+
return plaintext
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
getSenderKey(state, iteration) {
|
|
61
|
+
let chainKey = state.getSenderChainKey()
|
|
62
|
+
|
|
63
|
+
if (chainKey.getIteration() > iteration) {
|
|
64
|
+
if (state.hasSenderMessageKey(iteration)) {
|
|
65
|
+
const key = state.removeSenderMessageKey(iteration)
|
|
66
|
+
if (!key) throw new Error('No sender message key')
|
|
67
|
+
return key
|
|
68
|
+
}
|
|
69
|
+
throw new Error(`Old counter: ${chainKey.getIteration()} vs ${iteration}`)
|
|
64
70
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
71
|
+
|
|
72
|
+
if (iteration - chainKey.getIteration() > 2000) throw new Error('Over 2000 messages ahead')
|
|
73
|
+
|
|
74
|
+
while (chainKey.getIteration() < iteration) {
|
|
75
|
+
state.addSenderMessageKey(chainKey.getSenderMessageKey())
|
|
76
|
+
chainKey = chainKey.getNext()
|
|
72
77
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
|
|
79
|
+
state.setSenderChainKey(chainKey.getNext())
|
|
80
|
+
return chainKey.getSenderMessageKey()
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async getPlainText(iv, key, ciphertext) {
|
|
84
|
+
try {
|
|
85
|
+
return decrypt(key, ciphertext, iv)
|
|
86
|
+
} catch (e) {
|
|
87
|
+
throw new Error('InvalidMessageException')
|
|
80
88
|
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async getCipherText(iv, key, plaintext) {
|
|
92
|
+
try {
|
|
93
|
+
return encrypt(key, plaintext, iv)
|
|
94
|
+
} catch (e) {
|
|
95
|
+
throw new Error('InvalidMessageException')
|
|
96
|
+
}
|
|
97
|
+
}
|
|
81
98
|
}
|
|
82
|
-
|
|
99
|
+
|
|
100
|
+
export default GroupCipher
|