@realvare/based 2.5.71 → 2.6.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 +28 -16
- package/lib/Signal/libsignal.js +21 -0
- package/lib/Socket/socket.js +406 -1
- package/lib/Types/Auth.d.ts +8 -1
- package/lib/Types/Contact.d.ts +6 -0
- package/lib/Types/Newsletter.d.ts +17 -74
- package/lib/Types/Signal.d.ts +6 -0
- package/lib/Types/Socket.d.ts +9 -0
- package/lib/Utils/auth-utils.js +10 -0
- package/lib/Utils/cache-manager.js +5 -0
- package/lib/Utils/index.js +1 -0
- package/lib/Utils/messages-media.js +15 -2
- package/lib/Utils/newsletter-utils.d.ts +2 -0
- package/lib/Utils/newsletter-utils.js +48 -0
- package/lib/Utils/validate-connection.js +144 -84
- package/lib/WABinary/jid-utils.js +10 -3
- package/package.json +1 -1
package/README.MD
CHANGED
|
@@ -27,41 +27,53 @@
|
|
|
27
27
|
|
|
28
28
|
## Indice
|
|
29
29
|
|
|
30
|
+
- [Indice](#indice)
|
|
30
31
|
- [✨ Caratteristiche Principali](#-caratteristiche-principali)
|
|
31
32
|
- [🚀 Guida Rapida](#-guida-rapida)
|
|
33
|
+
- [Esempio Base - Avvio Bot](#esempio-base---avvio-bot)
|
|
34
|
+
- [Esempio Anti-Ban - Configurazione consigliata per Evitare Ban](#esempio-anti-ban---configurazione-consigliata-per-evitare-ban)
|
|
32
35
|
- [📊 Gestione Avanzata Cache](#-gestione-avanzata-cache)
|
|
36
|
+
- [Configurazione Cache Avanzata](#configurazione-cache-avanzata)
|
|
33
37
|
- [🔍 Risoluzione Problemi](#-risoluzione-problemi)
|
|
38
|
+
- [Problemi di Connessione](#problemi-di-connessione)
|
|
39
|
+
- [Gestione Memoria](#gestione-memoria)
|
|
40
|
+
- [Logging Avanzato](#logging-avanzato)
|
|
41
|
+
- [Gestione Messaggi Base con LID/JID](#gestione-messaggi-base-con-lidjid)
|
|
34
42
|
- [📚 Documentazione API](#-documentazione-api)
|
|
35
|
-
- [🏗️ Metodi Fondamentali](
|
|
43
|
+
- [🏗️ Metodi Fondamentali](#️-metodi-fondamentali)
|
|
36
44
|
- [🎯 Eventi Principali](#-eventi-principali)
|
|
37
|
-
|
|
38
|
-
|
|
45
|
+
- [🎪 Messaggi e Funzionalità Interattive](#-messaggi-e-funzionalità-interattive)
|
|
46
|
+
- [Messaggi Base](#messaggi-base)
|
|
47
|
+
- [Testo con Formattazione](#testo-con-formattazione)
|
|
39
48
|
- [Media Base](#media-base)
|
|
40
49
|
- [Media Avanzati](#media-avanzati)
|
|
41
50
|
- [Messaggi Interattivi](#messaggi-interattivi)
|
|
51
|
+
- [Messaggi con Bottoni Semplici](#messaggi-con-bottoni-semplici)
|
|
52
|
+
- [Messaggi con Bottoni e Immagine](#messaggi-con-bottoni-e-immagine)
|
|
53
|
+
- [Messaggi Liste](#messaggi-liste)
|
|
42
54
|
- [Altri Messaggi](#altri-messaggi)
|
|
43
|
-
|
|
44
|
-
- [🎭 Funzionalità Gruppi](#-funzionalit
|
|
55
|
+
- [Gestione delle Risposte](#gestione-delle-risposte)
|
|
56
|
+
- [🎭 Funzionalità Gruppi](#-funzionalità-gruppi)
|
|
45
57
|
- [Gestione Base Gruppi](#gestione-base-gruppi)
|
|
46
58
|
- [Gestione Partecipanti](#gestione-partecipanti)
|
|
47
59
|
- [Impostazioni Gruppo](#impostazioni-gruppo)
|
|
48
60
|
- [Messaggi Gruppo Avanzati](#messaggi-gruppo-avanzati)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
61
|
+
- [🔧 Fix LID/JID nel Proprio Main e Handler](#-fix-lidjid-nel-proprio-main-e-handler)
|
|
62
|
+
- [Best Practices per LID/JID](#best-practices-per-lidjid)
|
|
63
|
+
- [Esempio Integrato in Main](#esempio-integrato-in-main)
|
|
64
|
+
- [Esempio Handler Personalizzato](#esempio-handler-personalizzato)
|
|
53
65
|
- [🚀 Cache Intelligente LID/JID](#-cache-intelligente-lidjid)
|
|
54
|
-
- [🛡️ Validazione JID Avanzata](
|
|
66
|
+
- [🛡️ Validazione JID Avanzata](#️-validazione-jid-avanzata)
|
|
55
67
|
- [📊 Logging Condizionale](#-logging-condizionale)
|
|
56
68
|
- [🔧 Configurazione Performance](#-configurazione-performance)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
- [🛡️ Sicurezza e Crittografia](
|
|
69
|
+
- [🧩 Eventi: LID e JID sempre disponibili (nuovo)](#-eventi-lid-e-jid-sempre-disponibili-nuovo)
|
|
70
|
+
- [⚙️ Configurazione Avanzata](#️-configurazione-avanzata)
|
|
71
|
+
- [🔧 Opzioni Complete per makeWASocket](#-opzioni-complete-per-makewasocket)
|
|
72
|
+
- [🛡️ Sicurezza e Crittografia](#️-sicurezza-e-crittografia)
|
|
61
73
|
- [🌐 Supporto e Community](#-supporto-e-community)
|
|
62
74
|
- [📞 Contatti e Risorse](#-contatti-e-risorse)
|
|
63
75
|
- [🙏 Ringraziamenti](#-ringraziamenti)
|
|
64
|
-
- [⚠️ Disclaimer
|
|
76
|
+
- [⚠️ Disclaimer \& Licenza](#️-disclaimer--licenza)
|
|
65
77
|
- [📋 Nota Legale](#-nota-legale)
|
|
66
78
|
- [📜 Licenza MIT](#-licenza-mit)
|
|
67
79
|
|
|
@@ -1234,4 +1246,4 @@ Vedi [LICENSE](LICENSE) per dettagli.
|
|
|
1234
1246
|
<br>
|
|
1235
1247
|
<img src="https://capsule-render.vercel.app/api?type=waving&color=gradient&customColorList=24&height=120§ion=footer&text=&fontSize=30&fontColor=ffffff&animation=fadeIn&fontAlignY=35"/>
|
|
1236
1248
|
|
|
1237
|
-
</div>
|
|
1249
|
+
</div>
|
package/lib/Signal/libsignal.js
CHANGED
|
@@ -42,7 +42,17 @@ const sender_key_record_1 = require("./Group/sender-key-record");
|
|
|
42
42
|
const Group_1 = require("./Group");
|
|
43
43
|
function makeLibSignalRepository(auth) {
|
|
44
44
|
const storage = signalStorage(auth);
|
|
45
|
+
const lidMapping = {
|
|
46
|
+
get: async (lid) => {
|
|
47
|
+
const { [lid]: pn } = await auth.keys.get('lid-mapping', [lid]);
|
|
48
|
+
return pn;
|
|
49
|
+
},
|
|
50
|
+
set: (lid, pn) => {
|
|
51
|
+
return auth.keys.set({ 'lid-mapping': { [lid]: pn } });
|
|
52
|
+
}
|
|
53
|
+
};
|
|
45
54
|
return {
|
|
55
|
+
lidMapping,
|
|
46
56
|
decryptGroupMessage({ group, authorJid, msg }) {
|
|
47
57
|
const senderName = jidToSignalSenderKeyName(group, authorJid);
|
|
48
58
|
const cipher = new Group_1.GroupCipher(storage, senderName);
|
|
@@ -107,6 +117,17 @@ function makeLibSignalRepository(auth) {
|
|
|
107
117
|
},
|
|
108
118
|
jidToSignalProtocolAddress(jid) {
|
|
109
119
|
return jidToSignalProtocolAddress(jid).toString();
|
|
120
|
+
},
|
|
121
|
+
getLidAddress(jid) {
|
|
122
|
+
const { user, device } = (0, WABinary_1.jidDecode)(jid);
|
|
123
|
+
return new libsignal.ProtocolAddress(user, device || 0);
|
|
124
|
+
},
|
|
125
|
+
getDeviceCanHandleLid() {
|
|
126
|
+
const { platform, pushname, verifiedName } = auth.creds;
|
|
127
|
+
if (platform === 'android' || platform === 'ios' || platform === 'smba' || platform === 'smbi') {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
return false;
|
|
110
131
|
}
|
|
111
132
|
};
|
|
112
133
|
}
|
package/lib/Socket/socket.js
CHANGED
|
@@ -429,7 +429,7 @@ const makeSocket = (config) => {
|
|
|
429
429
|
}
|
|
430
430
|
end(new boom_1.Boom(msg || 'Intentional Logout', { statusCode: Types_1.DisconnectReason.loggedOut }));
|
|
431
431
|
};
|
|
432
|
-
const requestPairingCode = async (phoneNumber, pairKey
|
|
432
|
+
const requestPairingCode = async (phoneNumber, pairKey) => {
|
|
433
433
|
if (pairKey) {
|
|
434
434
|
authState.creds.pairingCode = pairKey.toUpperCase();
|
|
435
435
|
}
|
|
@@ -688,6 +688,411 @@ const makeSocket = (config) => {
|
|
|
688
688
|
/** Waits for the connection to WA to reach a state */
|
|
689
689
|
waitForConnectionUpdate: (0, Utils_1.bindWaitForConnectionUpdate)(ev),
|
|
690
690
|
sendWAMBuffer,
|
|
691
|
+
sendPoll: async (jid, poll) => {
|
|
692
|
+
const { name, values, selectableCount } = poll;
|
|
693
|
+
if (!name || !values) {
|
|
694
|
+
throw new boom_1.Boom('name and values of poll are required');
|
|
695
|
+
}
|
|
696
|
+
const pollCreation = {
|
|
697
|
+
name,
|
|
698
|
+
values,
|
|
699
|
+
selectableCount: selectableCount || 1,
|
|
700
|
+
};
|
|
701
|
+
// @ts-ignore
|
|
702
|
+
return ws.sendMessage(jid, { poll: pollCreation });
|
|
703
|
+
},
|
|
704
|
+
// lid related functions
|
|
705
|
+
assertLid: (jid) => {
|
|
706
|
+
if (!(0, WABinary_1.isLid)(jid)) {
|
|
707
|
+
throw new boom_1.Boom(`JID "${jid}" is not a LID`, {
|
|
708
|
+
statusCode: 400
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
},
|
|
712
|
+
getLIDById: async (jid) => {
|
|
713
|
+
if ((0, WABinary_1.isLid)(jid)) {
|
|
714
|
+
return jid;
|
|
715
|
+
}
|
|
716
|
+
const lid = await signalRepository.lidMapping.get(jid);
|
|
717
|
+
if (lid) {
|
|
718
|
+
return lid;
|
|
719
|
+
}
|
|
720
|
+
},
|
|
721
|
+
getPNById: async (jid) => {
|
|
722
|
+
if (!(0, WABinary_1.isLid)(jid)) {
|
|
723
|
+
return jid;
|
|
724
|
+
}
|
|
725
|
+
const pn = await signalRepository.lidMapping.get(jid);
|
|
726
|
+
if (pn) {
|
|
727
|
+
return pn;
|
|
728
|
+
}
|
|
729
|
+
},
|
|
730
|
+
storeLidPnMapping: (lid, pn) => {
|
|
731
|
+
return signalRepository.lidMapping.set(lid, pn);
|
|
732
|
+
},
|
|
733
|
+
// newsletter functions
|
|
734
|
+
newsletterCreate: async (name, description) => {
|
|
735
|
+
const result = await query({
|
|
736
|
+
tag: 'iq',
|
|
737
|
+
attrs: {
|
|
738
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
739
|
+
type: 'set',
|
|
740
|
+
xmlns: 'newsletter'
|
|
741
|
+
},
|
|
742
|
+
content: [
|
|
743
|
+
{
|
|
744
|
+
tag: 'create',
|
|
745
|
+
attrs: {},
|
|
746
|
+
content: [
|
|
747
|
+
{
|
|
748
|
+
tag: 'name',
|
|
749
|
+
attrs: {},
|
|
750
|
+
content: name
|
|
751
|
+
},
|
|
752
|
+
{
|
|
753
|
+
tag: 'description',
|
|
754
|
+
attrs: {},
|
|
755
|
+
content: description
|
|
756
|
+
}
|
|
757
|
+
]
|
|
758
|
+
}
|
|
759
|
+
]
|
|
760
|
+
});
|
|
761
|
+
const node = (0, WABinary_1.getBinaryNodeChild)(result, 'newsletter');
|
|
762
|
+
const metadata = (0, Utils_1.parseNewsletterMetadata)(node);
|
|
763
|
+
return metadata;
|
|
764
|
+
},
|
|
765
|
+
getNewsletterInfo: async (jid) => {
|
|
766
|
+
const result = await query({
|
|
767
|
+
tag: 'iq',
|
|
768
|
+
attrs: {
|
|
769
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
770
|
+
type: 'get',
|
|
771
|
+
xmlns: 'newsletter'
|
|
772
|
+
},
|
|
773
|
+
content: [
|
|
774
|
+
{
|
|
775
|
+
tag: 'newsletter',
|
|
776
|
+
attrs: {
|
|
777
|
+
id: jid,
|
|
778
|
+
type: 'invite'
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
]
|
|
782
|
+
});
|
|
783
|
+
const node = (0, WABinary_1.getBinaryNodeChild)(result, 'newsletter');
|
|
784
|
+
const metadata = (0, Utils_1.parseNewsletterMetadata)(node);
|
|
785
|
+
return metadata;
|
|
786
|
+
},
|
|
787
|
+
getNewsletterMessage: async (jid, serverId) => {
|
|
788
|
+
const result = await query({
|
|
789
|
+
tag: 'iq',
|
|
790
|
+
attrs: {
|
|
791
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
792
|
+
type: 'get',
|
|
793
|
+
xmlns: 'newsletter'
|
|
794
|
+
},
|
|
795
|
+
content: [
|
|
796
|
+
{
|
|
797
|
+
tag: 'messages',
|
|
798
|
+
attrs: {
|
|
799
|
+
id: jid,
|
|
800
|
+
'server-id': serverId
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
]
|
|
804
|
+
});
|
|
805
|
+
const messages = (0, WABinary_1.getBinaryNodeChild)(result, 'messages');
|
|
806
|
+
const message = (0, WABinary_1.getBinaryNodeChild)(messages, 'message');
|
|
807
|
+
return (0, Utils_1.parseNewsletterMessage)(message);
|
|
808
|
+
},
|
|
809
|
+
updateNewsletterMute: async (jid, mute) => {
|
|
810
|
+
const result = await query({
|
|
811
|
+
tag: 'iq',
|
|
812
|
+
attrs: {
|
|
813
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
814
|
+
type: 'set',
|
|
815
|
+
xmlns: 'newsletter'
|
|
816
|
+
},
|
|
817
|
+
content: [
|
|
818
|
+
{
|
|
819
|
+
tag: 'mute',
|
|
820
|
+
attrs: {
|
|
821
|
+
id: jid,
|
|
822
|
+
value: mute ? 'true' : 'false'
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
]
|
|
826
|
+
});
|
|
827
|
+
const node = (0, WABinary_1.getBinaryNodeChild)(result, 'newsletter');
|
|
828
|
+
const metadata = (0, Utils_1.parseNewsletterMetadata)(node);
|
|
829
|
+
return metadata;
|
|
830
|
+
},
|
|
831
|
+
toggleNewsletterSubscribe: async (jid, subscribe) => {
|
|
832
|
+
const result = await query({
|
|
833
|
+
tag: 'iq',
|
|
834
|
+
attrs: {
|
|
835
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
836
|
+
type: 'set',
|
|
837
|
+
xmlns: 'newsletter'
|
|
838
|
+
},
|
|
839
|
+
content: [
|
|
840
|
+
{
|
|
841
|
+
tag: subscribe ? 'subscribe' : 'unsubscribe',
|
|
842
|
+
attrs: {
|
|
843
|
+
id: jid
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
]
|
|
847
|
+
});
|
|
848
|
+
const node = (0, WABinary_1.getBinaryNodeChild)(result, 'newsletter');
|
|
849
|
+
const metadata = (0, Utils_1.parseNewsletterMetadata)(node);
|
|
850
|
+
return metadata;
|
|
851
|
+
},
|
|
852
|
+
sendNewsletterMessage: async (jid, content) => {
|
|
853
|
+
const result = await ws.sendMessage(jid, content);
|
|
854
|
+
return result;
|
|
855
|
+
},
|
|
856
|
+
getNewsletterMessages: async (jid, count, after) => {
|
|
857
|
+
const attrs = {
|
|
858
|
+
id: jid,
|
|
859
|
+
count: count.toString(),
|
|
860
|
+
};
|
|
861
|
+
if (after) {
|
|
862
|
+
attrs.after = after.toString();
|
|
863
|
+
}
|
|
864
|
+
const result = await query({
|
|
865
|
+
tag: 'iq',
|
|
866
|
+
attrs: {
|
|
867
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
868
|
+
type: 'get',
|
|
869
|
+
xmlns: 'newsletter'
|
|
870
|
+
},
|
|
871
|
+
content: [
|
|
872
|
+
{
|
|
873
|
+
tag: 'messages',
|
|
874
|
+
attrs
|
|
875
|
+
}
|
|
876
|
+
]
|
|
877
|
+
});
|
|
878
|
+
const messages = (0, WABinary_1.getBinaryNodeChild)(result, 'messages');
|
|
879
|
+
const messageNodes = (0, WABinary_1.getBinaryNodeChildren)(messages, 'message');
|
|
880
|
+
return messageNodes.map(Utils_1.parseNewsletterMessage);
|
|
881
|
+
},
|
|
882
|
+
// contact functions
|
|
883
|
+
addOrEditContact: async (jid, action) => {
|
|
884
|
+
const result = await query({
|
|
885
|
+
tag: 'iq',
|
|
886
|
+
attrs: {
|
|
887
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
888
|
+
type: 'set',
|
|
889
|
+
xmlns: 'contact'
|
|
890
|
+
},
|
|
891
|
+
content: [
|
|
892
|
+
{
|
|
893
|
+
tag: 'contact',
|
|
894
|
+
attrs: {
|
|
895
|
+
jid,
|
|
896
|
+
...action
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
]
|
|
900
|
+
});
|
|
901
|
+
return result;
|
|
902
|
+
},
|
|
903
|
+
removeContact: async (jid) => {
|
|
904
|
+
const result = await query({
|
|
905
|
+
tag: 'iq',
|
|
906
|
+
attrs: {
|
|
907
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
908
|
+
type: 'set',
|
|
909
|
+
xmlns: 'contact'
|
|
910
|
+
},
|
|
911
|
+
content: [
|
|
912
|
+
{
|
|
913
|
+
tag: 'contact',
|
|
914
|
+
attrs: {
|
|
915
|
+
jid,
|
|
916
|
+
type: 'remove'
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
]
|
|
920
|
+
});
|
|
921
|
+
return result;
|
|
922
|
+
},
|
|
923
|
+
// profile functions
|
|
924
|
+
updateProfilePicture: async (jid, content, options) => {
|
|
925
|
+
const { img } = await (0, Utils_1.generateProfilePicture)(content);
|
|
926
|
+
const result = await query({
|
|
927
|
+
tag: 'iq',
|
|
928
|
+
attrs: {
|
|
929
|
+
to: jid,
|
|
930
|
+
type: 'set',
|
|
931
|
+
xmlns: 'w:profile:picture'
|
|
932
|
+
},
|
|
933
|
+
content: [
|
|
934
|
+
{
|
|
935
|
+
tag: 'picture',
|
|
936
|
+
attrs: {
|
|
937
|
+
type: 'image',
|
|
938
|
+
...options
|
|
939
|
+
},
|
|
940
|
+
content: img
|
|
941
|
+
}
|
|
942
|
+
]
|
|
943
|
+
});
|
|
944
|
+
return result;
|
|
945
|
+
},
|
|
946
|
+
updateProfileName: async (name) => {
|
|
947
|
+
const result = await sendNode({
|
|
948
|
+
tag: 'presence',
|
|
949
|
+
attrs: {
|
|
950
|
+
name,
|
|
951
|
+
type: 'available'
|
|
952
|
+
}
|
|
953
|
+
});
|
|
954
|
+
return result;
|
|
955
|
+
},
|
|
956
|
+
updateProfileStatus: async (status) => {
|
|
957
|
+
const result = await query({
|
|
958
|
+
tag: 'iq',
|
|
959
|
+
attrs: {
|
|
960
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
961
|
+
type: 'set',
|
|
962
|
+
xmlns: 'status'
|
|
963
|
+
},
|
|
964
|
+
content: [
|
|
965
|
+
{
|
|
966
|
+
tag: 'status',
|
|
967
|
+
attrs: {},
|
|
968
|
+
content: Buffer.from(status, 'utf-8')
|
|
969
|
+
}
|
|
970
|
+
]
|
|
971
|
+
});
|
|
972
|
+
return result;
|
|
973
|
+
},
|
|
974
|
+
updateLastSeenPrivacy: async (value) => {
|
|
975
|
+
const result = await query({
|
|
976
|
+
tag: 'iq',
|
|
977
|
+
attrs: {
|
|
978
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
979
|
+
type: 'set',
|
|
980
|
+
xmlns: 'privacy'
|
|
981
|
+
},
|
|
982
|
+
content: [
|
|
983
|
+
{
|
|
984
|
+
tag: 'privacy',
|
|
985
|
+
attrs: {},
|
|
986
|
+
content: [
|
|
987
|
+
{
|
|
988
|
+
tag: 'last',
|
|
989
|
+
attrs: {
|
|
990
|
+
value
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
]
|
|
994
|
+
}
|
|
995
|
+
]
|
|
996
|
+
});
|
|
997
|
+
return result;
|
|
998
|
+
},
|
|
999
|
+
updateOnlinePrivacy: async (value) => {
|
|
1000
|
+
const result = await query({
|
|
1001
|
+
tag: 'iq',
|
|
1002
|
+
attrs: {
|
|
1003
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
1004
|
+
type: 'set',
|
|
1005
|
+
xmlns: 'privacy'
|
|
1006
|
+
},
|
|
1007
|
+
content: [
|
|
1008
|
+
{
|
|
1009
|
+
tag: 'privacy',
|
|
1010
|
+
attrs: {},
|
|
1011
|
+
content: [
|
|
1012
|
+
{
|
|
1013
|
+
tag: 'online',
|
|
1014
|
+
attrs: {
|
|
1015
|
+
value
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
]
|
|
1019
|
+
}
|
|
1020
|
+
]
|
|
1021
|
+
});
|
|
1022
|
+
return result;
|
|
1023
|
+
},
|
|
1024
|
+
updateProfilePicturePrivacy: async (value) => {
|
|
1025
|
+
const result = await query({
|
|
1026
|
+
tag: 'iq',
|
|
1027
|
+
attrs: {
|
|
1028
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
1029
|
+
type: 'set',
|
|
1030
|
+
xmlns: 'privacy'
|
|
1031
|
+
},
|
|
1032
|
+
content: [
|
|
1033
|
+
{
|
|
1034
|
+
tag: 'privacy',
|
|
1035
|
+
attrs: {},
|
|
1036
|
+
content: [
|
|
1037
|
+
{
|
|
1038
|
+
tag: 'profile',
|
|
1039
|
+
attrs: {
|
|
1040
|
+
value
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
]
|
|
1044
|
+
}
|
|
1045
|
+
]
|
|
1046
|
+
});
|
|
1047
|
+
return result;
|
|
1048
|
+
},
|
|
1049
|
+
fetchStatus: async (jid) => {
|
|
1050
|
+
const result = await query({
|
|
1051
|
+
tag: 'iq',
|
|
1052
|
+
attrs: {
|
|
1053
|
+
to: jid,
|
|
1054
|
+
type: 'get',
|
|
1055
|
+
xmlns: 'status'
|
|
1056
|
+
}
|
|
1057
|
+
});
|
|
1058
|
+
const node = (0, WABinary_1.getBinaryNodeChild)(result, 'status');
|
|
1059
|
+
return {
|
|
1060
|
+
status: node === null || node === void 0 ? void 0 : node.content.toString(),
|
|
1061
|
+
setAt: new Date(+(node === null || node === void 0 ? void 0 : node.attrs.t) * 1000)
|
|
1062
|
+
};
|
|
1063
|
+
},
|
|
1064
|
+
fetchBlocklist: async () => {
|
|
1065
|
+
const result = await query({
|
|
1066
|
+
tag: 'iq',
|
|
1067
|
+
attrs: {
|
|
1068
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
1069
|
+
type: 'get',
|
|
1070
|
+
xmlns: 'blocklist'
|
|
1071
|
+
}
|
|
1072
|
+
});
|
|
1073
|
+
const node = (0, WABinary_1.getBinaryNodeChild)(result, 'list');
|
|
1074
|
+
return (0, WABinary_1.getBinaryNodeChildren)(node, 'item').map(i => i.attrs.jid);
|
|
1075
|
+
},
|
|
1076
|
+
blocklistUpdate: async (jid, action) => {
|
|
1077
|
+
const result = await query({
|
|
1078
|
+
tag: 'iq',
|
|
1079
|
+
attrs: {
|
|
1080
|
+
to: WABinary_1.S_WHATSAPP_NET,
|
|
1081
|
+
type: 'set',
|
|
1082
|
+
xmlns: 'blocklist'
|
|
1083
|
+
},
|
|
1084
|
+
content: [
|
|
1085
|
+
{
|
|
1086
|
+
tag: 'item',
|
|
1087
|
+
attrs: {
|
|
1088
|
+
jid,
|
|
1089
|
+
action
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
]
|
|
1093
|
+
});
|
|
1094
|
+
return result;
|
|
1095
|
+
}
|
|
691
1096
|
};
|
|
692
1097
|
};
|
|
693
1098
|
exports.makeSocket = makeSocket;
|
package/lib/Types/Auth.d.ts
CHANGED
|
@@ -43,7 +43,9 @@ export type AuthenticationCreds = SignalCreds & {
|
|
|
43
43
|
readonly noiseKey: KeyPair;
|
|
44
44
|
readonly pairingEphemeralKeyPair: KeyPair;
|
|
45
45
|
advSecretKey: string;
|
|
46
|
-
me?: Contact
|
|
46
|
+
me?: Omit<Contact, 'imgUrl'> & {
|
|
47
|
+
lid?: string;
|
|
48
|
+
};
|
|
47
49
|
account?: proto.IADVSignedDeviceIdentity;
|
|
48
50
|
signalIdentities?: SignalIdentity[];
|
|
49
51
|
myAppStateKeyId?: string;
|
|
@@ -51,6 +53,8 @@ export type AuthenticationCreds = SignalCreds & {
|
|
|
51
53
|
nextPreKeyId: number;
|
|
52
54
|
lastAccountSyncTimestamp?: number;
|
|
53
55
|
platform?: string;
|
|
56
|
+
deviceIndex?: number;
|
|
57
|
+
historySyncConfig?: proto.IHistorySyncConfig;
|
|
54
58
|
processedHistoryMessages: MinimalMessage[];
|
|
55
59
|
/** number of times history & app state has been synced */
|
|
56
60
|
accountSyncCounter: number;
|
|
@@ -69,6 +73,9 @@ export type SignalDataTypeMap = {
|
|
|
69
73
|
};
|
|
70
74
|
'app-state-sync-key': proto.Message.IAppStateSyncKeyData;
|
|
71
75
|
'app-state-sync-version': LTHashState;
|
|
76
|
+
'lid-mapping': {
|
|
77
|
+
[lid: string]: string;
|
|
78
|
+
};
|
|
72
79
|
};
|
|
73
80
|
export type SignalDataSet = {
|
|
74
81
|
[T in keyof SignalDataTypeMap]?: {
|
package/lib/Types/Contact.d.ts
CHANGED
|
@@ -1,79 +1,22 @@
|
|
|
1
|
-
import { proto } from '../../WAProto';
|
|
2
|
-
export type NewsletterReactionMode = 'ALL' | 'BASIC' | 'NONE';
|
|
3
|
-
export type NewsletterState = 'ACTIVE' | 'GEOSUSPENDED' | 'SUSPENDED';
|
|
4
|
-
export type NewsletterVerification = 'VERIFIED' | 'UNVERIFIED';
|
|
5
|
-
export type NewsletterMute = 'ON' | 'OFF' | 'UNDEFINED';
|
|
6
|
-
export type NewsletterViewRole = 'ADMIN' | 'GUEST' | 'OWNER' | 'SUBSCRIBER';
|
|
7
|
-
export type NewsletterViewerMetadata = {
|
|
8
|
-
mute: NewsletterMute;
|
|
9
|
-
view_role: NewsletterViewRole;
|
|
10
|
-
};
|
|
1
|
+
import type { proto } from '../../WAProto';
|
|
11
2
|
export type NewsletterMetadata = {
|
|
12
|
-
/**jid of newsletter */
|
|
13
3
|
id: string;
|
|
14
|
-
/**state of newsletter */
|
|
15
|
-
state: NewsletterState;
|
|
16
|
-
/**creation timestamp of newsletter */
|
|
17
|
-
creation_time: number;
|
|
18
|
-
/**name of newsletter */
|
|
19
4
|
name: string;
|
|
20
|
-
/**timestamp of last name modification of newsletter */
|
|
21
|
-
nameTime: number;
|
|
22
|
-
/**description of newsletter */
|
|
23
5
|
description: string;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
reaction_codes?: NewsletterReactionMode;
|
|
36
|
-
/**subscribers count of newsletter */
|
|
37
|
-
subscribers: number;
|
|
38
|
-
/**verification state of newsletter */
|
|
39
|
-
verification: NewsletterVerification;
|
|
40
|
-
/**viewer metadata */
|
|
41
|
-
viewer_metadata: NewsletterViewerMetadata;
|
|
42
|
-
};
|
|
43
|
-
export type SubscriberAction = 'promote' | 'demote';
|
|
44
|
-
export type ReactionModeUpdate = {
|
|
45
|
-
reaction_codes: {
|
|
46
|
-
blocked_codes: null;
|
|
47
|
-
enabled_ts_sec: null;
|
|
48
|
-
value: NewsletterReactionMode;
|
|
49
|
-
};
|
|
50
|
-
};
|
|
51
|
-
/**only exists reaction mode update */
|
|
52
|
-
export type NewsletterSettingsUpdate = ReactionModeUpdate;
|
|
53
|
-
export type NewsletterReaction = {
|
|
54
|
-
count: number;
|
|
55
|
-
code: string;
|
|
56
|
-
};
|
|
57
|
-
export type NewsletterFetchedUpdate = {
|
|
58
|
-
/**id of message in newsletter, starts from 100 */
|
|
59
|
-
server_id: string;
|
|
60
|
-
/**count of views in this message */
|
|
61
|
-
views?: number;
|
|
62
|
-
/**reactions in this message */
|
|
63
|
-
reactions: NewsletterReaction[];
|
|
64
|
-
/**the message, if you requested only updates, you will not receive message */
|
|
65
|
-
message?: proto.IWebMessageInfo;
|
|
6
|
+
inviteCode: string;
|
|
7
|
+
handle: string;
|
|
8
|
+
subscriberCount: number;
|
|
9
|
+
verification: 'VERIFIED' | 'UNVERIFIED';
|
|
10
|
+
picture?: string;
|
|
11
|
+
preview?: string;
|
|
12
|
+
creationTime: number;
|
|
13
|
+
muted: boolean;
|
|
14
|
+
state: 'ACTIVE' | 'SUSPENDED' | 'GEOSUSPENDED';
|
|
15
|
+
viewRole: 'ADMIN' | 'GUEST' | 'SUBSCRIBER';
|
|
16
|
+
subscribe: 'SUBSCRIBED' | 'UNSUBSCRIBED';
|
|
66
17
|
};
|
|
67
|
-
export
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
export declare enum XWAPaths {
|
|
73
|
-
PROMOTE = "xwa2_notify_newsletter_admin_promote",
|
|
74
|
-
DEMOTE = "xwa2_notify_newsletter_admin_demote",
|
|
75
|
-
ADMIN_COUNT = "xwa2_newsletter_admin",
|
|
76
|
-
CREATE = "xwa2_newsletter_create",
|
|
77
|
-
NEWSLETTER = "xwa2_newsletter",
|
|
78
|
-
METADATA_UPDATE = "xwa2_notify_newsletter_on_metadata_update"
|
|
79
|
-
}
|
|
18
|
+
export type NewsletterMessage = {
|
|
19
|
+
serverMsgId: number;
|
|
20
|
+
views: number;
|
|
21
|
+
message: proto.IWebMessageInfo;
|
|
22
|
+
};
|
package/lib/Types/Signal.d.ts
CHANGED
|
@@ -40,6 +40,10 @@ type E2ESessionOpts = {
|
|
|
40
40
|
session: E2ESession;
|
|
41
41
|
};
|
|
42
42
|
export type SignalRepository = {
|
|
43
|
+
lidMapping: {
|
|
44
|
+
get: (lid: string) => Promise<string | undefined>;
|
|
45
|
+
set: (lid: string, pn: string) => Promise<void>;
|
|
46
|
+
};
|
|
43
47
|
decryptGroupMessage(opts: DecryptGroupSignalOpts): Promise<Uint8Array>;
|
|
44
48
|
processSenderKeyDistributionMessage(opts: ProcessSenderKeyDistributionMessageOpts): Promise<void>;
|
|
45
49
|
decryptMessage(opts: DecryptSignalProtoOpts): Promise<Uint8Array>;
|
|
@@ -53,5 +57,7 @@ export type SignalRepository = {
|
|
|
53
57
|
}>;
|
|
54
58
|
injectE2ESession(opts: E2ESessionOpts): Promise<void>;
|
|
55
59
|
jidToSignalProtocolAddress(jid: string): string;
|
|
60
|
+
getLidAddress(jid: string): any;
|
|
61
|
+
getDeviceCanHandleLid(): boolean;
|
|
56
62
|
};
|
|
57
63
|
export {};
|
package/lib/Types/Socket.d.ts
CHANGED
|
@@ -115,5 +115,14 @@ export type SocketConfig = {
|
|
|
115
115
|
getMessage: (key: proto.IMessageKey) => Promise<proto.IMessage | undefined>;
|
|
116
116
|
/** cached group metadata, use to prevent redundant requests to WA & speed up msg sending */
|
|
117
117
|
cachedGroupMetadata: (jid: string) => Promise<GroupMetadata | undefined>;
|
|
118
|
+
/** makeSignalRepository */
|
|
118
119
|
makeSignalRepository: (auth: SignalAuthState) => SignalRepository;
|
|
120
|
+
/**
|
|
121
|
+
* Meta-coexistence on WhatsApp Web
|
|
122
|
+
*/
|
|
123
|
+
coexistence?: boolean;
|
|
124
|
+
/**
|
|
125
|
+
* The number of messages to fetch at a time when interacting with newsletters
|
|
126
|
+
*/
|
|
127
|
+
newsletterPageSize?: number;
|
|
119
128
|
};
|
package/lib/Utils/auth-utils.js
CHANGED
|
@@ -190,6 +190,16 @@ const initAuthCreds = () => {
|
|
|
190
190
|
accountSettings: {
|
|
191
191
|
unarchiveChats: false
|
|
192
192
|
},
|
|
193
|
+
// ADVSignedDeviceIdentity
|
|
194
|
+
account: undefined,
|
|
195
|
+
// me: Omit<Contact, 'imgUrl'> & { lid?: string }
|
|
196
|
+
me: undefined,
|
|
197
|
+
// signalIdentities: SignalIdentity[]
|
|
198
|
+
signalIdentities: undefined,
|
|
199
|
+
platform: undefined,
|
|
200
|
+
myAppStateKeyId: undefined,
|
|
201
|
+
lastAccountSyncTimestamp: undefined,
|
|
202
|
+
historySyncConfig: undefined,
|
|
193
203
|
registered: false,
|
|
194
204
|
pairingCode: undefined,
|
|
195
205
|
lastPropHash: undefined,
|
|
@@ -54,6 +54,11 @@ class CacheManager {
|
|
|
54
54
|
return this.caches[cacheName]?.set(key, value, ttl);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
async setAsync(cacheName, key, fetchData, ttl = undefined) {
|
|
58
|
+
const value = await fetchData();
|
|
59
|
+
return this.set(cacheName, key, value, ttl);
|
|
60
|
+
}
|
|
61
|
+
|
|
57
62
|
del(cacheName, key) {
|
|
58
63
|
return this.caches[cacheName]?.del(key);
|
|
59
64
|
}
|
package/lib/Utils/index.js
CHANGED
|
@@ -32,3 +32,4 @@ __exportStar(require("./link-preview"), exports);
|
|
|
32
32
|
__exportStar(require("./event-buffer"), exports);
|
|
33
33
|
__exportStar(require("./process-message"), exports);
|
|
34
34
|
__exportStar(require("./performance-config"), exports);
|
|
35
|
+
__exportStar(require("./newsletter-utils"), exports);
|
|
@@ -479,8 +479,21 @@ async function generateThumbnail(file, mediaType, options) {
|
|
|
479
479
|
};
|
|
480
480
|
}
|
|
481
481
|
const getHttpStream = async (url, options = {}) => {
|
|
482
|
-
const
|
|
483
|
-
|
|
482
|
+
const { retryRequestDelayMs, maxMsgRetryCount } = options;
|
|
483
|
+
let retries = 0;
|
|
484
|
+
while (retries < maxMsgRetryCount) {
|
|
485
|
+
try {
|
|
486
|
+
const fetched = await axios_1.default.get(url.toString(), { ...options, responseType: 'stream' });
|
|
487
|
+
return fetched.data;
|
|
488
|
+
}
|
|
489
|
+
catch (error) {
|
|
490
|
+
retries++;
|
|
491
|
+
if (retries >= maxMsgRetryCount) {
|
|
492
|
+
throw error;
|
|
493
|
+
}
|
|
494
|
+
await (0, generics_1.delay)(retryRequestDelayMs || 1000);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
484
497
|
};
|
|
485
498
|
exports.getHttpStream = getHttpStream;
|
|
486
499
|
const prepareStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseNewsletterMessage = exports.parseNewsletterMetadata = void 0;
|
|
4
|
+
const WABinary_1 = require("../WABinary");
|
|
5
|
+
const generics_1 = require("./generics");
|
|
6
|
+
const parseNewsletterMetadata = (node) => {
|
|
7
|
+
const newsletter = (0, WABinary_1.getBinaryNodeChild)(node, 'newsletter');
|
|
8
|
+
const name = (0, WABinary_1.getBinaryNodeChild)(newsletter, 'name');
|
|
9
|
+
const description = (0, WABinary_1.getBinaryNodeChild)(newsletter, 'description');
|
|
10
|
+
const invite = (0, WABinary_1.getBinaryNodeChild)(newsletter, 'invite');
|
|
11
|
+
const handle = (0, WABinary_1.getBinaryNodeChild)(newsletter, 'handle');
|
|
12
|
+
const verification = (0, WABinary_1.getBinaryNodeChild)(newsletter, 'verification');
|
|
13
|
+
const picture = (0, WABinary_1.getBinaryNodeChild)(newsletter, 'picture');
|
|
14
|
+
const preview = (0, WABinary_1.getBinaryNodeChild)(newsletter, 'preview');
|
|
15
|
+
const creationTime = (0, WABinary_1.getBinaryNodeChild)(newsletter, 'creation_time');
|
|
16
|
+
const state = (0, WABinary_1.getBinaryNodeChild)(newsletter, 'state');
|
|
17
|
+
const subscribers = (0, WABinary_1.getBinaryNodeChild)(newsletter, 'subscribers');
|
|
18
|
+
const viewRole = (0, WABinary_1.getBinaryNodeChild)(newsletter, 'view_role');
|
|
19
|
+
const subscribe = (0, WABinary_1.getBinaryNodeChild)(newsletter, 'subscribe');
|
|
20
|
+
const muted = (0, WABinary_1.getBinaryNodeChild)(newsletter, 'mute');
|
|
21
|
+
return {
|
|
22
|
+
id: newsletter.attrs.id,
|
|
23
|
+
name: name === null || name === void 0 ? void 0 : name.content.toString(),
|
|
24
|
+
description: description === null || description === void 0 ? void 0 : description.content.toString(),
|
|
25
|
+
inviteCode: invite === null || invite === void 0 ? void 0 : invite.content.toString(),
|
|
26
|
+
handle: handle === null || handle === void 0 ? void 0 : handle.content.toString(),
|
|
27
|
+
subscriberCount: +(subscribers === null || subscribers === void 0 ? void 0 : subscribers.content.toString()),
|
|
28
|
+
verification: verification === null || verification === void 0 ? void 0 : verification.content.toString(),
|
|
29
|
+
picture: picture === null || picture === void 0 ? void 0 : picture.content.toString(),
|
|
30
|
+
preview: preview === null || preview === void 0 ? void 0 : preview.content.toString(),
|
|
31
|
+
creationTime: +(creationTime === null || creationTime === void 0 ? void 0 : creationTime.content.toString()),
|
|
32
|
+
muted: (muted === null || muted === void 0 ? void 0 : muted.content.toString()) === 'true',
|
|
33
|
+
state: state === null || state === void 0 ? void 0 : state.content.toString(),
|
|
34
|
+
viewRole: viewRole === null || viewRole === void 0 ? void 0 : viewRole.content.toString(),
|
|
35
|
+
subscribe: subscribe === null || subscribe === void 0 ? void 0 : subscribe.content.toString(),
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
exports.parseNewsletterMetadata = parseNewsletterMetadata;
|
|
39
|
+
const parseNewsletterMessage = (node) => {
|
|
40
|
+
const message = (0, WABinary_1.getBinaryNodeChild)(node, 'message');
|
|
41
|
+
const views = (0, WABinary_1.getBinaryNodeChild)(node, 'views');
|
|
42
|
+
return {
|
|
43
|
+
serverMsgId: +(node.attrs.server_id || 0),
|
|
44
|
+
views: +(views === null || views === void 0 ? void 0 : views.content.toString()),
|
|
45
|
+
message: (0, generics_1.normalizeMessageContent)(message),
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
exports.parseNewsletterMessage = parseNewsletterMessage;
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
"use strict"
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
1
|
+
"use strict"
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
|
+
|
|
5
|
+
const boom_1 = require("@hapi/boom")
|
|
6
|
+
const crypto_1 = require("crypto")
|
|
7
|
+
const WAProto_1 = require("../../WAProto")
|
|
8
|
+
const Defaults_1 = require("../Defaults")
|
|
9
|
+
const WABinary_1 = require("../WABinary")
|
|
10
|
+
const crypto_2 = require("./crypto")
|
|
11
|
+
const generics_1 = require("./generics")
|
|
12
|
+
const signal_1 = require("./signal")
|
|
13
|
+
|
|
12
14
|
const getUserAgent = (config) => {
|
|
13
15
|
return {
|
|
14
16
|
appVersion: {
|
|
@@ -22,57 +24,93 @@ const getUserAgent = (config) => {
|
|
|
22
24
|
device: 'Desktop',
|
|
23
25
|
osBuildNumber: '0.1',
|
|
24
26
|
localeLanguageIso6391: 'en',
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
mnc: '000',
|
|
28
|
+
mcc: '000',
|
|
29
|
+
localeCountryIso31661Alpha2: config.countryCode
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
28
33
|
const PLATFORM_MAP = {
|
|
29
34
|
'Mac OS': WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.DARWIN,
|
|
30
|
-
'Windows': WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WIN32
|
|
31
|
-
|
|
35
|
+
'Windows': WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WIN32,
|
|
36
|
+
'Android': WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WIN_HYBRID
|
|
37
|
+
}
|
|
38
|
+
|
|
32
39
|
const getWebInfo = (config) => {
|
|
33
|
-
let webSubPlatform = WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER
|
|
40
|
+
let webSubPlatform = WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER
|
|
34
41
|
if (config.syncFullHistory && PLATFORM_MAP[config.browser[0]]) {
|
|
35
|
-
webSubPlatform = PLATFORM_MAP[config.browser[0]]
|
|
42
|
+
webSubPlatform = PLATFORM_MAP[config.browser[0]]
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
webSubPlatform,
|
|
46
|
+
coexistence: config.coexistence,
|
|
36
47
|
}
|
|
37
|
-
|
|
38
|
-
|
|
48
|
+
}
|
|
49
|
+
|
|
39
50
|
const getClientPayload = (config) => {
|
|
40
51
|
const payload = {
|
|
41
52
|
connectType: WAProto_1.proto.ClientPayload.ConnectType.WIFI_UNKNOWN,
|
|
42
53
|
connectReason: WAProto_1.proto.ClientPayload.ConnectReason.USER_ACTIVATED,
|
|
43
54
|
userAgent: getUserAgent(config),
|
|
44
|
-
}
|
|
45
|
-
payload.webInfo = getWebInfo(config)
|
|
46
|
-
return payload
|
|
47
|
-
}
|
|
55
|
+
}
|
|
56
|
+
payload.webInfo = getWebInfo(config)
|
|
57
|
+
return payload
|
|
58
|
+
}
|
|
59
|
+
|
|
48
60
|
const generateLoginNode = (userJid, config) => {
|
|
49
|
-
const { user, device } =
|
|
61
|
+
const { user, device } = WABinary_1.jidDecode(userJid)
|
|
50
62
|
const payload = {
|
|
51
63
|
...getClientPayload(config),
|
|
52
64
|
passive: false,
|
|
53
65
|
pull: true,
|
|
54
66
|
username: +user,
|
|
55
67
|
device: device,
|
|
56
|
-
}
|
|
57
|
-
return WAProto_1.proto.ClientPayload.fromObject(payload)
|
|
58
|
-
}
|
|
59
|
-
|
|
68
|
+
}
|
|
69
|
+
return WAProto_1.proto.ClientPayload.fromObject(payload)
|
|
70
|
+
}
|
|
71
|
+
|
|
60
72
|
const getPlatformType = (platform) => {
|
|
61
|
-
const platformType = platform.toUpperCase()
|
|
62
|
-
return WAProto_1.proto.DeviceProps.PlatformType[platformType] || WAProto_1.proto.DeviceProps.PlatformType.DESKTOP
|
|
63
|
-
}
|
|
73
|
+
const platformType = platform.toUpperCase()
|
|
74
|
+
return WAProto_1.proto.DeviceProps.PlatformType[platformType] || WAProto_1.proto.DeviceProps.PlatformType.DESKTOP
|
|
75
|
+
}
|
|
76
|
+
|
|
64
77
|
const generateRegistrationNode = ({ registrationId, signedPreKey, signedIdentityKey }, config) => {
|
|
65
78
|
// the app version needs to be md5 hashed
|
|
66
79
|
// and passed in
|
|
67
|
-
const appVersionBuf =
|
|
80
|
+
const appVersionBuf = crypto_1.createHash('md5')
|
|
68
81
|
.update(config.version.join('.')) // join as string
|
|
69
|
-
.digest()
|
|
82
|
+
.digest()
|
|
83
|
+
|
|
70
84
|
const companion = {
|
|
71
85
|
os: config.browser[0],
|
|
72
86
|
platformType: getPlatformType(config.browser[1]),
|
|
73
87
|
requireFullSync: config.syncFullHistory,
|
|
74
|
-
|
|
75
|
-
|
|
88
|
+
historySyncConfig: {
|
|
89
|
+
storageQuotaMb: 10240,
|
|
90
|
+
inlineInitialPayloadInE2EeMsg: true,
|
|
91
|
+
recentSyncDaysLimit: undefined,
|
|
92
|
+
supportCallLogHistory: false,
|
|
93
|
+
supportBotUserAgentChatHistory: true,
|
|
94
|
+
supportCagReactionsAndPolls: true,
|
|
95
|
+
supportBizHostedMsg: true,
|
|
96
|
+
supportRecentSyncChunkMessageCountTuning: true,
|
|
97
|
+
supportHostedGroupMsg: true,
|
|
98
|
+
supportFbidBotChatHistory: true,
|
|
99
|
+
supportAddOnHistorySyncMigration: undefined,
|
|
100
|
+
supportMessageAssociation: true,
|
|
101
|
+
supportGroupHistory: false,
|
|
102
|
+
onDemandReady: undefined,
|
|
103
|
+
supportGuestChat: undefined
|
|
104
|
+
},
|
|
105
|
+
version: {
|
|
106
|
+
primary: 10,
|
|
107
|
+
secondary: 15,
|
|
108
|
+
tertiary: 7
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const companionProto = WAProto_1.proto.DeviceProps.encode(companion).finish()
|
|
113
|
+
|
|
76
114
|
const registerPayload = {
|
|
77
115
|
...getClientPayload(config),
|
|
78
116
|
passive: false,
|
|
@@ -80,48 +118,67 @@ const generateRegistrationNode = ({ registrationId, signedPreKey, signedIdentity
|
|
|
80
118
|
devicePairingData: {
|
|
81
119
|
buildHash: appVersionBuf,
|
|
82
120
|
deviceProps: companionProto,
|
|
83
|
-
eRegid:
|
|
121
|
+
eRegid: generics_1.encodeBigEndian(registrationId),
|
|
84
122
|
eKeytype: Defaults_1.KEY_BUNDLE_TYPE,
|
|
85
123
|
eIdent: signedIdentityKey.public,
|
|
86
|
-
eSkeyId:
|
|
124
|
+
eSkeyId: generics_1.encodeBigEndian(signedPreKey.keyId, 3),
|
|
87
125
|
eSkeyVal: signedPreKey.keyPair.public,
|
|
88
126
|
eSkeySig: signedPreKey.signature,
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return WAProto_1.proto.ClientPayload.fromObject(registerPayload)
|
|
131
|
+
}
|
|
132
|
+
|
|
94
133
|
const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, signalIdentities }) => {
|
|
95
|
-
const msgId = stanza.attrs.id
|
|
96
|
-
const pairSuccessNode =
|
|
97
|
-
const deviceIdentityNode =
|
|
98
|
-
const platformNode =
|
|
99
|
-
const deviceNode =
|
|
100
|
-
const businessNode =
|
|
134
|
+
const msgId = stanza.attrs.id
|
|
135
|
+
const pairSuccessNode = WABinary_1.getBinaryNodeChild(stanza, 'pair-success')
|
|
136
|
+
const deviceIdentityNode = WABinary_1.getBinaryNodeChild(pairSuccessNode, 'device-identity')
|
|
137
|
+
const platformNode = WABinary_1.getBinaryNodeChild(pairSuccessNode, 'platform')
|
|
138
|
+
const deviceNode = WABinary_1.getBinaryNodeChild(pairSuccessNode, 'device')
|
|
139
|
+
const businessNode = WABinary_1.getBinaryNodeChild(pairSuccessNode, 'biz')
|
|
101
140
|
if (!deviceIdentityNode || !deviceNode) {
|
|
102
|
-
throw new boom_1.Boom('Missing device-identity or device in pair success node', { data: stanza })
|
|
141
|
+
throw new boom_1.Boom('Missing device-identity or device in pair success node', { data: stanza })
|
|
142
|
+
}
|
|
143
|
+
const bizName = businessNode?.attrs?.name
|
|
144
|
+
const jid = deviceNode.attrs.jid
|
|
145
|
+
const lid = deviceNode.attrs.lid
|
|
146
|
+
const { details, hmac, accountType } = WAProto_1.proto.ADVSignedDeviceIdentityHMAC.decode(deviceIdentityNode.content)
|
|
147
|
+
|
|
148
|
+
let hmacPrefix = Buffer.from([])
|
|
149
|
+
if (accountType !== undefined && accountType === WAProto_1.proto.ADVEncryptionType.HOSTED) {
|
|
150
|
+
hmacPrefix = Buffer.from([6, 5])
|
|
103
151
|
}
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
const { details, hmac, accountType } = WAProto_1.proto.ADVSignedDeviceIdentityHMAC.decode(deviceIdentityNode.content);
|
|
107
|
-
const isHostedAccount = accountType !== undefined && accountType === WAProto_1.proto.ADVEncryptionType.HOSTED;
|
|
108
|
-
const hmacPrefix = isHostedAccount ? Buffer.from([6, 5]) : Buffer.alloc(0);
|
|
109
|
-
const advSign = (0, crypto_2.hmacSign)(Buffer.concat([hmacPrefix, details]), Buffer.from(advSecretKey, 'base64'));
|
|
152
|
+
|
|
153
|
+
const advSign = crypto_2.hmacSign(Buffer.concat([hmacPrefix, details]), Buffer.from(advSecretKey, 'base64'))
|
|
110
154
|
if (Buffer.compare(hmac, advSign) !== 0) {
|
|
111
|
-
throw new boom_1.Boom('Invalid account signature')
|
|
155
|
+
throw new boom_1.Boom('Invalid account signature')
|
|
112
156
|
}
|
|
113
|
-
|
|
114
|
-
const
|
|
115
|
-
const
|
|
157
|
+
|
|
158
|
+
const account = WAProto_1.proto.ADVSignedDeviceIdentity.decode(details)
|
|
159
|
+
const { accountSignatureKey, accountSignature, details: deviceDetails } = account
|
|
160
|
+
|
|
161
|
+
const decodedDeviceIdentity = WAProto_1.proto.ADVDeviceIdentity.decode(deviceDetails)
|
|
162
|
+
|
|
163
|
+
const accountSignaturePrefix =
|
|
164
|
+
decodedDeviceIdentity.deviceType === WAProto_1.proto.ADVEncryptionType.HOSTED
|
|
165
|
+
? Buffer.from([6, 5])
|
|
166
|
+
: Buffer.from([6, 0])
|
|
167
|
+
const accountMsg = Buffer.concat([accountSignaturePrefix, deviceDetails, signedIdentityKey.public])
|
|
116
168
|
if (!crypto_2.Curve.verify(accountSignatureKey, accountMsg, accountSignature)) {
|
|
117
|
-
throw new boom_1.Boom('Failed to verify account signature')
|
|
169
|
+
throw new boom_1.Boom('Failed to verify account signature')
|
|
118
170
|
}
|
|
119
|
-
|
|
120
|
-
const deviceMsg = Buffer.concat([
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
171
|
+
|
|
172
|
+
const deviceMsg = Buffer.concat([
|
|
173
|
+
Buffer.from([6, 1]),
|
|
174
|
+
deviceDetails,
|
|
175
|
+
signedIdentityKey.public,
|
|
176
|
+
accountSignatureKey
|
|
177
|
+
])
|
|
178
|
+
account.deviceSignature = crypto_2.Curve.sign(signedIdentityKey.private, deviceMsg)
|
|
179
|
+
const identity = signal_1.createSignalIdentity(lid, accountSignatureKey)
|
|
180
|
+
const accountEnc = encodeSignedDeviceIdentity(account, false)
|
|
181
|
+
const deviceIdentityData = WAProto_1.proto.ADVDeviceIdentity.decode(account.details)
|
|
125
182
|
const reply = {
|
|
126
183
|
tag: 'iq',
|
|
127
184
|
attrs: {
|
|
@@ -136,38 +193,41 @@ const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, s
|
|
|
136
193
|
content: [
|
|
137
194
|
{
|
|
138
195
|
tag: 'device-identity',
|
|
139
|
-
attrs: { 'key-index':
|
|
196
|
+
attrs: { 'key-index': deviceIdentityData.keyIndex.toString() },
|
|
140
197
|
content: accountEnc
|
|
141
198
|
}
|
|
142
199
|
]
|
|
143
200
|
}
|
|
144
201
|
]
|
|
145
|
-
}
|
|
202
|
+
}
|
|
146
203
|
const authUpdate = {
|
|
147
204
|
account,
|
|
148
|
-
me: { id: jid, name: bizName },
|
|
205
|
+
me: { id: jid, name: bizName, lid },
|
|
149
206
|
signalIdentities: [
|
|
150
207
|
...(signalIdentities || []),
|
|
151
208
|
identity
|
|
152
209
|
],
|
|
153
|
-
platform: platformNode
|
|
154
|
-
}
|
|
210
|
+
platform: platformNode?.attrs?.name
|
|
211
|
+
}
|
|
155
212
|
return {
|
|
156
213
|
creds: authUpdate,
|
|
157
214
|
reply
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
161
218
|
const encodeSignedDeviceIdentity = (account, includeSignatureKey) => {
|
|
162
|
-
|
|
163
|
-
account = { ...account };
|
|
219
|
+
account = { ...account }
|
|
164
220
|
// set to null if we are not to include the signature key
|
|
165
221
|
// or if we are including the signature key but it is empty
|
|
166
|
-
if (!includeSignatureKey || !
|
|
167
|
-
account.accountSignatureKey = null
|
|
222
|
+
if (!includeSignatureKey || !account.accountSignatureKey?.length) {
|
|
223
|
+
account.accountSignatureKey = null
|
|
168
224
|
}
|
|
169
|
-
return WAProto_1.proto.ADVSignedDeviceIdentity
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
225
|
+
return WAProto_1.proto.ADVSignedDeviceIdentity.encode(account).finish()
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
module.exports = {
|
|
229
|
+
generateLoginNode,
|
|
230
|
+
generateRegistrationNode,
|
|
231
|
+
configureSuccessfulPairing,
|
|
232
|
+
encodeSignedDeviceIdentity
|
|
233
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.lidToJid = exports.getBotJid = exports.jidNormalizedUser = exports.isJidBot = exports.isJidStatusBroadcast = exports.isJidGroup = exports.isJidNewsletter = exports.isJidBroadcast = exports.
|
|
3
|
+
exports.lidToJid = exports.getBotJid = exports.jidNormalizedUser = exports.isJidBot = exports.isJidStatusBroadcast = exports.isJidGroup = exports.isJidNewsletter = exports.isJidBroadcast = exports.isLid = exports.assertLid = exports.isJidUser = exports.isJidMetaAi = exports.areJidsSameUser = exports.jidDecode = exports.jidEncode = exports.META_AI_JID = exports.STORIES_JID = exports.PSA_WID = exports.SERVER_JID = exports.OFFICIAL_BIZ_JID = exports.S_WHATSAPP_NET = void 0;
|
|
4
4
|
exports.S_WHATSAPP_NET = '@s.whatsapp.net';
|
|
5
5
|
exports.OFFICIAL_BIZ_JID = '16505361212@c.us';
|
|
6
6
|
exports.SERVER_JID = 'server@c.us';
|
|
@@ -41,8 +41,15 @@ exports.isJidMetaAi = isJidMetaAi;
|
|
|
41
41
|
const isJidUser = (jid) => (jid === null || jid === void 0 ? void 0 : jid.endsWith('@s.whatsapp.net'));
|
|
42
42
|
exports.isJidUser = isJidUser;
|
|
43
43
|
/** is the jid a group */
|
|
44
|
-
const
|
|
45
|
-
exports.
|
|
44
|
+
const isLid = (jid) => (jid === null || jid === void 0 ? void 0 : jid.endsWith('@lid'));
|
|
45
|
+
exports.isLid = isLid;
|
|
46
|
+
/** assert the jid is a LID */
|
|
47
|
+
const assertLid = (jid) => {
|
|
48
|
+
if (!isLid(jid)) {
|
|
49
|
+
throw new Error(`JID "${jid}" is not a LID`);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
exports.assertLid = assertLid;
|
|
46
53
|
/** is the jid a broadcast */
|
|
47
54
|
const isJidBroadcast = (jid) => (jid === null || jid === void 0 ? void 0 : jid.endsWith('@broadcast'));
|
|
48
55
|
exports.isJidBroadcast = isJidBroadcast;
|