@badzz88/baileys 8.5.6 → 8.5.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/README.md +337 -1055
- package/WAProto/WAProto.proto +28 -1189
- package/WAProto/fix-imports.js +79 -69
- package/WAProto/index.d.ts +71491 -15254
- package/WAProto/index.js +126436 -19814
- package/engine-requirements.js +8 -15
- package/lib/Defaults/index.js +130 -0
- package/{src → lib}/Signal/Group/ciphertext-message.js +2 -5
- package/lib/Signal/Group/group-session-builder.js +30 -0
- package/{src → lib}/Signal/Group/group_cipher.js +11 -11
- package/lib/Signal/Group/index.js +12 -0
- package/lib/Signal/Group/keyhelper.js +18 -0
- package/{src → lib}/Signal/Group/sender-chain-key.js +6 -9
- package/{src → lib}/Signal/Group/sender-key-distribution-message.js +6 -9
- package/{src → lib}/Signal/Group/sender-key-message.js +9 -12
- package/{src → lib}/Signal/Group/sender-key-name.js +2 -5
- package/{src → lib}/Signal/Group/sender-key-record.js +8 -11
- package/{src → lib}/Signal/Group/sender-key-state.js +6 -9
- package/lib/Signal/Group/sender-message-key.js +26 -0
- package/{src → lib}/Signal/libsignal.js +131 -155
- package/{src → lib}/Signal/lid-mapping.js +27 -23
- package/lib/Socket/Client/index.js +3 -0
- package/lib/Socket/Client/types.js +11 -0
- package/{src → lib}/Socket/Client/websocket.js +11 -18
- package/{src → lib}/Socket/business.js +35 -67
- package/{src → lib}/Socket/chats.js +294 -550
- package/{src → lib}/Socket/communities.js +82 -114
- package/lib/Socket/graphql.js +716 -0
- package/lib/Socket/groups.js +374 -0
- package/lib/Socket/index.js +18 -0
- package/lib/Socket/interop.js +463 -0
- package/{src → lib}/Socket/luxu.js +120 -82
- package/lib/Socket/messages-recv.js +1916 -0
- package/lib/Socket/messages-send.js +1436 -0
- package/lib/Socket/mex.js +54 -0
- package/lib/Socket/newsletter.js +757 -0
- package/lib/Socket/privacy.js +318 -0
- package/{src → lib}/Socket/socket.js +356 -244
- package/lib/Socket/username.js +236 -0
- package/lib/Store/index.js +10 -0
- package/{src → lib}/Store/keyed-db.js +11 -21
- package/lib/Store/make-cache-manager-store.js +85 -0
- package/lib/Store/make-in-memory-store.js +244 -0
- package/{src → lib}/Store/make-ordered-dictionary.js +19 -25
- package/{src → lib}/Store/object-repository.js +11 -5
- package/lib/Types/Auth.js +2 -0
- package/lib/Types/Bussines.js +2 -0
- package/lib/Types/Call.js +2 -0
- package/lib/Types/Chat.js +8 -0
- package/lib/Types/Contact.js +2 -0
- package/lib/Types/Events.js +2 -0
- package/lib/Types/GroupMetadata.js +2 -0
- package/lib/Types/Label.js +25 -0
- package/lib/Types/LabelAssociation.js +7 -0
- package/lib/Types/Message.js +11 -0
- package/lib/Types/Mex.js +111 -0
- package/lib/Types/Product.js +2 -0
- package/lib/Types/Signal.js +2 -0
- package/lib/Types/Socket.js +3 -0
- package/lib/Types/State.js +56 -0
- package/lib/Types/USync.js +2 -0
- package/lib/Types/index.js +26 -0
- package/{src → lib}/Utils/auth-utils.js +91 -43
- package/lib/Utils/browser-utils.js +48 -0
- package/lib/Utils/business.js +231 -0
- package/lib/Utils/chat-utils.js +872 -0
- package/lib/Utils/companion-reg-client-utils.js +35 -0
- package/lib/Utils/crypto.js +118 -0
- package/lib/Utils/decode-wa-message.js +350 -0
- package/{src → lib}/Utils/event-buffer.js +81 -39
- package/lib/Utils/generics.js +403 -0
- package/lib/Utils/history.js +134 -0
- package/{src → lib}/Utils/identity-change-handler.js +9 -11
- package/lib/Utils/index.js +23 -0
- package/lib/Utils/link-preview.js +85 -0
- package/lib/Utils/logger.js +3 -0
- package/lib/Utils/lt-hash.js +8 -0
- package/{src → lib}/Utils/make-mutex.js +7 -10
- package/lib/Utils/message-composer.js +273 -0
- package/{src → lib}/Utils/message-retry-manager.js +76 -28
- package/lib/Utils/messages-media.js +870 -0
- package/lib/Utils/messages.js +1337 -0
- package/lib/Utils/noise-handler.js +201 -0
- package/{src → lib}/Utils/offline-node-processor.js +10 -4
- package/{src → lib}/Utils/pre-key-manager.js +27 -11
- package/lib/Utils/process-message.js +630 -0
- package/{src → lib}/Utils/reporting-utils.js +12 -15
- package/lib/Utils/signal.js +201 -0
- package/{src → lib}/Utils/stanza-ack.js +12 -4
- package/lib/Utils/sticker.js +110 -0
- package/{src → lib}/Utils/sync-action-utils.js +14 -10
- package/{src → lib}/Utils/tc-token-utils.js +48 -43
- package/{src → lib}/Utils/use-multi-file-auth-state.js +35 -25
- package/lib/Utils/validate-connection.js +203 -0
- package/{src → lib}/WABinary/constants.js +9 -12
- package/{src → lib}/WABinary/decode.js +38 -118
- package/{src → lib}/WABinary/encode.js +6 -11
- package/lib/WABinary/generic-utils.js +204 -0
- package/lib/WABinary/index.js +6 -0
- package/lib/WABinary/jid-utils.js +98 -0
- package/lib/WABinary/types.js +2 -0
- package/{src → lib}/WAM/BinaryInfo.js +2 -5
- package/{src → lib}/WAM/constants.js +4 -16635
- package/{src → lib}/WAM/encode.js +18 -17
- package/lib/WAM/index.js +4 -0
- package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +53 -0
- package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +43 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +54 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +57 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +30 -0
- package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +58 -0
- package/lib/WAUSync/Protocols/USyncLIDProtocol.js +30 -0
- package/lib/WAUSync/Protocols/USyncPictureProtocol.js +32 -0
- package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +28 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +39 -0
- package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +38 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +27 -0
- package/lib/WAUSync/Protocols/index.js +12 -0
- package/lib/WAUSync/USyncQuery.js +151 -0
- package/lib/WAUSync/USyncUser.js +56 -0
- package/lib/WAUSync/index.js +3 -0
- package/{src → lib}/index.js +16 -51
- package/package.json +129 -99
- package/LICENSE +0 -21
- package/src/Defaults/index.js +0 -186
- package/src/Defaults/phonenumber-mcc.json +0 -223
- package/src/Signal/Group/group-session-builder.js +0 -86
- package/src/Signal/Group/index.js +0 -140
- package/src/Signal/Group/keyhelper.js +0 -77
- package/src/Signal/Group/sender-message-key.js +0 -29
- package/src/Socket/Client/index.js +0 -31
- package/src/Socket/Client/types.js +0 -13
- package/src/Socket/aigroups.js +0 -221
- package/src/Socket/graphql.js +0 -523
- package/src/Socket/groups.js +0 -516
- package/src/Socket/index.js +0 -31
- package/src/Socket/interactive-handler.js +0 -527
- package/src/Socket/interop.js +0 -339
- package/src/Socket/managed-account.js +0 -98
- package/src/Socket/messages-recv.js +0 -2685
- package/src/Socket/messages-send.js +0 -2047
- package/src/Socket/mex.js +0 -57
- package/src/Socket/newsletter.js +0 -455
- package/src/Socket/privacy.js +0 -125
- package/src/Socket/registration.js +0 -236
- package/src/Socket/text-router.js +0 -65
- package/src/Socket/username.js +0 -130
- package/src/Store/index.js +0 -33
- package/src/Store/make-cache-manager-store.js +0 -84
- package/src/Store/make-in-memory-store.js +0 -551
- package/src/Types/Auth.js +0 -31
- package/src/Types/Bussines.js +0 -2
- package/src/Types/Call.js +0 -2
- package/src/Types/Chat.js +0 -4
- package/src/Types/Contact.js +0 -2
- package/src/Types/Events.js +0 -2
- package/src/Types/GroupMetadata.js +0 -2
- package/src/Types/Label.js +0 -26
- package/src/Types/LabelAssociation.js +0 -8
- package/src/Types/Message.js +0 -93
- package/src/Types/Mex.js +0 -112
- package/src/Types/Newsletter.js +0 -109
- package/src/Types/Product.js +0 -2
- package/src/Types/Signal.js +0 -2
- package/src/Types/Socket.js +0 -2
- package/src/Types/State.js +0 -62
- package/src/Types/USync.js +0 -2
- package/src/Types/index.js +0 -56
- package/src/Utils/browser-utils.js +0 -112
- package/src/Utils/business.js +0 -240
- package/src/Utils/chat-utils.js +0 -1230
- package/src/Utils/command-loader.d.ts +0 -27
- package/src/Utils/command-loader.js +0 -89
- package/src/Utils/companion-reg-client-utils.js +0 -40
- package/src/Utils/consumer-application.js +0 -105
- package/src/Utils/crypto.js +0 -118
- package/src/Utils/curve25519-js.js +0 -242
- package/src/Utils/decode-wa-message.js +0 -529
- package/src/Utils/generics.js +0 -483
- package/src/Utils/group-history.js +0 -44
- package/src/Utils/history.js +0 -232
- package/src/Utils/index.js +0 -58
- package/src/Utils/jid-display-normalization.js +0 -195
- package/src/Utils/link-preview.js +0 -135
- package/src/Utils/logger.js +0 -8
- package/src/Utils/lt-hash.js +0 -25
- package/src/Utils/message-composer.js +0 -471
- package/src/Utils/messages-media.js +0 -843
- package/src/Utils/messages.js +0 -2817
- package/src/Utils/meta-ai-msmsg.js +0 -222
- package/src/Utils/native-bridge.js +0 -68
- package/src/Utils/noise-handler.js +0 -169
- package/src/Utils/process-message.js +0 -950
- package/src/Utils/session-pool.d.ts +0 -14
- package/src/Utils/session-pool.js +0 -70
- package/src/Utils/signal.js +0 -217
- package/src/Utils/sticker.d.ts +0 -13
- package/src/Utils/sticker.js +0 -123
- package/src/Utils/validate-connection.js +0 -209
- package/src/Utils/view-once-cache.d.ts +0 -12
- package/src/Utils/view-once-cache.js +0 -63
- package/src/Utils/voip-rekey.js +0 -22
- package/src/WABinary/generic-utils.js +0 -238
- package/src/WABinary/index.js +0 -34
- package/src/WABinary/jid-utils.js +0 -351
- package/src/WABinary/types.js +0 -2
- package/src/WAM/index.js +0 -32
- package/src/WAUSync/Protocols/USyncBotProfileProtocol.js +0 -53
- package/src/WAUSync/Protocols/USyncBusinessProtocol.js +0 -44
- package/src/WAUSync/Protocols/USyncContactProtocol.js +0 -55
- package/src/WAUSync/Protocols/USyncDeviceProtocol.js +0 -55
- package/src/WAUSync/Protocols/USyncDisappearingModeProtocol.js +0 -31
- package/src/WAUSync/Protocols/USyncFeatureProtocol.js +0 -54
- package/src/WAUSync/Protocols/USyncLIDProtocol.js +0 -32
- package/src/WAUSync/Protocols/USyncNewsletterProtocol.js +0 -473
- package/src/WAUSync/Protocols/USyncPictureProtocol.js +0 -34
- package/src/WAUSync/Protocols/USyncSidelistProtocol.js +0 -29
- package/src/WAUSync/Protocols/USyncStatusProtocol.js +0 -42
- package/src/WAUSync/Protocols/USyncTextStatusProtocol.js +0 -38
- package/src/WAUSync/Protocols/USyncUsernameProtocol.js +0 -28
- package/src/WAUSync/Protocols/index.js +0 -40
- package/src/WAUSync/USyncQuery.js +0 -126
- package/src/WAUSync/USyncUser.js +0 -50
- package/src/WAUSync/index.js +0 -32
- package/src/antiban.js +0 -4152
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
function makeCacheableSignalKeyStore(store, logger, _cache) {
|
|
1
|
+
import NodeCache from '@cacheable/node-cache';
|
|
2
|
+
import { Boom } from '@hapi/boom';
|
|
3
|
+
import { AsyncLocalStorage } from 'async_hooks';
|
|
4
|
+
import { Mutex } from 'async-mutex';
|
|
5
|
+
import { randomBytes } from 'crypto';
|
|
6
|
+
import PQueue from 'p-queue';
|
|
7
|
+
import { DEFAULT_CACHE_TTLS } from '../Defaults/index.js';
|
|
8
|
+
import { Curve, signedKeyPair } from './crypto.js';
|
|
9
|
+
import { delay, generateRegistrationId } from './generics.js';
|
|
10
|
+
import { PreKeyManager } from './pre-key-manager.js';
|
|
11
|
+
/**
|
|
12
|
+
* Adds caching capability to a SignalKeyStore
|
|
13
|
+
* @param store the store to add caching to
|
|
14
|
+
* @param logger to log trace events
|
|
15
|
+
* @param _cache cache store to use
|
|
16
|
+
*/
|
|
17
|
+
export function makeCacheableSignalKeyStore(store, logger, _cache) {
|
|
19
18
|
const cache = _cache ||
|
|
20
|
-
new
|
|
21
|
-
stdTTL:
|
|
19
|
+
new NodeCache({
|
|
20
|
+
stdTTL: DEFAULT_CACHE_TTLS.SIGNAL_STORE, // 5 minutes
|
|
22
21
|
useClones: false,
|
|
23
22
|
deleteOnExpire: true
|
|
24
23
|
});
|
|
25
|
-
|
|
24
|
+
// Mutex for protecting cache operations
|
|
25
|
+
const cacheMutex = new Mutex();
|
|
26
26
|
function getUniqueId(type, id) {
|
|
27
27
|
return `${type}.${id}`;
|
|
28
28
|
}
|
|
@@ -32,7 +32,7 @@ function makeCacheableSignalKeyStore(store, logger, _cache) {
|
|
|
32
32
|
const data = {};
|
|
33
33
|
const idsToFetch = [];
|
|
34
34
|
for (const id of ids) {
|
|
35
|
-
const item = await cache.get(getUniqueId(type, id));
|
|
35
|
+
const item = (await cache.get(getUniqueId(type, id)));
|
|
36
36
|
if (typeof item !== 'undefined') {
|
|
37
37
|
data[id] = item;
|
|
38
38
|
}
|
|
@@ -47,6 +47,7 @@ function makeCacheableSignalKeyStore(store, logger, _cache) {
|
|
|
47
47
|
const item = fetched[id];
|
|
48
48
|
if (item) {
|
|
49
49
|
data[id] = item;
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
50
51
|
await cache.set(getUniqueId(type, id), item);
|
|
51
52
|
}
|
|
52
53
|
}
|
|
@@ -73,32 +74,55 @@ function makeCacheableSignalKeyStore(store, logger, _cache) {
|
|
|
73
74
|
}
|
|
74
75
|
};
|
|
75
76
|
}
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Adds DB-like transaction capability to the SignalKeyStore
|
|
79
|
+
* Uses AsyncLocalStorage for automatic context management
|
|
80
|
+
* @param state the key store to apply this capability to
|
|
81
|
+
* @param logger logger to log events
|
|
82
|
+
* @returns SignalKeyStore with transaction capability
|
|
83
|
+
*/
|
|
84
|
+
export const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetweenTriesMs }) => {
|
|
85
|
+
const txStorage = new AsyncLocalStorage();
|
|
86
|
+
// Queues for concurrency control (keyed by signal data type - bounded set)
|
|
78
87
|
const keyQueues = new Map();
|
|
88
|
+
// Transaction mutexes with reference counting for cleanup
|
|
79
89
|
const txMutexes = new Map();
|
|
80
90
|
const txMutexRefCounts = new Map();
|
|
81
|
-
|
|
91
|
+
// Pre-key manager for specialized operations
|
|
92
|
+
const preKeyManager = new PreKeyManager(state, logger);
|
|
93
|
+
/**
|
|
94
|
+
* Get or create a queue for a specific key type
|
|
95
|
+
*/
|
|
82
96
|
function getQueue(key) {
|
|
83
97
|
if (!keyQueues.has(key)) {
|
|
84
|
-
keyQueues.set(key, new
|
|
98
|
+
keyQueues.set(key, new PQueue({ concurrency: 1 }));
|
|
85
99
|
}
|
|
86
100
|
return keyQueues.get(key);
|
|
87
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Get or create a transaction mutex
|
|
104
|
+
*/
|
|
88
105
|
function getTxMutex(key) {
|
|
89
106
|
if (!txMutexes.has(key)) {
|
|
90
|
-
txMutexes.set(key, new
|
|
107
|
+
txMutexes.set(key, new Mutex());
|
|
91
108
|
txMutexRefCounts.set(key, 0);
|
|
92
109
|
}
|
|
93
110
|
return txMutexes.get(key);
|
|
94
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Acquire a reference to a transaction mutex
|
|
114
|
+
*/
|
|
95
115
|
function acquireTxMutexRef(key) {
|
|
96
116
|
const count = txMutexRefCounts.get(key) ?? 0;
|
|
97
117
|
txMutexRefCounts.set(key, count + 1);
|
|
98
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Release a reference to a transaction mutex and cleanup if no longer needed
|
|
121
|
+
*/
|
|
99
122
|
function releaseTxMutexRef(key) {
|
|
100
123
|
const count = (txMutexRefCounts.get(key) ?? 1) - 1;
|
|
101
124
|
txMutexRefCounts.set(key, count);
|
|
125
|
+
// Cleanup if no more references and mutex is not locked
|
|
102
126
|
if (count <= 0) {
|
|
103
127
|
const mutex = txMutexes.get(key);
|
|
104
128
|
if (mutex && !mutex.isLocked()) {
|
|
@@ -107,9 +131,15 @@ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetwee
|
|
|
107
131
|
}
|
|
108
132
|
}
|
|
109
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* Check if currently in a transaction
|
|
136
|
+
*/
|
|
110
137
|
function isInTransaction() {
|
|
111
138
|
return !!txStorage.getStore();
|
|
112
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Commit transaction with retries
|
|
142
|
+
*/
|
|
113
143
|
async function commitWithRetry(mutations) {
|
|
114
144
|
if (Object.keys(mutations).length === 0) {
|
|
115
145
|
logger.trace('no mutations in transaction');
|
|
@@ -128,7 +158,7 @@ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetwee
|
|
|
128
158
|
if (retriesLeft === 0) {
|
|
129
159
|
throw error;
|
|
130
160
|
}
|
|
131
|
-
await
|
|
161
|
+
await delay(delayBetweenTriesMs);
|
|
132
162
|
}
|
|
133
163
|
}
|
|
134
164
|
}
|
|
@@ -136,17 +166,21 @@ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetwee
|
|
|
136
166
|
get: async (type, ids) => {
|
|
137
167
|
const ctx = txStorage.getStore();
|
|
138
168
|
if (!ctx) {
|
|
169
|
+
// No transaction - direct read without exclusive lock for concurrency
|
|
139
170
|
return state.get(type, ids);
|
|
140
171
|
}
|
|
172
|
+
// In transaction - check cache first
|
|
141
173
|
const cached = ctx.cache[type] || {};
|
|
142
174
|
const missing = ids.filter(id => !(id in cached));
|
|
143
175
|
if (missing.length > 0) {
|
|
144
176
|
ctx.dbQueries++;
|
|
145
177
|
logger.trace({ type, count: missing.length }, 'fetching missing keys in transaction');
|
|
146
178
|
const fetched = await getTxMutex(type).runExclusive(() => state.get(type, missing));
|
|
179
|
+
// Update cache
|
|
147
180
|
ctx.cache[type] = ctx.cache[type] || {};
|
|
148
181
|
Object.assign(ctx.cache[type], fetched);
|
|
149
182
|
}
|
|
183
|
+
// Return requested ids from cache
|
|
150
184
|
const result = {};
|
|
151
185
|
for (const id of ids) {
|
|
152
186
|
const value = ctx.cache[type]?.[id];
|
|
@@ -159,28 +193,35 @@ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetwee
|
|
|
159
193
|
set: async (data) => {
|
|
160
194
|
const ctx = txStorage.getStore();
|
|
161
195
|
if (!ctx) {
|
|
196
|
+
// No transaction - direct write with queue protection
|
|
162
197
|
const types = Object.keys(data);
|
|
198
|
+
// Process pre-keys with validation
|
|
163
199
|
for (const type_ of types) {
|
|
164
200
|
const type = type_;
|
|
165
201
|
if (type === 'pre-key') {
|
|
166
202
|
await preKeyManager.validateDeletions(data, type);
|
|
167
203
|
}
|
|
168
204
|
}
|
|
205
|
+
// Write all data in parallel
|
|
169
206
|
await Promise.all(types.map(type => getQueue(type).add(async () => {
|
|
170
207
|
const typeData = { [type]: data[type] };
|
|
171
208
|
await state.set(typeData);
|
|
172
209
|
})));
|
|
173
210
|
return;
|
|
174
211
|
}
|
|
212
|
+
// In transaction - update cache and mutations
|
|
175
213
|
logger.trace({ types: Object.keys(data) }, 'caching in transaction');
|
|
176
214
|
for (const key_ in data) {
|
|
177
215
|
const key = key_;
|
|
216
|
+
// Ensure structures exist
|
|
178
217
|
ctx.cache[key] = ctx.cache[key] || {};
|
|
179
218
|
ctx.mutations[key] = ctx.mutations[key] || {};
|
|
219
|
+
// Special handling for pre-keys
|
|
180
220
|
if (key === 'pre-key') {
|
|
181
221
|
await preKeyManager.processOperations(data, key, ctx.cache, ctx.mutations, true);
|
|
182
222
|
}
|
|
183
223
|
else {
|
|
224
|
+
// Normal key types
|
|
184
225
|
Object.assign(ctx.cache[key], data[key]);
|
|
185
226
|
Object.assign(ctx.mutations[key], data[key]);
|
|
186
227
|
}
|
|
@@ -189,10 +230,12 @@ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetwee
|
|
|
189
230
|
isInTransaction,
|
|
190
231
|
transaction: async (work, key) => {
|
|
191
232
|
const existing = txStorage.getStore();
|
|
233
|
+
// Nested transaction - reuse existing context
|
|
192
234
|
if (existing) {
|
|
193
235
|
logger.trace('reusing existing transaction context');
|
|
194
236
|
return work();
|
|
195
237
|
}
|
|
238
|
+
// New transaction - acquire mutex and create context
|
|
196
239
|
const mutex = getTxMutex(key);
|
|
197
240
|
acquireTxMutexRef(key);
|
|
198
241
|
try {
|
|
@@ -205,6 +248,7 @@ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetwee
|
|
|
205
248
|
logger.trace('entering transaction');
|
|
206
249
|
try {
|
|
207
250
|
const result = await txStorage.run(ctx, work);
|
|
251
|
+
// Commit mutations
|
|
208
252
|
await commitWithRetry(ctx.mutations);
|
|
209
253
|
logger.trace({ dbQueries: ctx.dbQueries }, 'transaction completed');
|
|
210
254
|
return result;
|
|
@@ -221,29 +265,33 @@ const addTransactionCapability = (state, logger, { maxCommitRetries, delayBetwee
|
|
|
221
265
|
}
|
|
222
266
|
};
|
|
223
267
|
};
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
268
|
+
/**
|
|
269
|
+
* Returns the authenticated user's JID, or throws a Boom-401 if creds are not yet authenticated.
|
|
270
|
+
* Use this anywhere we'd otherwise reach for `creds.me!.id` to fail fast with a descriptive error.
|
|
271
|
+
*/
|
|
272
|
+
export const assertMeId = (creds) => {
|
|
273
|
+
const id = creds.me?.id;
|
|
274
|
+
if (!id) {
|
|
275
|
+
throw new Boom('Cannot proceed: socket is not authenticated yet (creds.me.id is missing)', { statusCode: 401 });
|
|
276
|
+
}
|
|
277
|
+
return id;
|
|
278
|
+
};
|
|
279
|
+
export const initAuthCreds = () => {
|
|
280
|
+
const identityKey = Curve.generateKeyPair();
|
|
227
281
|
return {
|
|
228
|
-
noiseKey:
|
|
229
|
-
pairingEphemeralKeyPair:
|
|
282
|
+
noiseKey: Curve.generateKeyPair(),
|
|
283
|
+
pairingEphemeralKeyPair: Curve.generateKeyPair(),
|
|
230
284
|
signedIdentityKey: identityKey,
|
|
231
|
-
signedPreKey:
|
|
232
|
-
registrationId:
|
|
233
|
-
advSecretKey:
|
|
285
|
+
signedPreKey: signedKeyPair(identityKey, 1),
|
|
286
|
+
registrationId: generateRegistrationId(),
|
|
287
|
+
advSecretKey: randomBytes(32).toString('base64'),
|
|
234
288
|
processedHistoryMessages: [],
|
|
235
|
-
initialFullSyncDone: false,
|
|
236
289
|
nextPreKeyId: 1,
|
|
237
290
|
firstUnuploadedPreKeyId: 1,
|
|
238
291
|
accountSyncCounter: 0,
|
|
239
292
|
accountSettings: {
|
|
240
293
|
unarchiveChats: false
|
|
241
294
|
},
|
|
242
|
-
deviceId: Buffer.from((0, crypto_1.randomUUID)().replace(/-/g, ''), 'hex').toString('base64url'),
|
|
243
|
-
phoneId: (0, crypto_1.randomUUID)(),
|
|
244
|
-
identityId: (0, crypto_1.randomBytes)(20),
|
|
245
|
-
backupToken: (0, crypto_1.randomBytes)(20),
|
|
246
|
-
registration: {},
|
|
247
295
|
registered: false,
|
|
248
296
|
pairingCode: undefined,
|
|
249
297
|
lastPropHash: undefined,
|
|
@@ -251,4 +299,4 @@ const initAuthCreds = () => {
|
|
|
251
299
|
additionalData: undefined
|
|
252
300
|
};
|
|
253
301
|
};
|
|
254
|
-
|
|
302
|
+
//# sourceMappingURL=auth-utils.js.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { platform, release } from 'os';
|
|
2
|
+
import { proto } from '../../WAProto/index.js';
|
|
3
|
+
const PLATFORM_MAP = {
|
|
4
|
+
aix: 'AIX',
|
|
5
|
+
darwin: 'Mac OS',
|
|
6
|
+
win32: 'Windows',
|
|
7
|
+
android: 'Android',
|
|
8
|
+
freebsd: 'FreeBSD',
|
|
9
|
+
openbsd: 'OpenBSD',
|
|
10
|
+
sunos: 'Solaris',
|
|
11
|
+
linux: 'Linux',
|
|
12
|
+
haiku: undefined,
|
|
13
|
+
cygwin: undefined,
|
|
14
|
+
netbsd: undefined
|
|
15
|
+
};
|
|
16
|
+
const BROWSER_MAP = {
|
|
17
|
+
safari: 'Safari',
|
|
18
|
+
chrome: 'Chrome',
|
|
19
|
+
edge: 'Edge',
|
|
20
|
+
firefox: 'Firefox',
|
|
21
|
+
opera: 'Opera',
|
|
22
|
+
brave: 'Brave',
|
|
23
|
+
samsung: 'Samsung Internet'
|
|
24
|
+
};
|
|
25
|
+
const getBrowserN = (bros) => {
|
|
26
|
+
const brosN = BROWSER_MAP[bros] || bros;
|
|
27
|
+
return brosN;
|
|
28
|
+
};
|
|
29
|
+
export const Browsers = {
|
|
30
|
+
ubuntu: browser => ['Ubuntu', getBrowserN(browser), '22.04.4'],
|
|
31
|
+
macOS: browser => ['Mac OS', getBrowserN(browser), '14.4.1'],
|
|
32
|
+
baileys: browser => ['Baileys', getBrowserN(browser), '6.5.0'],
|
|
33
|
+
windows: browser => ['Windows', getBrowserN(browser), '10.0.22631'],
|
|
34
|
+
iOS: browser => ['iOS', getBrowserN(browser), '18.2'],
|
|
35
|
+
android: browser => ['Android', getBrowserN(browser), '14.0.0'],
|
|
36
|
+
safari: browser => ['Safari', getBrowserN(browser), '26.5'],
|
|
37
|
+
custom: (platform, browser, ver) => {
|
|
38
|
+
let platformN = PLATFORM_MAP[platform].toLowerCase() || platform;
|
|
39
|
+
return [platformN, getBrowserN(browser), ver];
|
|
40
|
+
},
|
|
41
|
+
/** The appropriate browser based on your OS & release */
|
|
42
|
+
appropriate: browser => [PLATFORM_MAP[platform()] || 'Ubuntu', getBrowserN(browser), release()]
|
|
43
|
+
};
|
|
44
|
+
export const getPlatformId = (browser) => {
|
|
45
|
+
const platformType = proto.DeviceProps.PlatformType[browser.toUpperCase()];
|
|
46
|
+
return platformType ? platformType.toString() : '1'; //chrome
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=browser-utils.js.map
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { Boom } from '@hapi/boom';
|
|
2
|
+
import { createHash } from 'crypto';
|
|
3
|
+
import { createWriteStream, promises as fs } from 'fs';
|
|
4
|
+
import { tmpdir } from 'os';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import { getBinaryNodeChild, getBinaryNodeChildren, getBinaryNodeChildString } from '../WABinary/index.js';
|
|
7
|
+
import { generateMessageIDV2 } from './generics.js';
|
|
8
|
+
import { getStream, getUrlFromDirectPath } from './messages-media.js';
|
|
9
|
+
export const parseCatalogNode = (node) => {
|
|
10
|
+
const catalogNode = getBinaryNodeChild(node, 'product_catalog');
|
|
11
|
+
const products = getBinaryNodeChildren(catalogNode, 'product').map(parseProductNode);
|
|
12
|
+
const paging = getBinaryNodeChild(catalogNode, 'paging');
|
|
13
|
+
return {
|
|
14
|
+
products,
|
|
15
|
+
nextPageCursor: paging ? getBinaryNodeChildString(paging, 'after') : undefined
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export const parseCollectionsNode = (node) => {
|
|
19
|
+
const collectionsNode = getBinaryNodeChild(node, 'collections');
|
|
20
|
+
const collections = getBinaryNodeChildren(collectionsNode, 'collection').map(collectionNode => {
|
|
21
|
+
const id = getBinaryNodeChildString(collectionNode, 'id');
|
|
22
|
+
const name = getBinaryNodeChildString(collectionNode, 'name');
|
|
23
|
+
const products = getBinaryNodeChildren(collectionNode, 'product').map(parseProductNode);
|
|
24
|
+
return {
|
|
25
|
+
id,
|
|
26
|
+
name,
|
|
27
|
+
products,
|
|
28
|
+
status: parseStatusInfo(collectionNode)
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
return {
|
|
32
|
+
collections
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export const parseOrderDetailsNode = (node) => {
|
|
36
|
+
const orderNode = getBinaryNodeChild(node, 'order');
|
|
37
|
+
const products = getBinaryNodeChildren(orderNode, 'product').map(productNode => {
|
|
38
|
+
const imageNode = getBinaryNodeChild(productNode, 'image');
|
|
39
|
+
return {
|
|
40
|
+
id: getBinaryNodeChildString(productNode, 'id'),
|
|
41
|
+
name: getBinaryNodeChildString(productNode, 'name'),
|
|
42
|
+
imageUrl: getBinaryNodeChildString(imageNode, 'url'),
|
|
43
|
+
price: +getBinaryNodeChildString(productNode, 'price'),
|
|
44
|
+
currency: getBinaryNodeChildString(productNode, 'currency'),
|
|
45
|
+
quantity: +getBinaryNodeChildString(productNode, 'quantity')
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
const priceNode = getBinaryNodeChild(orderNode, 'price');
|
|
49
|
+
const orderDetails = {
|
|
50
|
+
price: {
|
|
51
|
+
total: +getBinaryNodeChildString(priceNode, 'total'),
|
|
52
|
+
currency: getBinaryNodeChildString(priceNode, 'currency')
|
|
53
|
+
},
|
|
54
|
+
products
|
|
55
|
+
};
|
|
56
|
+
return orderDetails;
|
|
57
|
+
};
|
|
58
|
+
export const toProductNode = (productId, product) => {
|
|
59
|
+
const attrs = {};
|
|
60
|
+
const content = [];
|
|
61
|
+
if (typeof productId !== 'undefined') {
|
|
62
|
+
content.push({
|
|
63
|
+
tag: 'id',
|
|
64
|
+
attrs: {},
|
|
65
|
+
content: Buffer.from(productId)
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
if (typeof product.name !== 'undefined') {
|
|
69
|
+
content.push({
|
|
70
|
+
tag: 'name',
|
|
71
|
+
attrs: {},
|
|
72
|
+
content: Buffer.from(product.name)
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (typeof product.description !== 'undefined') {
|
|
76
|
+
content.push({
|
|
77
|
+
tag: 'description',
|
|
78
|
+
attrs: {},
|
|
79
|
+
content: Buffer.from(product.description)
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
if (typeof product.retailerId !== 'undefined') {
|
|
83
|
+
content.push({
|
|
84
|
+
tag: 'retailer_id',
|
|
85
|
+
attrs: {},
|
|
86
|
+
content: Buffer.from(product.retailerId)
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
if (product.images.length) {
|
|
90
|
+
content.push({
|
|
91
|
+
tag: 'media',
|
|
92
|
+
attrs: {},
|
|
93
|
+
content: product.images.map(img => {
|
|
94
|
+
if (!('url' in img)) {
|
|
95
|
+
throw new Boom('Expected img for product to already be uploaded', { statusCode: 400 });
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
tag: 'image',
|
|
99
|
+
attrs: {},
|
|
100
|
+
content: [
|
|
101
|
+
{
|
|
102
|
+
tag: 'url',
|
|
103
|
+
attrs: {},
|
|
104
|
+
content: Buffer.from(img.url.toString())
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
};
|
|
108
|
+
})
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
if (typeof product.price !== 'undefined') {
|
|
112
|
+
content.push({
|
|
113
|
+
tag: 'price',
|
|
114
|
+
attrs: {},
|
|
115
|
+
content: Buffer.from(product.price.toString())
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
if (typeof product.currency !== 'undefined') {
|
|
119
|
+
content.push({
|
|
120
|
+
tag: 'currency',
|
|
121
|
+
attrs: {},
|
|
122
|
+
content: Buffer.from(product.currency)
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
if ('originCountryCode' in product) {
|
|
126
|
+
if (typeof product.originCountryCode === 'undefined') {
|
|
127
|
+
attrs['compliance_category'] = 'COUNTRY_ORIGIN_EXEMPT';
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
content.push({
|
|
131
|
+
tag: 'compliance_info',
|
|
132
|
+
attrs: {},
|
|
133
|
+
content: [
|
|
134
|
+
{
|
|
135
|
+
tag: 'country_code_origin',
|
|
136
|
+
attrs: {},
|
|
137
|
+
content: Buffer.from(product.originCountryCode)
|
|
138
|
+
}
|
|
139
|
+
]
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (typeof product.isHidden !== 'undefined') {
|
|
144
|
+
attrs['is_hidden'] = product.isHidden.toString();
|
|
145
|
+
}
|
|
146
|
+
const node = {
|
|
147
|
+
tag: 'product',
|
|
148
|
+
attrs,
|
|
149
|
+
content
|
|
150
|
+
};
|
|
151
|
+
return node;
|
|
152
|
+
};
|
|
153
|
+
export const parseProductNode = (productNode) => {
|
|
154
|
+
const isHidden = productNode.attrs.is_hidden === 'true';
|
|
155
|
+
const id = getBinaryNodeChildString(productNode, 'id');
|
|
156
|
+
const mediaNode = getBinaryNodeChild(productNode, 'media');
|
|
157
|
+
const statusInfoNode = getBinaryNodeChild(productNode, 'status_info');
|
|
158
|
+
const product = {
|
|
159
|
+
id,
|
|
160
|
+
imageUrls: parseImageUrls(mediaNode),
|
|
161
|
+
reviewStatus: {
|
|
162
|
+
whatsapp: getBinaryNodeChildString(statusInfoNode, 'status')
|
|
163
|
+
},
|
|
164
|
+
availability: 'in stock',
|
|
165
|
+
name: getBinaryNodeChildString(productNode, 'name'),
|
|
166
|
+
retailerId: getBinaryNodeChildString(productNode, 'retailer_id'),
|
|
167
|
+
url: getBinaryNodeChildString(productNode, 'url'),
|
|
168
|
+
description: getBinaryNodeChildString(productNode, 'description'),
|
|
169
|
+
price: +getBinaryNodeChildString(productNode, 'price'),
|
|
170
|
+
currency: getBinaryNodeChildString(productNode, 'currency'),
|
|
171
|
+
isHidden
|
|
172
|
+
};
|
|
173
|
+
return product;
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* Uploads images not already uploaded to WA's servers
|
|
177
|
+
*/
|
|
178
|
+
export async function uploadingNecessaryImagesOfProduct(product, waUploadToServer, timeoutMs = 30000) {
|
|
179
|
+
product = {
|
|
180
|
+
...product,
|
|
181
|
+
images: product.images
|
|
182
|
+
? await uploadingNecessaryImages(product.images, waUploadToServer, timeoutMs)
|
|
183
|
+
: product.images
|
|
184
|
+
};
|
|
185
|
+
return product;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Uploads images not already uploaded to WA's servers
|
|
189
|
+
*/
|
|
190
|
+
export const uploadingNecessaryImages = async (images, waUploadToServer, timeoutMs = 30000) => {
|
|
191
|
+
const results = await Promise.all(images.map(async (img) => {
|
|
192
|
+
if ('url' in img) {
|
|
193
|
+
const url = img.url.toString();
|
|
194
|
+
if (url.includes('.whatsapp.net')) {
|
|
195
|
+
return { url };
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const { stream } = await getStream(img);
|
|
199
|
+
const hasher = createHash('sha256');
|
|
200
|
+
const filePath = join(tmpdir(), 'img' + generateMessageIDV2());
|
|
201
|
+
const encFileWriteStream = createWriteStream(filePath);
|
|
202
|
+
for await (const block of stream) {
|
|
203
|
+
hasher.update(block);
|
|
204
|
+
encFileWriteStream.write(block);
|
|
205
|
+
}
|
|
206
|
+
const sha = hasher.digest('base64');
|
|
207
|
+
const { directPath } = await waUploadToServer(filePath, {
|
|
208
|
+
mediaType: 'product-catalog-image',
|
|
209
|
+
fileEncSha256B64: sha,
|
|
210
|
+
timeoutMs
|
|
211
|
+
});
|
|
212
|
+
await fs.unlink(filePath).catch(err => console.log('Error deleting temp file ', err));
|
|
213
|
+
return { url: getUrlFromDirectPath(directPath) };
|
|
214
|
+
}));
|
|
215
|
+
return results;
|
|
216
|
+
};
|
|
217
|
+
const parseImageUrls = (mediaNode) => {
|
|
218
|
+
const imgNode = getBinaryNodeChild(mediaNode, 'image');
|
|
219
|
+
return {
|
|
220
|
+
requested: getBinaryNodeChildString(imgNode, 'request_image_url'),
|
|
221
|
+
original: getBinaryNodeChildString(imgNode, 'original_image_url')
|
|
222
|
+
};
|
|
223
|
+
};
|
|
224
|
+
const parseStatusInfo = (mediaNode) => {
|
|
225
|
+
const node = getBinaryNodeChild(mediaNode, 'status_info');
|
|
226
|
+
return {
|
|
227
|
+
status: getBinaryNodeChildString(node, 'status'),
|
|
228
|
+
canAppeal: getBinaryNodeChildString(node, 'can_appeal') === 'true'
|
|
229
|
+
};
|
|
230
|
+
};
|
|
231
|
+
//# sourceMappingURL=business.js.map
|