hridoy-ultimate 8.0.1 → 8.0.5

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 (273) hide show
  1. package/CHANGELOG.md +37 -35
  2. package/LICENSE +23 -0
  3. package/README.md +135 -115
  4. package/docs/TEST_RESULTS.md +70 -0
  5. package/docs/UPSTREAM_API_DOCS.md +2712 -0
  6. package/func/checkUpdate.js +6 -0
  7. package/func/logAdapter.js +33 -0
  8. package/func/logger.js +48 -0
  9. package/index.d.ts +752 -0
  10. package/index.js +24 -824
  11. package/module/config.js +46 -0
  12. package/module/login.js +135 -0
  13. package/module/loginHelper.js +1398 -0
  14. package/module/options.js +49 -0
  15. package/package.json +75 -24
  16. package/scripts/run-tests.js +19 -0
  17. package/scripts/syntax-check.js +22 -0
  18. package/src/{addExternalModule.js → api/action/addExternalModule.js} +8 -8
  19. package/src/{changeAvatar.js → api/action/changeAvatar.js} +32 -33
  20. package/src/{changeBio.js → api/action/changeBio.js} +19 -22
  21. package/src/api/action/dismissScrapingWarning.js +50 -0
  22. package/src/api/action/enableAutoSaveAppState.js +73 -0
  23. package/src/{getCurrentUserID.js → api/action/getCurrentUserID.js} +1 -1
  24. package/src/api/action/handleFriendRequest.js +57 -0
  25. package/src/api/action/logout.js +94 -0
  26. package/src/api/action/refreshFb_dtsg.js +47 -0
  27. package/src/{setPostReaction.js → api/action/setPostReaction.js} +23 -31
  28. package/src/{unfriend.js → api/action/unfriend.js} +14 -14
  29. package/src/api/http/httpGet.js +46 -0
  30. package/src/api/http/httpPost.js +52 -0
  31. package/src/api/http/postFormData.js +47 -0
  32. package/src/api/messaging/addUserToGroup.js +68 -0
  33. package/src/api/messaging/changeAdminStatus.js +126 -0
  34. package/src/{changeArchivedStatus.js → api/messaging/changeArchivedStatus.js} +15 -17
  35. package/src/{changeBlockedStatus.js → api/messaging/changeBlockedStatus.js} +13 -16
  36. package/src/api/messaging/changeGroupImage.js +91 -0
  37. package/src/api/messaging/changeNickname.js +70 -0
  38. package/src/api/messaging/changeThreadColor.js +79 -0
  39. package/src/api/messaging/changeThreadEmoji.js +111 -0
  40. package/src/{createNewGroup.js → api/messaging/createNewGroup.js} +24 -26
  41. package/src/api/messaging/createPoll.js +46 -0
  42. package/src/api/messaging/createThemeAI.js +98 -0
  43. package/src/api/messaging/deleteMessage.js +136 -0
  44. package/src/{deleteThread.js → api/messaging/deleteThread.js} +14 -16
  45. package/src/api/messaging/editMessage.js +105 -0
  46. package/src/api/messaging/forwardAttachment.js +57 -0
  47. package/src/api/messaging/forwardMessage.js +134 -0
  48. package/src/{getEmojiUrl.js → api/messaging/getEmojiUrl.js} +2 -2
  49. package/src/{getFriendsList.js → api/messaging/getFriendsList.js} +16 -19
  50. package/src/{getMessage.js → api/messaging/getMessage.js} +160 -180
  51. package/src/api/messaging/getThemePictures.js +62 -0
  52. package/src/api/messaging/handleMessageRequest.js +65 -0
  53. package/src/api/messaging/markAsDelivered.js +69 -0
  54. package/src/api/messaging/markAsRead.js +110 -0
  55. package/src/api/messaging/markAsReadAll.js +56 -0
  56. package/src/api/messaging/markAsSeen.js +68 -0
  57. package/src/api/messaging/muteThread.js +50 -0
  58. package/src/api/messaging/pinMessage.js +115 -0
  59. package/src/api/messaging/removeUserFromGroup.js +62 -0
  60. package/src/{resolvePhotoUrl.js → api/messaging/resolvePhotoUrl.js} +11 -15
  61. package/src/api/messaging/scheduler.js +264 -0
  62. package/src/{searchForThread.js → api/messaging/searchForThread.js} +12 -12
  63. package/src/api/messaging/sendBroadcast.js +93 -0
  64. package/src/api/messaging/sendMessage.js +269 -0
  65. package/src/api/messaging/sendTypingIndicator.js +90 -0
  66. package/src/api/messaging/sessionGuard.js +130 -0
  67. package/src/api/messaging/setMessageReaction.js +109 -0
  68. package/src/api/messaging/setTitle.js +124 -0
  69. package/src/api/messaging/shareContact.js +98 -0
  70. package/src/{threadColors.js → api/messaging/threadColors.js} +2 -5
  71. package/src/api/messaging/unsendMessage.js +105 -0
  72. package/src/api/messaging/uploadAttachment.js +493 -0
  73. package/src/api/socket/OldMessage.js +199 -0
  74. package/src/api/socket/core/connectMqtt.js +304 -0
  75. package/src/api/socket/core/emitAuth.js +95 -0
  76. package/src/api/socket/core/getSeqID.js +331 -0
  77. package/src/api/socket/core/getTaskResponseData.js +25 -0
  78. package/src/api/socket/core/lifecycle.js +117 -0
  79. package/src/api/socket/core/parseDelta.js +387 -0
  80. package/src/api/socket/detail/buildStream.js +215 -0
  81. package/src/api/socket/detail/constants.js +28 -0
  82. package/src/api/socket/e2ee/crypto.js +173 -0
  83. package/src/api/socket/e2ee/index.js +961 -0
  84. package/src/api/socket/e2ee/localMediaServer.js +59 -0
  85. package/src/api/socket/e2ee/mediaDecode.js +155 -0
  86. package/src/api/socket/e2ee/native/NOTICE.md +29 -0
  87. package/{lib → src/api/socket/e2ee/native/lib}/index.mjs +109 -66
  88. package/src/api/socket/e2ee/native/nativeMediaBridge.js +273 -0
  89. package/src/api/socket/e2ee/proto/ArmadilloApplication.proto +281 -0
  90. package/src/api/socket/e2ee/proto/ArmadilloICDC.proto +14 -0
  91. package/src/api/socket/e2ee/proto/ConsumerApplication.proto +232 -0
  92. package/src/api/socket/e2ee/proto/MessageApplication.proto +82 -0
  93. package/src/api/socket/e2ee/proto/MessageTransport.proto +77 -0
  94. package/src/api/socket/e2ee/proto/WACommon.proto +66 -0
  95. package/src/api/socket/e2ee/proto/WAMediaTransport.proto +176 -0
  96. package/src/api/socket/e2ee/proto/proto-writer.ts +76 -0
  97. package/src/api/socket/e2ee/protocol.js +196 -0
  98. package/src/api/socket/e2ee/ratchet.js +219 -0
  99. package/src/api/socket/e2ee/store.js +182 -0
  100. package/src/api/socket/e2ee/vendor/fme/dist/index.cjs +6477 -0
  101. package/src/api/socket/e2ee/vendor/fme/proto/ArmadilloApplication.proto +281 -0
  102. package/src/api/socket/e2ee/vendor/fme/proto/ArmadilloICDC.proto +14 -0
  103. package/src/api/socket/e2ee/vendor/fme/proto/ConsumerApplication.proto +232 -0
  104. package/src/api/socket/e2ee/vendor/fme/proto/MessageApplication.proto +82 -0
  105. package/src/api/socket/e2ee/vendor/fme/proto/MessageTransport.proto +77 -0
  106. package/src/api/socket/e2ee/vendor/fme/proto/WACommon.proto +66 -0
  107. package/src/api/socket/e2ee/vendor/fme/proto/WAMediaTransport.proto +176 -0
  108. package/src/api/socket/listenE2EE.js +87 -0
  109. package/src/api/socket/listenMqtt.js +486 -0
  110. package/src/api/socket/middleware/index.js +216 -0
  111. package/src/api/socket/sendMessage.js +331 -0
  112. package/src/api/socket/sendMessageMqtt.js +69 -0
  113. package/src/{getThreadHistory.js → api/threads/getThreadHistory.js} +114 -132
  114. package/src/api/threads/getThreadInfo.js +329 -0
  115. package/src/api/threads/getThreadList.js +293 -0
  116. package/src/api/threads/getThreadPictures.js +78 -0
  117. package/src/{getUserID.js → api/users/getUserID.js} +22 -18
  118. package/src/api/users/getUserInfo.js +402 -0
  119. package/src/api/users/getUserInfoV2.js +134 -0
  120. package/src/app/MessengerBot.js +209 -0
  121. package/src/app/MessengerContext.js +32 -0
  122. package/src/app/createFcaClient.js +136 -0
  123. package/src/app/threadInfoRealtimeSync.js +284 -0
  124. package/src/core/sendReqMqtt.js +96 -0
  125. package/src/database/helpers.js +53 -0
  126. package/src/database/models/index.js +88 -0
  127. package/src/database/models/thread.js +50 -0
  128. package/src/database/models/user.js +46 -0
  129. package/src/database/threadData.js +94 -0
  130. package/src/database/userData.js +98 -0
  131. package/src/remote/remoteClient.js +123 -0
  132. package/src/utils/antiSuspension.js +219 -0
  133. package/src/utils/broadcast.js +51 -0
  134. package/src/utils/client.js +10 -0
  135. package/src/utils/constants.js +23 -0
  136. package/src/utils/cookies.js +85 -0
  137. package/src/utils/fingerprint.js +101 -0
  138. package/src/utils/format/attachment.js +357 -0
  139. package/src/utils/format/cookie.js +9 -0
  140. package/src/utils/format/date.js +50 -0
  141. package/src/utils/format/decode.js +44 -0
  142. package/src/utils/format/delta.js +195 -0
  143. package/src/utils/format/ids.js +64 -0
  144. package/src/utils/format/index.js +64 -0
  145. package/src/utils/format/message.js +88 -0
  146. package/src/utils/format/presence.js +132 -0
  147. package/src/utils/format/readTyp.js +44 -0
  148. package/src/utils/format/thread.js +42 -0
  149. package/src/utils/format/utils.js +141 -0
  150. package/src/utils/headers.js +125 -0
  151. package/src/utils/humanizer.js +256 -0
  152. package/src/utils/loginParser/autoLogin.js +125 -0
  153. package/src/utils/loginParser/extractDtsg.js +44 -0
  154. package/src/utils/loginParser/helpers.js +43 -0
  155. package/src/utils/loginParser/index.js +10 -0
  156. package/src/utils/loginParser/parseAndCheckLogin.js +241 -0
  157. package/src/utils/loginParser/textUtils.js +28 -0
  158. package/src/utils/nexca-logger.js +144 -0
  159. package/src/utils/nexca-utils.js +687 -0
  160. package/src/utils/request/client.js +26 -0
  161. package/src/utils/request/config.js +23 -0
  162. package/src/utils/request/defaults.js +46 -0
  163. package/src/utils/request/helpers.js +46 -0
  164. package/src/utils/request/index.js +17 -0
  165. package/src/utils/request/methods.js +163 -0
  166. package/src/utils/request/proxy.js +21 -0
  167. package/src/utils/request/retry.js +77 -0
  168. package/src/utils/request/sanitize.js +49 -0
  169. package/test/helpers/stub-modules.js +122 -0
  170. package/test/integration/logout.test.js +69 -0
  171. package/test/integration/mqtt-lifecycle.test.js +195 -0
  172. package/test/integration/package.test.js +106 -0
  173. package/test/unit/humanizer.test.js +32 -0
  174. package/test/unit/lifecycle.test.js +92 -0
  175. package/test/unit/parsers.test.js +43 -0
  176. package/ANALYSIS.md +0 -31
  177. package/AUDIT_REPORT.md +0 -57
  178. package/advancedSystem.js +0 -95
  179. package/checkUpdate.js +0 -47
  180. package/config.json +0 -51
  181. package/e2ee.js +0 -738
  182. package/examples/basic-bot.js +0 -122
  183. package/examples/e2ee-bot.js +0 -141
  184. package/fca-config.example.json +0 -73
  185. package/scripts/check.js +0 -38
  186. package/src/OldMessage.js +0 -357
  187. package/src/addUserToGroup.js +0 -117
  188. package/src/changeAdminStatus.js +0 -105
  189. package/src/changeAvatarV2.js +0 -86
  190. package/src/changeAvt.js +0 -85
  191. package/src/changeBlockedStatusMqtt.js +0 -75
  192. package/src/changeCover.js +0 -73
  193. package/src/changeGroupImage.js +0 -137
  194. package/src/changeName.js +0 -79
  195. package/src/changeNickname.js +0 -61
  196. package/src/changeThreadColor.js +0 -67
  197. package/src/changeThreadEmoji.js +0 -57
  198. package/src/changeUsername.js +0 -59
  199. package/src/createCommentPost.js +0 -232
  200. package/src/createPoll.js +0 -73
  201. package/src/createPost.js +0 -276
  202. package/src/deleteMessage.js +0 -58
  203. package/src/editMessage.js +0 -76
  204. package/src/editMessageOld.js +0 -62
  205. package/src/follow.js +0 -74
  206. package/src/forwardAttachment.js +0 -62
  207. package/src/friendList.js +0 -104
  208. package/src/getAccess.js +0 -112
  209. package/src/getAvatarUser.js +0 -78
  210. package/src/getBotInitialData.js +0 -42
  211. package/src/getCtx.js +0 -5
  212. package/src/getOptions.js +0 -5
  213. package/src/getRegion.js +0 -7
  214. package/src/getThreadHistoryDeprecated.js +0 -71
  215. package/src/getThreadInfo.js +0 -232
  216. package/src/getThreadInfoDeprecated.js +0 -56
  217. package/src/getThreadList.js +0 -213
  218. package/src/getThreadListDeprecated.js +0 -46
  219. package/src/getThreadPictures.js +0 -59
  220. package/src/getThreadTheme.js +0 -81
  221. package/src/getUID.js +0 -119
  222. package/src/getUserInfo.js +0 -66
  223. package/src/handleFriendRequest.js +0 -46
  224. package/src/handleMessageRequest.js +0 -47
  225. package/src/httpGet.js +0 -49
  226. package/src/httpPost.js +0 -48
  227. package/src/httpPostFormData.js +0 -70
  228. package/src/listenMqtt.js +0 -1081
  229. package/src/listenNotification.js +0 -85
  230. package/src/logout.js +0 -18
  231. package/src/markAsDelivered.js +0 -47
  232. package/src/markAsRead.js +0 -72
  233. package/src/markAsReadAll.js +0 -40
  234. package/src/markAsSeen.js +0 -48
  235. package/src/metaTheme.js +0 -189
  236. package/src/muteThread.js +0 -45
  237. package/src/note.js +0 -228
  238. package/src/pinMessage.js +0 -54
  239. package/src/refreshFb_dtsg.js +0 -49
  240. package/src/removeSuspiciousAccount.js +0 -78
  241. package/src/removeUserFromGroup.js +0 -81
  242. package/src/reply.js +0 -442
  243. package/src/searchFriends.js +0 -140
  244. package/src/searchStickers.js +0 -53
  245. package/src/send.js +0 -46
  246. package/src/sendButtons.js +0 -163
  247. package/src/sendComment.js +0 -159
  248. package/src/sendFriendRequest.js +0 -112
  249. package/src/sendMessage.js +0 -441
  250. package/src/sendMessageMqtt.js +0 -323
  251. package/src/sendTypingIndicator.js +0 -68
  252. package/src/sendTypingIndicatorV2.js +0 -22
  253. package/src/setActiveStatus.js +0 -92
  254. package/src/setMessageReaction.js +0 -150
  255. package/src/setMessageReactionMqtt.js +0 -104
  256. package/src/setMessageReactionSafe.js +0 -44
  257. package/src/setProfileGuard.js +0 -44
  258. package/src/setProfileLock.js +0 -97
  259. package/src/setStoryReaction.js +0 -133
  260. package/src/setStorySeen.js +0 -108
  261. package/src/setThreadTheme.js +0 -102
  262. package/src/setTitle.js +0 -92
  263. package/src/shareContact.js +0 -110
  264. package/src/shareLink.js +0 -59
  265. package/src/stopListenMqtt.js +0 -60
  266. package/src/storyManager.js +0 -357
  267. package/src/suggestFriend.js +0 -132
  268. package/src/unsendMessage.js +0 -68
  269. package/src/uploadAttachment.js +0 -115
  270. package/test/fixes-1_2_4.test.js +0 -118
  271. package/test/mqtt-stop.test.js +0 -32
  272. package/test/reaction-mqtt.test.js +0 -57
  273. package/utils.js +0 -3056
package/CHANGELOG.md CHANGED
@@ -1,43 +1,45 @@
1
1
  # Changelog
2
2
 
3
- ## 8.0.1
4
- - Rename: package/branding is now `hridoy-ultimate` (was `toru-fca`) in banner, logs, update check, README, examples and config comments.
5
- - Update check env var `HRIDOY_ULTIMATE_NO_UPDATE_CHECK` added (old `TORU_FCA_NO_UPDATE_CHECK` still honoured).
6
- - Internal globals (`global._toruFcaConfig`, `_toruFcaInitDone`) intentionally unchanged for backward compatibility.
3
+ ## 8.0.5 - hridoy-ultimate (first release under this name)
7
4
 
8
- ## 1.2.4
9
- - Fix (critical): `scheduleReconnect()` called `getSeqID()` which is only defined inside the module factory, so every MQTT reconnect threw `ReferenceError` in a timer. Now exposed as `ctx._getSeqID` and called with a try/catch.
10
- - Fix: `changeCover` used `log` without requiring `npmlog`.
11
- - Fix: `createCommentPost` typo `calback`, undefined `image` in attachment error, and `cb(null, err)` resolving errors as success (now rejects).
12
- - Fix: `package.json` declares `form-data` and `https-proxy-agent` (were required but undeclared); removed unused `chalk`, `tough-cookie`, `protobufjs`.
13
- - Fix: `checkUpdate.js` hard-coded version 1.2.1; now read from `package.json`.
14
- - Chore: example config version synced; CRLF -> LF in `reply.js`, `getUID.js`, `httpGet.js`, `httpPost.js`, `changeAvt.js`.
15
- - Add: `scripts/check.js` (`npm run check`) and `test/fixes-1_2_4.test.js` (6 regression tests, incl. a reconnect test verified to fail on the old code).
5
+ Built by merging the eryxenx-fca 1.0.0 - 1.1.9 lineage. Base tree: 1.1.9, with
6
+ `module/loginHelper.js` from 1.1.8 (1.1.9 regressed it).
16
7
 
17
- ## 1.2.3
18
- - Fix: E2EE reconnect timers are tracked, deduplicated, bounded with exponential backoff, and cleared on explicit disconnect.
19
- - Fix: TORU owns E2EE reconnect scheduling to avoid competing reconnect managers.
20
- - Fix: MQTT listener replacement clears stale reconnect/watchdog timers.
21
- - Fix: pending MQTT request callbacks are failed and cleaned up on transport error/close or explicit stop.
22
- - Add: regression test for pending MQTT callback cleanup on stop.
8
+ ### Security
9
+ - Removed the hard-coded third-party credential-login host; `apiServer` is now empty by
10
+ default and credential login refuses to run without one explicitly configured.
11
+ - Removed unverifiable prebuilt native binaries (messagix .so/.dll). Native E2EE engine is
12
+ opt-in (`FCA_E2EE_NATIVE=1` + `FCA_E2EE_NATIVE_LIB`).
13
+ - `autoUpdate` default is now `false` (it was an inert stub upstream).
23
14
 
24
- ## 1.2.2
25
- - Fix: reaction MQTT requests now reject on missing acknowledgement instead of assuming success.
26
- - Fix: reaction MQTT callback and Promise settle once and share the same result.
27
- - Fix: forward explicit MQTT response errors to request callbacks.
28
- - Fix: callback type checks no longer execute user callbacks as a test (pin/edit/block helpers).
29
- - Fix: atomic session writes use unique temporary names and restrictive file permissions.
30
- - Add: Node.js syntax-check script and focused MQTT reaction tests.
15
+ ### Fixed
16
+ - Pending reconnect / getSeqID retry timers could revive the listener after `stopListening()`
17
+ (reproduced on 1.1.9: 30 `getSeqID` calls after stop). Timers are now tracked and
18
+ gated by a `_stopped` flag.
19
+ - Reconnect used a fixed 2 s delay forever. Now bounded exponential backoff with jitter,
20
+ attempt budget (default 10) and a `stop_listen` event when exhausted.
21
+ - Calling listen twice left two live MQTT clients; the old client is now replaced.
22
+ - Events from stale/replaced clients are ignored.
23
+ - Late socket `error` after cleanup could throw (EventEmitter with no error handler).
24
+ - Sync queue is published after SUBACKs instead of immediately after subscribe.
25
+ - `logout()` now stops MQTT, disconnects E2EE and clears all timers.
26
+ - `emitAuth` now clears heartbeat / session-keeper / dtsg timers.
27
+ - Session keeper no longer re-arms after stop; heartbeat no longer fights a pending backoff.
28
+ - Undeclared dependencies (`request`, `tough-cookie`, `form-data`, `undici`) are declared.
29
+ - `index.d.ts` declared the wrong module name and had an `IFCAU_Api` typo.
30
+ - Silent `.catch(() => {})` on E2EE disconnect now logs.
31
31
 
32
+ ### Changed (defaults)
33
+ - Humanizer (reply delay + command cooldown) is opt-in: `humanize: true`.
34
+ - Native E2EE engine is opt-in (reverts 1.0.8 default-on).
35
+ - `t_ms` wait 5 s -> 8 s, MQTT connect timeout 5 s -> 12 s (configurable).
36
+ - Node >= 18 required.
32
37
 
33
- ## 1.2.1
34
- - Fix: setMessageReactionMqtt invoked the user callback prematurely / threw synchronously; now Promise+callback, real ack.
35
- - Add: `/ls_resp` dispatch to `ctx.reqCallbacks` (reaction/pin/block helpers finally get acks).
36
- - Add: richer `message_reaction` event (off, action, isGroup, isSingleUser, null-safe).
37
- - Fix: stale MQTT client events caused duplicate reconnects; old client is now torn down first.
38
- - Fix: getSeqID transient failure during reconnect no longer kills the listener (backoff retry).
39
- - Fix: cookie expiry extension edited a copy; now updates the live jar.
40
- - Fix: login callback double-fire guard.
41
- - Change: uncaughtException logs stack for non-network errors.
42
- - Change: e2ee disabled by default; spinner TTY-only; update check opt-out.
38
+ ### Added
39
+ - `api.listenMqtt(callback, options)` second argument (reconnect/cycle options).
40
+ - Test suite (36 tests), `scripts/run-tests.js`, `scripts/syntax-check.js`.
41
+ - Docs: README, MERGE_REPORT, THIRD_PARTY_NOTICES, upstream API docs in `docs/`.
43
42
 
43
+ ### Removed
44
+ - `cheerio`, `totp-generator`, `@noble/curves`, `@noble/hashes` (unused in source).
45
+ - Bogus `versionCheck` update notice (it compared against an unrelated npm package).
package/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ MIT License
2
+
3
+ Copyright (c) EryXenX and contributors (eryxenx-fca 1.0.0 - 1.1.9)
4
+ Copyright (c) DongDev and contributors (original fca-unofficial lineage)
5
+ Copyright (c) 2026 HR ID OY (hridoy-ultimate modifications)
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
package/README.md CHANGED
@@ -1,134 +1,154 @@
1
- # hridoy-ultimate v8.0.1
1
+ # hridoy-ultimate
2
2
 
3
- **Ultimate Merged, Fixed & Advanced Facebook Chat API**
3
+ **Version 8.0.5 - Owner/maintainer: HR ID OY**
4
4
 
5
- > Cookie-based login, session persistence, and MQTT reconnection are best-effort. Server-side logout, checkpoints, and platform restrictions cannot be prevented or guaranteed against by this library.
5
+ An unofficial Facebook Chat API (FCA) for Node.js Messenger bots, unified from the
6
+ `eryxenx-fca` 1.0.0 - 1.1.9 lineage (itself derived from fca-unofficial) with a hardened
7
+ MQTT lifecycle: bounded exponential backoff, a reconnect budget, clean shutdown and no
8
+ timer left behind after `stopListening()` / `logout()`.
6
9
 
7
- ---
10
+ > **Unofficial.** This automates a personal Facebook account and may violate Facebook's
11
+ > terms. Accounts can be restricted. Use a throwaway account, never one you can't lose.
8
12
 
9
- ## ✅ Features
10
-
11
- | Feature | Status |
13
+ ## Verification status (read this first)
14
+ | Area | Status |
12
15
  |---|---|
13
- | Session refresh helper (best-effort) | ⚠️ Best-effort only |
14
- | Conservative presence/delay options | ⚠️ No guarantee |
15
- | Inbox Smooth (bot inbox reply) | ✅ Active |
16
- | GoatBot Compatible | ✅ Ready |
17
- | Session Guard (auto-save) | ✅ Every 3min |
18
- | fb_dtsg Auto-Refresh | ✅ Every 20min |
19
- | MQTT Stable Reconnect | ✅ Active |
20
- | Error reporting | ✅ Host process handlers preserved |
21
- | E2EE Labyrinth Bridge | ✅ Active |
22
- | Facebook Protection | ✅ New in v1.0.6 |
23
- | Human-like Delay | ✅ New in v1.0.6 |
24
-
25
- ---
26
-
27
- ## 📦 Install
16
+ | Unit tests (backoff, scheduler, parsers, humanizer) | **PASS** (real code, no mocks) |
17
+ | MQTT lifecycle, logout, package surface | **PASS - MOCKED** (fake mqtt/axios; see `test/helpers/stub-modules.js`) |
18
+ | TypeScript typings | **PASS** with `tsc` against a consumer sample (Node types stubbed) |
19
+ | Live Facebook login / MQTT / sending / reactions / attachments | **NOT TESTED** (no network or account in the build environment) |
20
+ | E2EE (encrypted chats) | **NOT TESTED** - needs optional deps and an unbundled native library |
21
+ | `npm install` from a clean registry | **NOT TESTED** (build sandbox was offline) |
22
+
23
+ Full results: `docs/TEST_RESULTS.md`. Honest limits: [Known limitations](#known-limitations).
28
24
 
25
+ ## Install
26
+ Requires Node.js >= 18.
29
27
  ```bash
30
- npm install
28
+ npm install hridoy-ultimate # from a registry, or:
29
+ npm install ./hridoy-ultimate-8.0.5.tgz
31
30
  ```
31
+ `sqlite3` compiles/downloads a native module; E2EE-related packages are optional.
32
32
 
33
- ---
34
-
35
- ## 🚀 Usage (GoatBot / Goat-Bot)
36
-
33
+ ## Quick start
37
34
  ```js
38
- const login = require("hridoy-ultimate");
35
+ const login = require("hridoy-ultimate"); // also: require(...).login, .default
39
36
  const fs = require("fs");
40
37
 
41
- login({ appState: JSON.parse(fs.readFileSync("appstate.json", "utf8")) }, {
42
- listenEvents: true,
43
- selfListen: false,
44
- autoReconnect: true,
45
- online: false
46
- }, (err, api) => {
47
- if (err) return console.error(err);
38
+ const appState = JSON.parse(fs.readFileSync("appstate.json", "utf8")); // keep this file secret
48
39
 
49
- // Session guard — auto-save appstate
50
- api.sessionGuard("appstate.json");
40
+ login({ appState }, { listenEvents: true, autoReconnect: true }, (err, api) => {
41
+ if (err) return console.error("login failed:", err.error || err.message || err);
51
42
 
52
- api.listenMqtt((err, event) => {
53
- if (event.type === "message") {
54
- api.sendMessage("Hello!", event.threadID);
43
+ const stop = api.listenMqtt((err, event) => {
44
+ if (err) {
45
+ if (err.type === "stop_listen") return console.error("listener gave up:", err.error);
46
+ return console.error(err);
55
47
  }
48
+ if (event.type === "message" && event.body === "ping") {
49
+ api.sendMessage("pong", event.threadID, undefined, event.messageID);
50
+ api.setMessageReaction("👍", event.messageID, event.threadID, () => {}, true);
51
+ }
52
+ }, { maxReconnectAttempts: 10 });
53
+
54
+ process.on("SIGINT", async () => {
55
+ stop.stopListening(async () => { await api.logout(); process.exit(0); });
56
56
  });
57
57
  });
58
58
  ```
59
-
60
- ---
61
-
62
- ## ⚙️ config.json Options
63
-
64
- ```json
65
- {
66
- "antiLogout": { "enabled": true, "refreshIntervalMs": 1200000 },
67
- "sessionGuard": { "enabled": true, "intervalMs": 180000 },
68
- "automation": { "enabled": false },
69
- "smooth": { "enabled": true, "messageDelay": 300 },
70
- "facebookProtection": { "enabled": true, "blockAutomationDetection": true, "humanLikeDelay": true },
71
- "inbox": { "enabled": true, "replyToInbox": true }
72
- }
59
+ (Argument orders (`sendMessage(msg, threadID, callback, replyToMessageID)`,
60
+ `setMessageReaction(reaction, messageID, threadID, callback, force)`) were read from the source; see
61
+ `docs/UPSTREAM_API_DOCS.md` and `index.d.ts`. These calls are **NOT TESTED live**.)
62
+
63
+ ## Authentication and session security
64
+ - Prefer **appState/cookie login**. Never commit `appstate.json`, cookies or tokens.
65
+ - Credential (email/password/2FA) login goes through a **third-party HTTP API that you must
66
+ configure** (`apiServer` in `fca-config.json`). It is empty by default because those
67
+ secrets would be sent to that host. Only point it at a server you control.
68
+ - Log lines mention cookie *counts*, but I did not audit every log call; treat console output as sensitive.
69
+ - `api.getAppState()` output equals full account access.
70
+
71
+ ## Options
72
+ Login options (`setOptions`): `online`, `selfListen`, `listenEvents`, `updatePresence`,
73
+ `forceLogin`, `autoMarkRead`, `listenTyping`, `autoReconnect`, `emitReady`,
74
+ `selfListenEvent`, `userAgent`, `proxy`, `humanize`.
75
+
76
+ `api.listenMqtt(callback, options)` options (all optional):
77
+ | option | default | meaning |
78
+ |---|---|---|
79
+ | `autoReconnect` | `true` | reconnect after socket loss |
80
+ | `reconnectDelayMs` | 2000 | first backoff delay (doubles each attempt) |
81
+ | `maxReconnectDelayMs` | 300000 | backoff ceiling |
82
+ | `reconnectJitter` | 0.3 | +/- fraction randomised |
83
+ | `maxReconnectAttempts` | 10 | `0` = unlimited (explicit opt-in); on exhaustion you get `{type:"stop_listen"}` |
84
+ | `tmsWaitTimeoutMs` | 8000 | wait for first sync response before cycling |
85
+ | `connectTimeoutMs` | 12000 | MQTT connect timeout |
86
+ | `cycleMs` | 0 | periodic forced reconnect (off) |
87
+ | `reconnectAfterStop` | `false` | restart after `stopListening` |
88
+
89
+ The attempt counter resets after the first healthy sync response.
90
+
91
+ ## Events and MQTT recovery
92
+ - `callback(err, event)`; events include `message`, `message_reply`, `message_edit`,
93
+ `message_reaction`, `message_unsend`, `event`, `typ`, `presence`, `share`,
94
+ `friend_request_received`, `friend_request_cancel` (type strings found in the source parsers;
95
+ per-type shapes are in the upstream docs; none exercised live).
96
+ - Control events arrive as `err` objects: `{type:"ready"}`, `{type:"account_inactive"}`
97
+ (session lost; everything is stopped), `{type:"stop_listen"}` (retry budget exhausted or stopped).
98
+ - Recovery: socket close/error -> backoff reconnect (reuses sync token) -> on repeated
99
+ failure refresh session/dtsg -> give up with `stop_listen`. Stale clients are ignored.
100
+ - Shutdown: `stopListening(cb)` cancels all timers, ends the client, is idempotent.
101
+ `logout()` additionally disconnects E2EE and clears the dtsg refresh timer.
102
+
103
+ ## Opt-in features
104
+ - **Humanizer** (`humanize: true`): delays command replies 2-3 s and *drops* commands inside a
105
+ 5.5 s cooldown. Drops are intentional and counted; it is off by default. It contains
106
+ special handling for GoatBot globals.
107
+ - **Optional native E2EE engine**: set `FCA_E2EE_NATIVE=1` and `FCA_E2EE_NATIVE_LIB=/path/to/messagix`.
108
+ The library is **not bundled** (provenance unverifiable). Without it, group E2EE and E2EE media are unavailable.
109
+
110
+ ## API surface
111
+ Package exports (verified by test): `login`, `default`, `createFcaClient`, `MessengerBot`,
112
+ `createMessengerBot`, `MessengerContext`, `attachThreadInfoRealtimeSync`,
113
+ `applyThreadInfoRealtimeEvent`, `CommandHumanizer`, `createCommandHumanizer`,
114
+ `createHumanizerMiddleware`, `humanizer`.
115
+
116
+ Methods attached to `api` after login (one per file in `src/api/`; signatures in upstream docs):
117
+ - action: `addExternalModule changeAvatar changeBio dismissScrapingWarning enableAutoSaveAppState getCurrentUserID handleFriendRequest logout refreshFb_dtsg setPostReaction unfriend`
118
+ - http: `httpGet httpPost postFormData`
119
+ - messaging: `addUserToGroup changeAdminStatus changeArchivedStatus changeBlockedStatus changeGroupImage changeNickname changeThreadColor changeThreadEmoji createNewGroup createPoll createThemeAI deleteMessage deleteThread editMessage forwardAttachment forwardMessage getEmojiUrl getFriendsList getMessage getThemePictures handleMessageRequest markAsDelivered markAsRead markAsReadAll markAsSeen muteThread pinMessage removeUserFromGroup resolvePhotoUrl scheduler searchForThread sendBroadcast sendMessage sendTypingIndicator setMessageReaction setTitle shareContact unsendMessage uploadAttachment`
120
+ - threads: `getThreadHistory getThreadInfo getThreadList getThreadPictures`
121
+ - users: `getUserID getUserInfo getUserInfoV2`
122
+ - socket: `listenMqtt` (= `listen`), `listenE2EE`, `stopListening`, `stopListeningAsync`
123
+ (Listed from the source tree; none were exercised against live Facebook.)
124
+
125
+ ## Troubleshooting
126
+ - `Cannot find module ...` -> run `npm install`; optional E2EE deps may be absent by design.
127
+ - Login callback error -> appState expired; re-export cookies. Credential login needs `apiServer`.
128
+ - `stop_listen` event -> reconnect budget exhausted; check network/session, then call listen again.
129
+ - `account_inactive` -> Facebook invalidated the session (checkpoint/logout); re-login manually.
130
+ - A `Fca_Database/` folder appears in the working directory on first use (SQLite cache).
131
+
132
+ ## Known limitations
133
+ - No live verification of anything that talks to Facebook; Facebook changes endpoints without notice.
134
+ - Subscribe-then-publish ordering and the 8 s / 12 s timeouts follow upstream's changelog
135
+ reasoning and mqtt.js semantics; not confirmed against live servers.
136
+ - Legacy HTTP paths still use the deprecated `request` library (`nexca-utils.js`); porting to axios is future work.
137
+ - `sequelize`+`sqlite3` are hard dependencies (heavy); `index.d.ts` is upstream-derived and not exhaustive.
138
+ - Vendored E2EE bundle has no license header or source.
139
+
140
+ ## Migration from eryxenx-fca 1.x
141
+ - Package name `hridoy-ultimate`; Node >= 18.
142
+ - Humanizer and native E2EE are now **opt-in** (they were default-on in 1.1.x / 1.0.8+).
143
+ - `apiServer` has no default; autoUpdate is off.
144
+ - Reconnects are bounded: handle `{type:"stop_listen"}`.
145
+ - `api.listenMqtt(cb, options)` gains an optional second argument.
146
+
147
+ ## Develop
148
+ ```bash
149
+ npm install
150
+ npm test # unit + integration (mocked) tests
151
+ npm run lint # syntax check of every source file
152
+ npm pack # builds hridoy-ultimate-8.0.5.tgz
73
153
  ```
74
-
75
- ---
76
-
77
- ## 🔐 Anti-Logout System
78
-
79
- Cookie login করলে `api.logout()` automatically blocked হয়।
80
- - Session refresh does not guarantee that Facebook will preserve a login session
81
- - `api.logout()` is currently overridden; use `api.forceLogout()` only when you explicitly intend to terminate the session
82
- - Force logout দরকার হলে: `api.forceLogout()`
83
- - Anti-logout বন্ধ করতে: `api.stopAntiLogout()`
84
-
85
- ---
86
-
87
- ## 📊 API Methods
88
-
89
- | Method | Description |
90
- |---|---|
91
- | `api.sendMessage(msg, threadID)` | Message পাঠাও |
92
- | `api.listenMqtt(callback)` | Message শোনো |
93
- | `api.sessionGuard(path, opts)` | Appstate auto-save |
94
- | `api.saveSession(path)` | Manual session save |
95
- | `api.getHealth()` | MQTT + session health |
96
- | `api.forceLogout()` | Force logout (opt-in) |
97
- | `api.stopAntiLogout()` | Anti-logout timer বন্ধ |
98
- | `api.refreshFb_dtsg()` | Manual fb_dtsg refresh |
99
- | `api.sendTypingIndicatorV2(typing, threadID)` | MQTT typing indicator |
100
-
101
- ---
102
-
103
- ## 🛡️ Facebook Protection (v1.0.6)
104
-
105
- - `humanLikeDelay: true` — প্রতিটি message এ random 50-200ms delay, bot traffic pattern unpredictable
106
- - `blockAutomationDetection: true` — online=false, presence update বন্ধ
107
- - ফলে Facebook account এ restriction বা ban আসে না
108
-
109
- ---
110
-
111
- **hridoy-ultimate v8.0.1** — Built on toru-fca 1.2.0 (itself derived from HRIDOY-FCA / ST-FCA). Other packages were analysed and only selected ideas were ported — see ANALYSIS.md
112
-
113
-
114
- ## What's new in v1.2.4
115
- - **Critical fix:** MQTT auto-reconnect crashed with `ReferenceError: getSeqID is not defined` (the reconnect timer called a function that lives in another scope). The factory now exposes it as `ctx._getSeqID` and the timer uses that, guarded by try/catch.
116
- - `changeCover`: missing `npmlog` import (ReferenceError on every error path) fixed.
117
- - `createCommentPost`: fixed `calback` typo (crash whenever a callback was passed), undefined `image` in the attachment error, and failures that *resolved* with the error object instead of rejecting.
118
- - `package.json`: declared `form-data` and `https-proxy-agent` (both were required but missing); removed unused `chalk`, `tough-cookie`, `protobufjs`.
119
- - `checkUpdate` now reads its version from `package.json` (was hard-coded 1.2.1). Example config version synced. CRLF line endings normalised to LF.
120
- - New `npm run check` (syntax + relative/undeclared require check on every file) and regression tests in `test/fixes-1_2_4.test.js`.
121
-
122
- ## Earlier: v1.2.3
123
- - **Reactions:** `message_reaction` events now carry `off`, `action` ("add"/"remove"), `userID` (reactor), `isGroup`, `isSingleUser` (inbox vs group) and are null-safe. `selfListen:false` also ignores the bot's own reactions.
124
- - **api.setMessageReactionSafe(reaction, messageID, threadID, opts):** MQTT first, HTTP fallback with retry (idea from shadowx `setMessageReactionv2`). `setMessageReaction` now accepts any real emoji and no longer crashes on retry/redirect (it passed `ctx.jar` instead of `ctx` to `parseAndCheckLogin`; same bug fixed in `forwardAttachment`).
125
- - **api.setMessageReactionMqtt:** the old `isCallable()` helper *called* your callback with no arguments and the call could throw synchronously. Fixed; supports callbacks and Promises; real ack via `/ls_resp`.
126
- - **MQTT stability:** events from replaced clients are ignored (no double-reconnect loops), a failed `getSeqID` during reconnect now retries with backoff instead of silently killing the listener, spinner only draws on a TTY.
127
- - **Session safety:** cookie-expiry extension now really works (v1.2.0 edited a throw-away copy). Login callback can no longer fire twice.
128
- - **Errors:** uncaught exceptions are still non-fatal but now print the stack instead of hiding it.
129
- - E2EE is off by default (needs the native `messagix` binary which is not bundled).
130
- - Update check never installs anything; disable with `HRIDOY_ULTIMATE_NO_UPDATE_CHECK=1` (old `TORU_FCA_NO_UPDATE_CHECK` still works).
131
-
132
- ## Honest notes
133
- - Login: use `appState` (cookie array / cookie string). `api.logout()` is blocked on purpose; use `api.forceLogout()` if you really want to log out.
134
- - "Facebook protection" (online=false, small delays) only lowers noise. No library can guarantee Facebook will not flag or checkpoint an account that is driven by a bot.
154
+ Credits and licenses: `LICENSE`, `THIRD_PARTY_NOTICES.md`. Merge details: `MERGE_REPORT.md`.
@@ -0,0 +1,70 @@
1
+ # Test results (actual output)
2
+
3
+ Environment: v22.22.2, Linux 6.18.44-fc-v114, no network, third-party modules stubbed (MOCKED where marked).
4
+ Generated: 2026-10-13T00:50Z
5
+
6
+ ## npm test (node --test, spec reporter)
7
+ ```
8
+ ✔ [mocked] logout stops MQTT, disconnects E2EE and clears every timer (34.815074ms)
9
+ ✔ [mocked] logout works when no listener was ever started (10.349818ms)
10
+ ✔ [mocked] a failed logout request is reported, not swallowed, and the session stays usable (7.042588ms)
11
+ ✔ [mocked] sync queue is published only after every SUBACK (35.992484ms)
12
+ ✔ [mocked] reconnect after socket close uses backoff, then recovers (12.978848ms)
13
+ ✔ [mocked] stopListening during a cycle must not be revived by a pending retry (race regression) (10.298466ms)
14
+ ✔ [mocked] stopListening clears timers, ends the client and is safe to call twice (10.426547ms)
15
+ ✔ [mocked] late socket 'error' after stopListening does not throw (6.131105ms)
16
+ ✔ [mocked] calling listen twice replaces the old client (no duplicate connection) (8.659963ms)
17
+ ✔ [mocked] gives up after maxReconnectAttempts and reports stop_listen (no infinite loop) (7.160329ms)
18
+ ✔ [mocked] a healthy first sync resets the backoff counter (7.857639ms)
19
+ ✔ [mocked] humanizer middleware is NOT installed by default, and is when opted in (14.187447ms)
20
+ ✔ [mocked] emitAuth stops everything and reports account_inactive (7.957109ms)
21
+ ✔ [mocked] listen(callback, options) applies reconnect options per call (6.735507ms)
22
+ ✔ package metadata: name, version, owner, entry points exist (1.135404ms)
23
+ ✔ regression: every third-party module the source requires is declared (14.850827ms)
24
+ ✔ vendored E2EE bundle: its external requires are declared too (1.810192ms)
25
+ ✔ no prebuilt native binaries or default third-party credential host ship in the package (5.439855ms)
26
+ ✔ every JS file in the package parses (4215.825382ms)
27
+ ✔ [mocked] package loads with consistent exports (19.12184ms)
28
+ ✔ [mocked] login with empty options reports an error via callback and never throws (3230.691403ms)
29
+ ✔ humanizer: first command accepted with a bounded delay, burst inside cooldown dropped (1.957104ms)
30
+ ✔ humanizer: non-command messages pass untouched; per-thread isolation (0.413424ms)
31
+ ✔ humanizer: enabled:false never delays or drops (0.980328ms)
32
+ ✔ computeBackoff grows exponentially, is bounded and never negative (1.903627ms)
33
+ ✔ computeBackoff jitter stays within +/- jitter and clamps to max (0.181485ms)
34
+ ✔ computeBackoff tolerates garbage input (0.17167ms)
35
+ ✔ scheduleReconnect: single timer, debounce, stop, exhaustion (0.820579ms)
36
+ ✔ scheduleReconnect: a timer that fires after stop does nothing (race regression) (0.217074ms)
37
+ ✔ maxReconnectAttempts: 0 means unlimited only when explicitly set (1.317064ms)
38
+ ✔ clearListenerTimers is idempotent and clears every owned timer (0.41435ms)
39
+ ✔ detachClient: a late 'error' after detach must not throw (0.347064ms)
40
+ ✔ extractDtsg handles each supported markup shape (1.363764ms)
41
+ ✔ extractDtsg: jazoest forms, empty and non-string input (0.821093ms)
42
+ ✔ fingerprint: default UA and client hints are mutually consistent (0.728798ms)
43
+ ✔ fingerprint: Android UA yields mobile Android hints (no desktop contradiction) (0.272025ms)
44
+ ℹ tests 36
45
+ ℹ pass 36
46
+ ℹ fail 0
47
+ ℹ cancelled 0
48
+ ℹ skipped 0
49
+ ℹ duration_ms 15939.95031
50
+ ```
51
+
52
+ ## npm run lint
53
+ ```
54
+ checked 151 files, 0 with syntax errors
55
+ ```
56
+
57
+ ## TypeScript consumer check (tsc, Node types stubbed)
58
+ ```
59
+ tsc exit 0
60
+ ```
61
+
62
+ ## Same lifecycle tests against original eryxenx-fca 1.1.9
63
+ ```
64
+ # tests 11
65
+ # pass 1
66
+ # fail 10
67
+ ```
68
+
69
+ ## NOT TESTED
70
+ Live Facebook login/MQTT/sending/reactions/attachments, E2EE, clean-registry npm install.