@cexy/hoonfca 1.0.1 → 1.0.3

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.
Files changed (170) hide show
  1. package/.travis.yml +6 -0
  2. package/LICENSE-MIT +21 -0
  3. package/index.d.ts +620 -0
  4. package/index.js +778 -1
  5. package/package.json +31 -84
  6. package/src/{apis/addExternalModule.js → addExternalModule.js} +4 -5
  7. package/src/addUserToGroup.js +113 -0
  8. package/src/changeAdminStatus.js +95 -0
  9. package/src/changeApprovalMode.js +79 -0
  10. package/src/changeArchivedStatus.js +55 -0
  11. package/src/changeBio.js +76 -0
  12. package/src/changeBlockedStatus.js +47 -0
  13. package/src/changeBlockedStatusMqtt.js +86 -0
  14. package/src/changeGroupImage.js +133 -0
  15. package/src/changeNickname.js +59 -0
  16. package/src/changeThreadColor.js +71 -0
  17. package/src/{apis/changeThreadEmoji.js → changeThreadEmoji.js} +8 -6
  18. package/src/createNewGroup.js +88 -0
  19. package/src/createPoll.js +130 -0
  20. package/src/deleteMessage.js +56 -0
  21. package/src/deleteThread.js +56 -0
  22. package/src/editMessage.js +63 -0
  23. package/src/forwardAttachment.js +60 -0
  24. package/src/forwardMessage.js +63 -0
  25. package/src/getCurrentUserID.js +7 -0
  26. package/src/getEmojiUrl.js +29 -0
  27. package/src/getFriendsList.js +84 -0
  28. package/src/getGroupsList.js +83 -0
  29. package/src/getMarketplace.js +84 -0
  30. package/src/getNotifications.js +86 -0
  31. package/src/getPagesList.js +83 -0
  32. package/src/getStories.js +88 -0
  33. package/src/getThreadHistory.js +647 -0
  34. package/src/getThreadInfo.js +222 -0
  35. package/src/getThreadList.js +292 -0
  36. package/src/getThreadPictures.js +79 -0
  37. package/src/getUserID.js +66 -0
  38. package/src/getUserInfo.js +128 -0
  39. package/src/handleFriendRequest.js +57 -0
  40. package/src/handleMessageRequest.js +65 -0
  41. package/src/{apis/httpGet.js → httpGet.js} +15 -20
  42. package/src/httpPost.js +58 -0
  43. package/src/listenMqtt.js +1018 -0
  44. package/src/logout.js +75 -0
  45. package/src/markAsDelivered.js +58 -0
  46. package/src/{apis/markAsRead.js → markAsRead.js} +19 -30
  47. package/src/markAsReadAll.js +50 -0
  48. package/src/markAsSeen.js +61 -0
  49. package/src/muteThread.js +52 -0
  50. package/src/pinMessage.js +61 -0
  51. package/src/removeUserFromGroup.js +79 -0
  52. package/src/resolvePhotoUrl.js +45 -0
  53. package/src/searchForThread.js +53 -0
  54. package/src/searchUsers.js +89 -0
  55. package/src/sendComment.js +161 -0
  56. package/src/sendMessage.js +457 -0
  57. package/src/sendTypingIndicator.js +179 -0
  58. package/src/setBio.js +86 -0
  59. package/src/setMessageReaction.js +186 -0
  60. package/src/setPostReaction.js +71 -0
  61. package/src/setTheme.js +313 -0
  62. package/src/setTitle.js +90 -0
  63. package/src/shareContact.js +53 -0
  64. package/src/shareLink.js +62 -0
  65. package/src/threadColors.js +57 -0
  66. package/src/unfriend.js +53 -0
  67. package/src/unsendMessage.js +104 -0
  68. package/utils.js +1447 -0
  69. package/LICENSE +0 -3
  70. package/README.md +0 -491
  71. package/examples/login-with-cookies.js +0 -102
  72. package/examples/verify.js +0 -70
  73. package/src/apis/addUserToGroup.js +0 -108
  74. package/src/apis/changeAdminStatus.js +0 -148
  75. package/src/apis/changeArchivedStatus.js +0 -61
  76. package/src/apis/changeAvatar.js +0 -103
  77. package/src/apis/changeBio.js +0 -69
  78. package/src/apis/changeBlockedStatus.js +0 -54
  79. package/src/apis/changeGroupImage.js +0 -136
  80. package/src/apis/changeThreadColor.js +0 -116
  81. package/src/apis/comment.js +0 -207
  82. package/src/apis/createAITheme.js +0 -129
  83. package/src/apis/createNewGroup.js +0 -79
  84. package/src/apis/createPoll.js +0 -73
  85. package/src/apis/deleteMessage.js +0 -44
  86. package/src/apis/deleteThread.js +0 -52
  87. package/src/apis/e2ee.js +0 -17
  88. package/src/apis/editMessage.js +0 -70
  89. package/src/apis/emoji.js +0 -124
  90. package/src/apis/fetchThemeData.js +0 -82
  91. package/src/apis/follow.js +0 -81
  92. package/src/apis/forwardMessage.js +0 -52
  93. package/src/apis/friend.js +0 -243
  94. package/src/apis/gcmember.js +0 -122
  95. package/src/apis/gcname.js +0 -123
  96. package/src/apis/gcrule.js +0 -119
  97. package/src/apis/getAccess.js +0 -111
  98. package/src/apis/getBotInfo.js +0 -88
  99. package/src/apis/getBotInitialData.js +0 -43
  100. package/src/apis/getFriendsList.js +0 -79
  101. package/src/apis/getMessage.js +0 -423
  102. package/src/apis/getTheme.js +0 -95
  103. package/src/apis/getThemeInfo.js +0 -116
  104. package/src/apis/getThreadHistory.js +0 -239
  105. package/src/apis/getThreadInfo.js +0 -267
  106. package/src/apis/getThreadList.js +0 -232
  107. package/src/apis/getThreadPictures.js +0 -58
  108. package/src/apis/getUserID.js +0 -117
  109. package/src/apis/getUserInfo.js +0 -513
  110. package/src/apis/getUserInfoV2.js +0 -146
  111. package/src/apis/handleMessageRequest.js +0 -50
  112. package/src/apis/httpPost.js +0 -89
  113. package/src/apis/httpPostFormData.js +0 -69
  114. package/src/apis/listenMqtt.js +0 -1236
  115. package/src/apis/listenSpeed.js +0 -179
  116. package/src/apis/logout.js +0 -87
  117. package/src/apis/markAsDelivered.js +0 -47
  118. package/src/apis/markAsReadAll.js +0 -40
  119. package/src/apis/markAsSeen.js +0 -70
  120. package/src/apis/mqttDeltaValue.js +0 -278
  121. package/src/apis/muteThread.js +0 -45
  122. package/src/apis/nickname.js +0 -132
  123. package/src/apis/notes.js +0 -163
  124. package/src/apis/pinMessage.js +0 -150
  125. package/src/apis/produceMetaTheme.js +0 -180
  126. package/src/apis/realtime.js +0 -182
  127. package/src/apis/removeUserFromGroup.js +0 -117
  128. package/src/apis/resolvePhotoUrl.js +0 -58
  129. package/src/apis/searchForThread.js +0 -154
  130. package/src/apis/sendMessage.js +0 -354
  131. package/src/apis/sendMessageMqtt.js +0 -249
  132. package/src/apis/sendTypingIndicator.js +0 -91
  133. package/src/apis/setMessageReaction.js +0 -27
  134. package/src/apis/setMessageReactionMqtt.js +0 -61
  135. package/src/apis/setThreadTheme.js +0 -260
  136. package/src/apis/setThreadThemeMqtt.js +0 -94
  137. package/src/apis/share.js +0 -107
  138. package/src/apis/shareContact.js +0 -66
  139. package/src/apis/stickers.js +0 -257
  140. package/src/apis/story.js +0 -181
  141. package/src/apis/theme.js +0 -233
  142. package/src/apis/unfriend.js +0 -47
  143. package/src/apis/unsendMessage.js +0 -17
  144. package/src/engine/client.js +0 -92
  145. package/src/engine/models/buildAPI.js +0 -152
  146. package/src/engine/models/loginHelper.js +0 -519
  147. package/src/engine/models/setOptions.js +0 -88
  148. package/src/security/e2ee.js +0 -109
  149. package/src/types/index.d.ts +0 -498
  150. package/src/utils/antiSuspension.js +0 -506
  151. package/src/utils/auth-helpers.js +0 -149
  152. package/src/utils/autoReLogin.js +0 -336
  153. package/src/utils/axios.js +0 -436
  154. package/src/utils/cache.js +0 -54
  155. package/src/utils/clients.js +0 -282
  156. package/src/utils/constants.js +0 -410
  157. package/src/utils/formatters/data/formatAttachment.js +0 -370
  158. package/src/utils/formatters/data/formatDelta.js +0 -109
  159. package/src/utils/formatters/index.js +0 -159
  160. package/src/utils/formatters/value/formatCookie.js +0 -91
  161. package/src/utils/formatters/value/formatDate.js +0 -36
  162. package/src/utils/formatters/value/formatID.js +0 -16
  163. package/src/utils/formatters.js +0 -1373
  164. package/src/utils/headers.js +0 -230
  165. package/src/utils/index.js +0 -153
  166. package/src/utils/monitoring.js +0 -333
  167. package/src/utils/rateLimiter.js +0 -319
  168. package/src/utils/tokenRefresh.js +0 -657
  169. package/src/utils/user-agents.js +0 -238
  170. package/src/utils/validation.js +0 -157
@@ -1,336 +0,0 @@
1
- "use strict";
2
-
3
- const utils = require('./index');
4
-
5
- // Network error codes and patterns that indicate a transient connectivity
6
- // issue rather than a genuine Facebook session expiry.
7
- const NETWORK_ERROR_PATTERNS = [
8
- 'ECONNRESET', 'ETIMEDOUT', 'ECONNREFUSED', 'ENETUNREACH',
9
- 'EHOSTUNREACH', 'EAI_AGAIN', 'ENOTFOUND', 'ESOCKETTIMEDOUT',
10
- 'socket hang up', 'network error', 'connect ETIMEDOUT',
11
- 'read ECONNRESET', 'write ECONNRESET'
12
- ];
13
-
14
- function isNetworkError(err) {
15
- if (!err) return false;
16
- const msg = (err.message || String(err || '')).toLowerCase();
17
- const code = err.code || '';
18
- return NETWORK_ERROR_PATTERNS.some(p => msg.includes(p.toLowerCase()) || code === p);
19
- }
20
-
21
- class AutoReLoginManager {
22
- constructor() {
23
- this.credentials = null;
24
- this.loginOptions = null;
25
- this.loginCallback = null;
26
- this.isReLoggingIn = false;
27
- this.pendingRequests = [];
28
- this.maxRetries = 5;
29
- this.retryCount = 0;
30
- // Track when the last failure occurred so we can decay retryCount
31
- // automatically after a long quiet period (e.g. temporary FB outage).
32
- this.lastFailureAt = 0;
33
- // If last re-login failure was longer than this ago, reset retryCount.
34
- // Prevents the bot from being permanently dead after a single outage.
35
- this.retryCountDecayMs = 2 * 60 * 60 * 1000; // 2 hours
36
- this.onReLoginSuccess = null;
37
- this.onReLoginFailure = null;
38
- this.enabled = false;
39
- this.reLoginInterval = 1000 * 60 * 60 * 24; // 24 hours
40
- this.sessionMonitorInterval = null;
41
- this.sessionCheckInterval = 1000 * 60 * 30; // 30 minutes
42
- // Lock mechanism to prevent race conditions in re-login
43
- this._reauthLock = null;
44
- this._reauthLockPromise = null;
45
- }
46
-
47
- setCredentials(credentials, options, callback) {
48
- this.credentials = credentials;
49
- this.loginOptions = options || {};
50
- this.loginCallback = callback;
51
- this.enabled = true;
52
- // Reset retry counter on fresh credential set so old failures
53
- // from a previous session do not permanently lock re-login.
54
- this.retryCount = 0;
55
- // Do NOT call startSessionMonitoring() here — the api object is not
56
- // available yet. loginHelper calls startSessionMonitoring(api) once
57
- // all api methods are registered.
58
- }
59
-
60
- startSessionMonitoring(api) {
61
- if (this.sessionMonitorInterval) {
62
- clearInterval(this.sessionMonitorInterval);
63
- }
64
-
65
- if (!this.enabled || !api) return;
66
-
67
- this.sessionMonitorInterval = setInterval(async () => {
68
- if (this.isReLoggingIn) return;
69
-
70
- try {
71
- const isValid = await api.isSessionValid();
72
- if (isValid === 'network_error') {
73
- // Transient connectivity issue — session is probably fine.
74
- utils.warn("AutoReLogin", "Session check returned network error — skipping re-login (transient)");
75
- return;
76
- }
77
- if (!isValid) {
78
- utils.warn("AutoReLogin", "Session health check failed, attempting token refresh first...");
79
-
80
- let refreshed = false;
81
- try {
82
- if (api.tokenRefreshManager && typeof api.tokenRefreshManager.refreshTokens === 'function') {
83
- refreshed = await api.tokenRefreshManager.refreshTokens(
84
- api.ctx,
85
- api.defaultFuncs,
86
- 'https://www.facebook.com'
87
- );
88
- }
89
- } catch (refreshErr) {
90
- if (isNetworkError(refreshErr)) {
91
- utils.warn("AutoReLogin", "Token refresh failed with network error — skipping re-login (transient):", refreshErr.message);
92
- return;
93
- }
94
- utils.warn("AutoReLogin", "Token refresh failed:", refreshErr.message);
95
- }
96
-
97
- if (!refreshed) {
98
- utils.warn("AutoReLogin", "Token refresh unsuccessful, triggering automatic re-login");
99
- await this.handleSessionExpiry(api, 'https://www.facebook.com', "Session expired during monitoring");
100
- } else {
101
- utils.log("AutoReLogin", "Token refresh successful, session restored without re-login");
102
- }
103
- }
104
- } catch (error) {
105
- if (isNetworkError(error)) {
106
- utils.warn("AutoReLogin", "Session monitoring skipped — network error (transient):", error.message);
107
- return;
108
- }
109
- utils.error("AutoReLogin", "Session monitoring error:", error.message);
110
- }
111
- }, this.sessionCheckInterval);
112
-
113
- utils.log("AutoReLogin", `Session monitoring started (interval: ${this.sessionCheckInterval}ms)`);
114
- }
115
-
116
- stopSessionMonitoring() {
117
- if (this.sessionMonitorInterval) {
118
- clearInterval(this.sessionMonitorInterval);
119
- this.sessionMonitorInterval = null;
120
- utils.log("AutoReLogin", "Session monitoring stopped");
121
- }
122
- }
123
-
124
- isEnabled() {
125
- return this.enabled && this.credentials !== null;
126
- }
127
-
128
- async handleSessionExpiry(api, fbLinkOrFunc, ERROR_RETRIEVING) {
129
- if (!this.isEnabled()) {
130
- utils.warn("AutoReLogin", "Auto re-login not enabled. Credentials not stored.");
131
- return false;
132
- }
133
-
134
- // Convert string to function if needed
135
- const fbLinkFunc = typeof fbLinkOrFunc === 'function' ? fbLinkOrFunc : () => fbLinkOrFunc;
136
-
137
- // Acquire lock to prevent concurrent re-login attempts.
138
- // If a re-login is already running, wait for it to finish and return
139
- // its result directly — do NOT start a second parallel re-login.
140
- if (this._reauthLock || this.isReLoggingIn) {
141
- utils.log("AutoReLogin", "Re-login already in progress. Waiting for it to complete...");
142
- return new Promise((resolve, reject) => {
143
- this.pendingRequests.push({ resolve, reject });
144
- });
145
- }
146
-
147
- // Time-based decay: if the last failure was long enough ago (e.g. a
148
- // temporary Facebook/network outage that has since resolved), reset
149
- // retryCount so the bot can try again rather than staying permanently dead.
150
- if (this.retryCount >= this.maxRetries && this.lastFailureAt > 0) {
151
- const timeSinceLastFailure = Date.now() - this.lastFailureAt;
152
- if (timeSinceLastFailure >= this.retryCountDecayMs) {
153
- utils.log("AutoReLogin",
154
- `Resetting retryCount (${this.retryCount}) — last failure was ${Math.round(timeSinceLastFailure / 60000)} min ago (decay window: ${this.retryCountDecayMs / 60000} min)`
155
- );
156
- this.retryCount = 0;
157
- }
158
- }
159
-
160
- if (this.retryCount >= this.maxRetries) {
161
- utils.error("AutoReLogin", `Maximum re-login attempts (${this.maxRetries}) exceeded`);
162
- if (this.onReLoginFailure) {
163
- this.onReLoginFailure(new Error("Max re-login retries exceeded"));
164
- }
165
- return false;
166
- }
167
-
168
- // Set lock
169
- this.isReLoggingIn = true;
170
- let releaseLock;
171
- this._reauthLockPromise = new Promise((resolve) => {
172
- releaseLock = resolve;
173
- });
174
- this._reauthLock = true;
175
-
176
- this.retryCount++;
177
- utils.log("AutoReLogin", `Starting automatic re-login (attempt ${this.retryCount}/${this.maxRetries})...`);
178
-
179
- try {
180
- await this.pauseAPIRequests();
181
-
182
- const loginHelperModel = require('../engine/models/loginHelper');
183
- const setOptionsModel = require('../engine/models/setOptions');
184
- const buildAPIModel = require('../engine/models/buildAPI');
185
-
186
- await new Promise((resolve, reject) => {
187
- loginHelperModel(
188
- this.credentials,
189
- this.loginOptions,
190
- (loginError, newApi) => {
191
- if (loginError) {
192
- reject(loginError);
193
- return;
194
- }
195
-
196
- if (api) {
197
- api.ctx = newApi.ctx;
198
- api.defaultFuncs = newApi.defaultFuncs;
199
-
200
- if (api.tokenRefreshManager) {
201
- api.tokenRefreshManager.resetFailureCount();
202
- }
203
- }
204
-
205
- resolve(newApi);
206
- },
207
- setOptionsModel,
208
- buildAPIModel,
209
- api,
210
- fbLinkFunc, // Use the function we created
211
- ERROR_RETRIEVING
212
- );
213
- });
214
-
215
- utils.log("AutoReLogin", "Re-login successful! Session restored.");
216
- this.retryCount = 0;
217
- this.isReLoggingIn = false;
218
-
219
- this.resolvePendingRequests(true);
220
-
221
- if (this.onReLoginSuccess) {
222
- this.onReLoginSuccess();
223
- }
224
-
225
- try {
226
- if (api && api.listenMqtt && api.ctx && api.ctx._listeningActive) {
227
- try {
228
- if (typeof api.stopListening === 'function') {
229
- try { api.stopListening(); } catch (_) {}
230
- }
231
- const cb = api.ctx._lastListenCallback || null;
232
- if (cb) {
233
- api.listenMqtt(cb);
234
- } else {
235
- api.listenMqtt();
236
- }
237
- } catch (_) {}
238
- }
239
- } catch (_) {}
240
-
241
- return true;
242
- } catch (error) {
243
- utils.error("AutoReLogin", `Re-login failed:`, error.message);
244
- this.isReLoggingIn = false;
245
- this.lastFailureAt = Date.now();
246
-
247
- if (this.retryCount >= this.maxRetries) {
248
- this.resolvePendingRequests(false);
249
- if (this.onReLoginFailure) {
250
- this.onReLoginFailure(error);
251
- }
252
- // Release lock before returning so waiters are unblocked.
253
- this._reauthLock = false;
254
- if (releaseLock) releaseLock();
255
- return false;
256
- }
257
-
258
- const backoffDelay = Math.min(30000, Math.pow(2, this.retryCount) * 1000);
259
- utils.log("AutoReLogin", `Retrying re-login in ${backoffDelay}ms...`);
260
-
261
- // Release the lock BEFORE the retry so the recursive call can
262
- // acquire it. Without this the recursive call sees _reauthLock=true
263
- // and deadlocks waiting for a promise that never resolves.
264
- this._reauthLock = false;
265
- if (releaseLock) releaseLock();
266
-
267
- await new Promise(resolve => setTimeout(resolve, backoffDelay));
268
-
269
- return await this.handleSessionExpiry(api, fbLinkOrFunc, ERROR_RETRIEVING);
270
- } finally {
271
- // Always ensure the lock is released (covers early returns from try block).
272
- if (this._reauthLock) {
273
- this._reauthLock = false;
274
- if (releaseLock) releaseLock();
275
- }
276
- }
277
- }
278
-
279
- async pauseAPIRequests() {
280
- utils.log("AutoReLogin", "Pausing API requests during re-login...");
281
- await new Promise(resolve => setTimeout(resolve, 1000));
282
- }
283
-
284
- resolvePendingRequests(success) {
285
- utils.log("AutoReLogin", `Resolving ${this.pendingRequests.length} pending requests (success: ${success})`);
286
-
287
- this.pendingRequests.forEach(({ resolve, reject }) => {
288
- if (success) {
289
- resolve(true);
290
- } else {
291
- reject(new Error("Re-login failed"));
292
- }
293
- });
294
-
295
- this.pendingRequests = [];
296
- }
297
-
298
- setReLoginSuccessCallback(callback) {
299
- this.onReLoginSuccess = callback;
300
- }
301
-
302
- setReLoginFailureCallback(callback) {
303
- this.onReLoginFailure = callback;
304
- }
305
-
306
- updateAppState(appState) {
307
- if (!this.credentials) return;
308
- if (!Array.isArray(appState) || appState.length === 0) return;
309
- if (!this.credentials.appState || Array.isArray(this.credentials.appState) || typeof this.credentials.appState === "string") {
310
- this.credentials.appState = appState;
311
- }
312
- }
313
-
314
- disable() {
315
- this.enabled = false;
316
- this.stopSessionMonitoring();
317
- this.credentials = null;
318
- this.loginOptions = null;
319
- this.loginCallback = null;
320
- utils.log("AutoReLogin", "Auto re-login disabled and credentials cleared");
321
- }
322
-
323
- reset() {
324
- this.retryCount = 0;
325
- this.isReLoggingIn = false;
326
- this.pendingRequests = [];
327
- }
328
- }
329
-
330
- const globalAutoReLoginManager = new AutoReLoginManager();
331
-
332
- module.exports = {
333
- AutoReLoginManager,
334
- globalAutoReLoginManager,
335
- isNetworkError
336
- };