hridoy-ultimate 8.0.2 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (281) hide show
  1. package/CHANGELOG.md +68 -40
  2. package/LICENSE +23 -0
  3. package/MERGE_REPORT.md +54 -0
  4. package/README.md +158 -113
  5. package/THIRD_PARTY_NOTICES.md +36 -0
  6. package/docs/TEST_RESULTS.md +68 -0
  7. package/docs/UPSTREAM_API_DOCS.md +2712 -0
  8. package/func/checkUpdate.js +6 -0
  9. package/func/logAdapter.js +33 -0
  10. package/func/logger.js +48 -0
  11. package/index.d.ts +812 -0
  12. package/index.js +30 -824
  13. package/module/config.js +46 -0
  14. package/module/login.js +136 -0
  15. package/module/loginHelper.js +1413 -0
  16. package/module/options.js +55 -0
  17. package/package.json +75 -22
  18. package/scripts/run-tests.js +19 -0
  19. package/scripts/syntax-check.js +22 -0
  20. package/src/{addExternalModule.js → api/action/addExternalModule.js} +8 -8
  21. package/src/{changeAvatar.js → api/action/changeAvatar.js} +32 -33
  22. package/src/{changeBio.js → api/action/changeBio.js} +19 -22
  23. package/src/api/action/dismissScrapingWarning.js +50 -0
  24. package/src/api/action/enableAutoSaveAppState.js +73 -0
  25. package/src/{getCurrentUserID.js → api/action/getCurrentUserID.js} +1 -1
  26. package/src/api/action/handleFriendRequest.js +57 -0
  27. package/src/api/action/logout.js +95 -0
  28. package/src/api/action/refreshFb_dtsg.js +47 -0
  29. package/src/{setPostReaction.js → api/action/setPostReaction.js} +23 -31
  30. package/src/{unfriend.js → api/action/unfriend.js} +14 -14
  31. package/src/api/http/httpGet.js +46 -0
  32. package/src/api/http/httpPost.js +52 -0
  33. package/src/api/http/postFormData.js +47 -0
  34. package/src/api/messaging/addUserToGroup.js +68 -0
  35. package/src/api/messaging/changeAdminStatus.js +126 -0
  36. package/src/{changeArchivedStatus.js → api/messaging/changeArchivedStatus.js} +15 -17
  37. package/src/{changeBlockedStatus.js → api/messaging/changeBlockedStatus.js} +13 -16
  38. package/src/api/messaging/changeGroupImage.js +91 -0
  39. package/src/api/messaging/changeNickname.js +70 -0
  40. package/src/api/messaging/changeThreadColor.js +79 -0
  41. package/src/api/messaging/changeThreadEmoji.js +111 -0
  42. package/src/{createNewGroup.js → api/messaging/createNewGroup.js} +24 -26
  43. package/src/api/messaging/createPoll.js +46 -0
  44. package/src/api/messaging/createThemeAI.js +98 -0
  45. package/src/api/messaging/deleteMessage.js +136 -0
  46. package/src/{deleteThread.js → api/messaging/deleteThread.js} +14 -16
  47. package/src/api/messaging/editMessage.js +105 -0
  48. package/src/api/messaging/forwardAttachment.js +57 -0
  49. package/src/api/messaging/forwardMessage.js +134 -0
  50. package/src/{getEmojiUrl.js → api/messaging/getEmojiUrl.js} +2 -2
  51. package/src/{getFriendsList.js → api/messaging/getFriendsList.js} +16 -19
  52. package/src/{getMessage.js → api/messaging/getMessage.js} +160 -180
  53. package/src/api/messaging/getThemePictures.js +62 -0
  54. package/src/api/messaging/handleMessageRequest.js +65 -0
  55. package/src/api/messaging/markAsDelivered.js +69 -0
  56. package/src/api/messaging/markAsRead.js +110 -0
  57. package/src/api/messaging/markAsReadAll.js +56 -0
  58. package/src/api/messaging/markAsSeen.js +68 -0
  59. package/src/api/messaging/muteThread.js +50 -0
  60. package/src/api/messaging/pinMessage.js +115 -0
  61. package/src/api/messaging/removeUserFromGroup.js +62 -0
  62. package/src/{resolvePhotoUrl.js → api/messaging/resolvePhotoUrl.js} +11 -15
  63. package/src/api/messaging/scheduler.js +264 -0
  64. package/src/{searchForThread.js → api/messaging/searchForThread.js} +12 -12
  65. package/src/api/messaging/sendBroadcast.js +93 -0
  66. package/src/api/messaging/sendMessage.js +269 -0
  67. package/src/api/messaging/sendTypingIndicator.js +90 -0
  68. package/src/api/messaging/sessionGuard.js +130 -0
  69. package/src/api/messaging/setMessageReaction.js +114 -0
  70. package/src/api/messaging/setTitle.js +124 -0
  71. package/src/api/messaging/shareContact.js +98 -0
  72. package/src/{threadColors.js → api/messaging/threadColors.js} +2 -5
  73. package/src/api/messaging/unsendMessage.js +105 -0
  74. package/src/api/messaging/uploadAttachment.js +493 -0
  75. package/src/api/socket/OldMessage.js +199 -0
  76. package/src/api/socket/core/connectMqtt.js +304 -0
  77. package/src/api/socket/core/emitAuth.js +95 -0
  78. package/src/api/socket/core/getSeqID.js +331 -0
  79. package/src/api/socket/core/getTaskResponseData.js +25 -0
  80. package/src/api/socket/core/lifecycle.js +117 -0
  81. package/src/api/socket/core/parseDelta.js +387 -0
  82. package/src/api/socket/detail/buildStream.js +215 -0
  83. package/src/api/socket/detail/constants.js +28 -0
  84. package/src/api/socket/e2ee/crypto.js +173 -0
  85. package/src/api/socket/e2ee/index.js +977 -0
  86. package/src/api/socket/e2ee/localMediaServer.js +59 -0
  87. package/src/api/socket/e2ee/mediaDecode.js +155 -0
  88. package/src/api/socket/e2ee/native/NOTICE.md +29 -0
  89. package/{lib → src/api/socket/e2ee/native/lib}/index.mjs +109 -66
  90. package/src/api/socket/e2ee/native/nativeMediaBridge.js +273 -0
  91. package/src/api/socket/e2ee/proto/ArmadilloApplication.proto +281 -0
  92. package/src/api/socket/e2ee/proto/ArmadilloICDC.proto +14 -0
  93. package/src/api/socket/e2ee/proto/ConsumerApplication.proto +232 -0
  94. package/src/api/socket/e2ee/proto/MessageApplication.proto +82 -0
  95. package/src/api/socket/e2ee/proto/MessageTransport.proto +77 -0
  96. package/src/api/socket/e2ee/proto/WACommon.proto +66 -0
  97. package/src/api/socket/e2ee/proto/WAMediaTransport.proto +176 -0
  98. package/src/api/socket/e2ee/proto/proto-writer.ts +76 -0
  99. package/src/api/socket/e2ee/protocol.js +196 -0
  100. package/src/api/socket/e2ee/ratchet.js +219 -0
  101. package/src/api/socket/e2ee/store.js +182 -0
  102. package/src/api/socket/e2ee/vendor/fme/dist/index.cjs +6477 -0
  103. package/src/api/socket/e2ee/vendor/fme/proto/ArmadilloApplication.proto +281 -0
  104. package/src/api/socket/e2ee/vendor/fme/proto/ArmadilloICDC.proto +14 -0
  105. package/src/api/socket/e2ee/vendor/fme/proto/ConsumerApplication.proto +232 -0
  106. package/src/api/socket/e2ee/vendor/fme/proto/MessageApplication.proto +82 -0
  107. package/src/api/socket/e2ee/vendor/fme/proto/MessageTransport.proto +77 -0
  108. package/src/api/socket/e2ee/vendor/fme/proto/WACommon.proto +66 -0
  109. package/src/api/socket/e2ee/vendor/fme/proto/WAMediaTransport.proto +176 -0
  110. package/src/api/socket/listenE2EE.js +87 -0
  111. package/src/api/socket/listenMqtt.js +499 -0
  112. package/src/api/socket/middleware/index.js +216 -0
  113. package/src/api/socket/sendMessage.js +331 -0
  114. package/src/api/socket/sendMessageMqtt.js +69 -0
  115. package/src/{getThreadHistory.js → api/threads/getThreadHistory.js} +114 -132
  116. package/src/api/threads/getThreadInfo.js +329 -0
  117. package/src/api/threads/getThreadList.js +293 -0
  118. package/src/api/threads/getThreadPictures.js +78 -0
  119. package/src/{getUserID.js → api/users/getUserID.js} +22 -18
  120. package/src/api/users/getUserInfo.js +402 -0
  121. package/src/api/users/getUserInfoV2.js +134 -0
  122. package/src/app/MessengerBot.js +209 -0
  123. package/src/app/MessengerContext.js +32 -0
  124. package/src/app/createFcaClient.js +136 -0
  125. package/src/app/threadInfoRealtimeSync.js +284 -0
  126. package/src/core/sendReqMqtt.js +96 -0
  127. package/src/database/helpers.js +53 -0
  128. package/src/database/models/index.js +88 -0
  129. package/src/database/models/thread.js +50 -0
  130. package/src/database/models/user.js +46 -0
  131. package/src/database/threadData.js +94 -0
  132. package/src/database/userData.js +98 -0
  133. package/src/remote/remoteClient.js +123 -0
  134. package/src/utils/antiSuspension.js +219 -0
  135. package/src/utils/broadcast.js +51 -0
  136. package/src/utils/client.js +10 -0
  137. package/src/utils/constants.js +23 -0
  138. package/src/utils/cookies.js +85 -0
  139. package/src/utils/fingerprint.js +110 -0
  140. package/src/utils/format/attachment.js +357 -0
  141. package/src/utils/format/cookie.js +9 -0
  142. package/src/utils/format/date.js +50 -0
  143. package/src/utils/format/decode.js +44 -0
  144. package/src/utils/format/delta.js +195 -0
  145. package/src/utils/format/ids.js +64 -0
  146. package/src/utils/format/index.js +64 -0
  147. package/src/utils/format/message.js +88 -0
  148. package/src/utils/format/presence.js +132 -0
  149. package/src/utils/format/readTyp.js +44 -0
  150. package/src/utils/format/thread.js +42 -0
  151. package/src/utils/format/utils.js +141 -0
  152. package/src/utils/headers.js +125 -0
  153. package/src/utils/humanizer.js +256 -0
  154. package/src/utils/loginParser/autoLogin.js +125 -0
  155. package/src/utils/loginParser/extractDtsg.js +44 -0
  156. package/src/utils/loginParser/helpers.js +43 -0
  157. package/src/utils/loginParser/index.js +10 -0
  158. package/src/utils/loginParser/parseAndCheckLogin.js +241 -0
  159. package/src/utils/loginParser/textUtils.js +28 -0
  160. package/src/utils/nexca-logger.js +144 -0
  161. package/src/utils/nexca-utils.js +687 -0
  162. package/src/utils/request/client.js +26 -0
  163. package/src/utils/request/config.js +23 -0
  164. package/src/utils/request/defaults.js +46 -0
  165. package/src/utils/request/helpers.js +46 -0
  166. package/src/utils/request/index.js +17 -0
  167. package/src/utils/request/methods.js +163 -0
  168. package/src/utils/request/proxy.js +21 -0
  169. package/src/utils/request/retry.js +77 -0
  170. package/src/utils/request/sanitize.js +49 -0
  171. package/src/utils/typingIndicator.js +202 -0
  172. package/test/helpers/stub-modules.js +122 -0
  173. package/test/integration/logout.test.js +69 -0
  174. package/test/integration/mqtt-lifecycle.test.js +195 -0
  175. package/test/integration/package.test.js +116 -0
  176. package/test/integration/typing-wiring.test.js +71 -0
  177. package/test/unit/fingerprint.test.js +19 -0
  178. package/test/unit/humanizer.test.js +32 -0
  179. package/test/unit/lifecycle.test.js +92 -0
  180. package/test/unit/parsers.test.js +43 -0
  181. package/test/unit/typing.test.js +136 -0
  182. package/ANALYSIS.md +0 -31
  183. package/AUDIT_REPORT.md +0 -57
  184. package/advancedSystem.js +0 -95
  185. package/checkUpdate.js +0 -47
  186. package/config.json +0 -51
  187. package/e2ee.js +0 -738
  188. package/examples/basic-bot.js +0 -122
  189. package/examples/e2ee-bot.js +0 -141
  190. package/fca-config.example.json +0 -73
  191. package/scripts/check.js +0 -38
  192. package/src/OldMessage.js +0 -357
  193. package/src/addUserToGroup.js +0 -117
  194. package/src/changeAdminStatus.js +0 -105
  195. package/src/changeAvatarV2.js +0 -86
  196. package/src/changeAvt.js +0 -85
  197. package/src/changeBlockedStatusMqtt.js +0 -75
  198. package/src/changeCover.js +0 -73
  199. package/src/changeGroupImage.js +0 -137
  200. package/src/changeName.js +0 -79
  201. package/src/changeNickname.js +0 -61
  202. package/src/changeThreadColor.js +0 -67
  203. package/src/changeThreadEmoji.js +0 -57
  204. package/src/changeUsername.js +0 -59
  205. package/src/createCommentPost.js +0 -232
  206. package/src/createPoll.js +0 -73
  207. package/src/createPost.js +0 -276
  208. package/src/deleteMessage.js +0 -58
  209. package/src/editMessage.js +0 -76
  210. package/src/editMessageOld.js +0 -62
  211. package/src/follow.js +0 -74
  212. package/src/forwardAttachment.js +0 -62
  213. package/src/friendList.js +0 -104
  214. package/src/getAccess.js +0 -112
  215. package/src/getAvatarUser.js +0 -78
  216. package/src/getBotInitialData.js +0 -42
  217. package/src/getCtx.js +0 -5
  218. package/src/getOptions.js +0 -5
  219. package/src/getRegion.js +0 -7
  220. package/src/getThreadHistoryDeprecated.js +0 -71
  221. package/src/getThreadInfo.js +0 -232
  222. package/src/getThreadInfoDeprecated.js +0 -56
  223. package/src/getThreadList.js +0 -213
  224. package/src/getThreadListDeprecated.js +0 -46
  225. package/src/getThreadPictures.js +0 -59
  226. package/src/getThreadTheme.js +0 -81
  227. package/src/getUID.js +0 -119
  228. package/src/getUserInfo.js +0 -66
  229. package/src/handleFriendRequest.js +0 -46
  230. package/src/handleMessageRequest.js +0 -47
  231. package/src/httpGet.js +0 -49
  232. package/src/httpPost.js +0 -48
  233. package/src/httpPostFormData.js +0 -70
  234. package/src/listenMqtt.js +0 -1081
  235. package/src/listenNotification.js +0 -85
  236. package/src/logout.js +0 -18
  237. package/src/markAsDelivered.js +0 -47
  238. package/src/markAsRead.js +0 -72
  239. package/src/markAsReadAll.js +0 -40
  240. package/src/markAsSeen.js +0 -48
  241. package/src/metaTheme.js +0 -189
  242. package/src/muteThread.js +0 -45
  243. package/src/note.js +0 -228
  244. package/src/pinMessage.js +0 -54
  245. package/src/refreshFb_dtsg.js +0 -49
  246. package/src/removeSuspiciousAccount.js +0 -78
  247. package/src/removeUserFromGroup.js +0 -81
  248. package/src/reply.js +0 -442
  249. package/src/searchFriends.js +0 -140
  250. package/src/searchStickers.js +0 -53
  251. package/src/send.js +0 -46
  252. package/src/sendButtons.js +0 -163
  253. package/src/sendComment.js +0 -159
  254. package/src/sendFriendRequest.js +0 -112
  255. package/src/sendMessage.js +0 -441
  256. package/src/sendMessageMqtt.js +0 -323
  257. package/src/sendTypingIndicator.js +0 -68
  258. package/src/sendTypingIndicatorV2.js +0 -22
  259. package/src/setActiveStatus.js +0 -92
  260. package/src/setMessageReaction.js +0 -150
  261. package/src/setMessageReactionMqtt.js +0 -104
  262. package/src/setMessageReactionSafe.js +0 -44
  263. package/src/setProfileGuard.js +0 -44
  264. package/src/setProfileLock.js +0 -97
  265. package/src/setStoryReaction.js +0 -133
  266. package/src/setStorySeen.js +0 -108
  267. package/src/setThreadTheme.js +0 -102
  268. package/src/setTitle.js +0 -92
  269. package/src/shareContact.js +0 -110
  270. package/src/shareLink.js +0 -59
  271. package/src/stopListenMqtt.js +0 -60
  272. package/src/storyManager.js +0 -357
  273. package/src/suggestFriend.js +0 -132
  274. package/src/unsendMessage.js +0 -68
  275. package/src/uploadAttachment.js +0 -115
  276. package/test/fixes-1_2_4.test.js +0 -118
  277. package/test/mqtt-stop.test.js +0 -32
  278. package/test/reaction-mqtt.test.js +0 -57
  279. package/utils.js +0 -3056
  280. /package/{build → src/api/socket/e2ee/native/build}/messagix.dll +0 -0
  281. /package/{build → src/api/socket/e2ee/native/build}/messagix.so +0 -0
package/CHANGELOG.md CHANGED
@@ -1,43 +1,71 @@
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.
7
-
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).
16
-
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.
23
-
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.
31
-
32
-
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.
3
+ ## 9.0.0 - hridoy-ultimate (merge of 83 analysed builds)
43
4
 
5
+ Base: hridoy-ultimate 8.0.5 (`fca.zip`), plus fixes taken from the `@eryxenx/fca` 1.0.0-1.1.9,
6
+ `fca-eryxenx` 1.x-39.x lines (see `MERGE_REPORT.md` for the per-fix source versions).
7
+
8
+ ### Added
9
+ - **Typing indicator, default ON** (`src/utils/typingIndicator.js`): shows typing when a
10
+ command-like message arrives, clears it when the reply is sent or after 8 s; zero added
11
+ latency; MQTT and E2EE threads. Options `typingIndicator: false | {...}`,
12
+ `api.getTypingIndicator()`, `api.setTypingIndicator()`, `api.withTyping()`.
13
+ - `messagix.so` / `messagix.dll` bundled in `src/api/socket/e2ee/native/build/` (SHA-256 pinned
14
+ in a test and in `THIRD_PARTY_NOTICES.md`). Enabling needs only `FCA_E2EE_NATIVE=1`; the
15
+ engine stays opt-in because it kicks the vendored engine's socket (same E2EE device).
16
+ - `MERGE_REPORT.md`, `THIRD_PARTY_NOTICES.md` (both were listed in `files` but missing).
17
+ - 10 typing tests, fingerprint test, pinned-binary package test.
18
+
19
+ ### Fixed
20
+ - `setMessageReaction` no longer falls back to the bogus thread id `"0"`; it rejects with a
21
+ clear error when the thread cannot be resolved.
22
+ - Chrome fingerprint pool refreshed to 149.0.7827.102 / 151.0.7922.75 (was Chrome 131-135).
23
+ The User-Agent is now the reduced `Chrome/<major>.0.0.0` form real Chrome sends; the full
24
+ build stays in `Sec-CH-UA-Full-Version-List` (client hints derived from the same fingerprint).
25
+ - `index.d.ts`: `sendTypingIndicator` had the wrong signature; 23 previously undeclared API methods
26
+ and the `humanize` / `typingIndicator` options are now declared.
27
+ - Logout / stopListening clear typing timers.
28
+
29
+ ## 8.0.5 - hridoy-ultimate (first release under this name)
30
+
31
+ Built by merging the eryxenx-fca 1.0.0 - 1.1.9 lineage. Base tree: 1.1.9, with
32
+ `module/loginHelper.js` from 1.1.8 (1.1.9 regressed it).
33
+
34
+ ### Security
35
+ - Removed the hard-coded third-party credential-login host; `apiServer` is now empty by
36
+ default and credential login refuses to run without one explicitly configured.
37
+ - Removed unverifiable prebuilt native binaries (messagix .so/.dll). Native E2EE engine is
38
+ opt-in (`FCA_E2EE_NATIVE=1` + `FCA_E2EE_NATIVE_LIB`).
39
+ - `autoUpdate` default is now `false` (it was an inert stub upstream).
40
+
41
+ ### Fixed
42
+ - Pending reconnect / getSeqID retry timers could revive the listener after `stopListening()`
43
+ (reproduced on 1.1.9: 30 `getSeqID` calls after stop). Timers are now tracked and
44
+ gated by a `_stopped` flag.
45
+ - Reconnect used a fixed 2 s delay forever. Now bounded exponential backoff with jitter,
46
+ attempt budget (default 10) and a `stop_listen` event when exhausted.
47
+ - Calling listen twice left two live MQTT clients; the old client is now replaced.
48
+ - Events from stale/replaced clients are ignored.
49
+ - Late socket `error` after cleanup could throw (EventEmitter with no error handler).
50
+ - Sync queue is published after SUBACKs instead of immediately after subscribe.
51
+ - `logout()` now stops MQTT, disconnects E2EE and clears all timers.
52
+ - `emitAuth` now clears heartbeat / session-keeper / dtsg timers.
53
+ - Session keeper no longer re-arms after stop; heartbeat no longer fights a pending backoff.
54
+ - Undeclared dependencies (`request`, `tough-cookie`, `form-data`, `undici`) are declared.
55
+ - `index.d.ts` declared the wrong module name and had an `IFCAU_Api` typo.
56
+ - Silent `.catch(() => {})` on E2EE disconnect now logs.
57
+
58
+ ### Changed (defaults)
59
+ - Humanizer (reply delay + command cooldown) is opt-in: `humanize: true`.
60
+ - Native E2EE engine is opt-in (reverts 1.0.8 default-on).
61
+ - `t_ms` wait 5 s -> 8 s, MQTT connect timeout 5 s -> 12 s (configurable).
62
+ - Node >= 18 required.
63
+
64
+ ### Added
65
+ - `api.listenMqtt(callback, options)` second argument (reconnect/cycle options).
66
+ - Test suite (36 tests), `scripts/run-tests.js`, `scripts/syntax-check.js`.
67
+ - Docs: README, MERGE_REPORT, THIRD_PARTY_NOTICES, upstream API docs in `docs/`.
68
+
69
+ ### Removed
70
+ - `cheerio`, `totp-generator`, `@noble/curves`, `@noble/hashes` (unused in source).
71
+ - 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.
@@ -0,0 +1,54 @@
1
+ # Merge report - hridoy-ultimate 9.0.0
2
+
3
+ ## Inputs
4
+ - 83 published packages, analysed statically (extract, per-version diff, `node --check`, reading
5
+ the core paths): `@eryxenx/fca` 1.0.0-1.1.9 (18), `fca-eryxenx` 1.0.0-29.0.0 (20),
6
+ 3.0.2 + 30.0.0-39.1.8 (20), 4.0.x + 39.1.9-39.9.0 (20), 6.0.0-9.0.3 (5).
7
+ - `fca.zip` = hridoy-ultimate 8.0.5, used as the base tree (already a hardened merge of
8
+ `@eryxenx/fca` 1.1.9 with `loginHelper.js` from 1.1.8, with a 36-test suite).
9
+ - `messagix.so` / `messagix.dll` supplied by the maintainer.
10
+
11
+ Nothing was run against Facebook. Not every one of the ~14,000 extracted files was read line by
12
+ line; the 12,144 `.js/.cjs/.mjs` files contain only 352 distinct contents.
13
+
14
+ ## What the best builds contributed, and where it stands in 9.0.0
15
+ Verified by reading the 8.0.5 code before touching it.
16
+
17
+ | Improvement | Best source | Status |
18
+ |---|---|---|
19
+ | Stable MQTT (backoff, SUBACK, 8 s / 12 s timeouts, stale-client guard) | `fca-eryxenx` 20-23 | already in base (own implementation, tested) |
20
+ | Native client reuse + `koffi.disposable` string free (leak fixes) | 39.2.0 / 39.2.1 | already in base |
21
+ | 15 s `withTimeout` on native calls | 39.1.8 | already in base |
22
+ | `getThreadInfo` E2EE branch | 39.1.6 | already in base |
23
+ | E2EE group routing in react / unsend / edit | 39.2.2 | already in base (`isE2EEGroup`) |
24
+ | Session keeper (cookie + `fb_dtsg` refresh) | 39.2.7 | already in base |
25
+ | `Accept` header navigation vs XHR | 39.2.5 | already in base |
26
+ | Attachment id fallback in `sendMessage` | 7.0.0 | already in base |
27
+ | Native E2EE engine opt-in (not auto-connected) | 39.2.8 | already in base |
28
+ | Logout stops MQTT / E2EE / timers | none (all builds lacked it) | already in base |
29
+ | Typing indicator | none (only the opt-in humanizer had one) | **new in 9.0.0** |
30
+ | Bundled `messagix` binaries | maintainer upload | **restored in 9.0.0, opt-in** |
31
+ | Reduced UA + refreshed Chrome pool | fingerprint.js from 1.1.7, rebuilt | **new in 9.0.0** |
32
+ | `setMessageReaction` thread `"0"` fallback | present in every build | **fixed in 9.0.0** |
33
+ | `index.d.ts` coverage | 23 of 66 methods missing in 1.1.9 | **fixed in 9.0.0** |
34
+
35
+ ## Rejected on purpose
36
+ - `autoLogin: true` default and the `minhdong.site` credential host (every `fca-eryxenx` build and
37
+ `@eryxenx/fca` 1.0.0-1.0.5). Credentials and the 2FA secret would go to a third party.
38
+ - Default-on humanizer (silently drops commands inside its cooldown), default-on native engine
39
+ (kicks the vendored E2EE socket), bogus `versionCheck` (1.1.9), inert auto-update.
40
+ - 39.3.0-39.9.0: branch cut from the 39.1.2-39.1.4 tree, loses the 39.2.x fixes, adds
41
+ `[E2EE-DEBUG]` logging of full reaction payloads. 39.1.0-39.1.4 / 39.3.0+ also ship a duplicate
42
+ 17.5 MB native copy.
43
+ - `fca-eryxenx` 9.0.0 (syntax error in `core/channel.js:178`), 3.0.2-6.0.0 (`editMessage` requires a
44
+ non-existent `../utils`), 4.0.4's dead "stability patch", the stray `index.js.nexca`, nested
45
+ `e2ee/e2ee/` copies.
46
+
47
+ ## Known issues kept (documented, not hidden)
48
+ - `module/login.js` still installs process-wide `unhandledRejection` / `uncaughtException`
49
+ handlers that log and continue; they keep bots alive but can hide a fatal state.
50
+ - `src/api/messaging/sendMessage.js` is loaded and then overridden by `src/api/socket/sendMessage.js`
51
+ (`loginHelper.js`); kept for backward compatibility.
52
+ - Legacy HTTP paths still use the deprecated `request` library (`src/utils/nexca-utils.js`).
53
+ - Native binaries: x86-64 only, stripped, license wording conflicts (see `THIRD_PARTY_NOTICES.md`).
54
+ - Live Facebook behaviour (login, MQTT, send, react, E2EE, typing) is NOT verified here.
package/README.md CHANGED
@@ -1,134 +1,179 @@
1
- # hridoy-ultimate v8.0.1
1
+ # hridoy-ultimate
2
2
 
3
- **Ultimate Merged, Fixed & Advanced Facebook Chat API**
3
+ **Version 9.0.0 - 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 and `fca-eryxenx` 1.x - 39.x lineages (83 published builds
7
+ analysed, see `MERGE_REPORT.md`; itself derived from fca-unofficial) with a hardened
8
+ MQTT lifecycle: bounded exponential backoff, a reconnect budget, clean shutdown and no
9
+ timer left behind after `stopListening()` / `logout()`.
6
10
 
7
- ---
11
+ > **Unofficial.** This automates a personal Facebook account and may violate Facebook's
12
+ > terms. Accounts can be restricted. Use a throwaway account, never one you can't lose.
8
13
 
9
- ## ✅ Features
10
-
11
- | Feature | Status |
14
+ ## Verification status (read this first)
15
+ | Area | Status |
12
16
  |---|---|
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
17
+ | Unit tests (backoff, scheduler, parsers, humanizer, typing indicator, fingerprint) | **PASS** (real code, no mocks) |
18
+ | MQTT lifecycle, logout, typing wiring, package surface (incl. pinned binary hashes) | **PASS - MOCKED** (fake mqtt/axios; see `test/helpers/stub-modules.js`) |
19
+ | TypeScript typings | **PASS** with `tsc` against a consumer sample (Node types stubbed) |
20
+ | Live Facebook login / MQTT / sending / reactions / attachments | **NOT TESTED** (no network or account in the build environment) |
21
+ | E2EE (encrypted chats) and the bundled native binaries | **NOT TESTED** - needs optional deps and a live account |
22
+ | `npm install` from a clean registry | **NOT TESTED** (build sandbox was offline) |
23
+
24
+ Full results: `docs/TEST_RESULTS.md`. Honest limits: [Known limitations](#known-limitations).
28
25
 
26
+ ## Install
27
+ Requires Node.js >= 18.
29
28
  ```bash
30
- npm install
29
+ npm install hridoy-ultimate # from a registry, or:
30
+ npm install ./hridoy-ultimate-9.0.0.tgz
31
31
  ```
32
+ `sqlite3` compiles/downloads a native module; E2EE-related packages are optional.
32
33
 
33
- ---
34
-
35
- ## 🚀 Usage (GoatBot / Goat-Bot)
36
-
34
+ ## Quick start
37
35
  ```js
38
- const login = require("hridoy-ultimate");
36
+ const login = require("hridoy-ultimate"); // also: require(...).login, .default
39
37
  const fs = require("fs");
40
38
 
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);
39
+ const appState = JSON.parse(fs.readFileSync("appstate.json", "utf8")); // keep this file secret
48
40
 
49
- // Session guard — auto-save appstate
50
- api.sessionGuard("appstate.json");
41
+ login({ appState }, { listenEvents: true, autoReconnect: true }, (err, api) => {
42
+ if (err) return console.error("login failed:", err.error || err.message || err);
51
43
 
52
- api.listenMqtt((err, event) => {
53
- if (event.type === "message") {
54
- api.sendMessage("Hello!", event.threadID);
44
+ const stop = api.listenMqtt((err, event) => {
45
+ if (err) {
46
+ if (err.type === "stop_listen") return console.error("listener gave up:", err.error);
47
+ return console.error(err);
55
48
  }
49
+ if (event.type === "message" && event.body === "ping") {
50
+ api.sendMessage("pong", event.threadID, undefined, event.messageID);
51
+ api.setMessageReaction("👍", event.messageID, event.threadID, () => {}, true);
52
+ }
53
+ }, { maxReconnectAttempts: 10 });
54
+
55
+ process.on("SIGINT", async () => {
56
+ stop.stopListening(async () => { await api.logout(); process.exit(0); });
56
57
  });
57
58
  });
58
59
  ```
60
+ (Argument orders (`sendMessage(msg, threadID, callback, replyToMessageID)`,
61
+ `setMessageReaction(reaction, messageID, threadID, callback, force)`) were read from the source; see
62
+ `docs/UPSTREAM_API_DOCS.md` and `index.d.ts`. These calls are **NOT TESTED live**.)
63
+
64
+ ## Authentication and session security
65
+ - Prefer **appState/cookie login**. Never commit `appstate.json`, cookies or tokens.
66
+ - Credential (email/password/2FA) login goes through a **third-party HTTP API that you must
67
+ configure** (`apiServer` in `fca-config.json`). It is empty by default because those
68
+ secrets would be sent to that host. Only point it at a server you control.
69
+ - Log lines mention cookie *counts*, but I did not audit every log call; treat console output as sensitive.
70
+ - `api.getAppState()` output equals full account access.
71
+
72
+ ## Options
73
+ Login options (`setOptions`): `online`, `selfListen`, `listenEvents`, `updatePresence`,
74
+ `forceLogin`, `autoMarkRead`, `listenTyping`, `autoReconnect`, `emitReady`,
75
+ `selfListenEvent`, `userAgent`, `proxy`, `humanize`, `typingIndicator`.
76
+
77
+ `api.listenMqtt(callback, options)` options (all optional):
78
+ | option | default | meaning |
79
+ |---|---|---|
80
+ | `autoReconnect` | `true` | reconnect after socket loss |
81
+ | `reconnectDelayMs` | 2000 | first backoff delay (doubles each attempt) |
82
+ | `maxReconnectDelayMs` | 300000 | backoff ceiling |
83
+ | `reconnectJitter` | 0.3 | +/- fraction randomised |
84
+ | `maxReconnectAttempts` | 10 | `0` = unlimited (explicit opt-in); on exhaustion you get `{type:"stop_listen"}` |
85
+ | `tmsWaitTimeoutMs` | 8000 | wait for first sync response before cycling |
86
+ | `connectTimeoutMs` | 12000 | MQTT connect timeout |
87
+ | `cycleMs` | 0 | periodic forced reconnect (off) |
88
+ | `reconnectAfterStop` | `false` | restart after `stopListening` |
89
+
90
+ The attempt counter resets after the first healthy sync response.
91
+
92
+ ## Events and MQTT recovery
93
+ - `callback(err, event)`; events include `message`, `message_reply`, `message_edit`,
94
+ `message_reaction`, `message_unsend`, `event`, `typ`, `presence`, `share`,
95
+ `friend_request_received`, `friend_request_cancel` (type strings found in the source parsers;
96
+ per-type shapes are in the upstream docs; none exercised live).
97
+ - Control events arrive as `err` objects: `{type:"ready"}`, `{type:"account_inactive"}`
98
+ (session lost; everything is stopped), `{type:"stop_listen"}` (retry budget exhausted or stopped).
99
+ - Recovery: socket close/error -> backoff reconnect (reuses sync token) -> on repeated
100
+ failure refresh session/dtsg -> give up with `stop_listen`. Stale clients are ignored.
101
+ - Shutdown: `stopListening(cb)` cancels all timers, ends the client, is idempotent.
102
+ `logout()` additionally disconnects E2EE and clears the dtsg refresh timer.
103
+
104
+ ## Typing indicator (default ON)
105
+ Shows "typing..." in a thread the moment a command-like message arrives (GoatBot prefix,
106
+ `/`, `!`, `.`) and clears it when your reply is sent, or after a safety timeout (8 s). It
107
+ adds **no latency**: the event is delivered first, the typing signal is fire-and-forget. Works
108
+ for normal and E2EE threads.
59
109
 
60
- ---
61
-
62
- ## ⚙️ config.json Options
110
+ ```js
111
+ login(cookie, { typingIndicator: false }); // off
112
+ login(cookie, { typingIndicator: { onlyCommands: false } }); // type for every text message
113
+ login(cookie, { typingIndicator: { commands: ["#"], maxMs: 6000, groups: true, dms: true } });
63
114
 
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
- }
115
+ api.setTypingIndicator(false); // switch at runtime
116
+ await api.withTyping(threadID, async () => { /* slow work */ }); // typing while fn runs
117
+ api.sendTypingIndicator(threadID, true, { duration: 5000 }); // manual control
73
118
  ```
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.
119
+ A GoatBot `config.enableTypingIndicator: false` also disables it unless you pass the option
120
+ explicitly. When `humanize` is enabled the humanizer shows typing itself and this one stays out of the way.
121
+
122
+ ## Opt-in features
123
+ - **Humanizer** (`humanize: true`): delays command replies 2-3 s and *drops* commands inside a
124
+ 5.5 s cooldown. Drops are intentional and counted; it is off by default. It contains
125
+ special handling for GoatBot globals.
126
+ - **Native E2EE engine** (group E2EE receive/send and E2EE media): the `messagix` binaries are
127
+ bundled in `src/api/socket/e2ee/native/build/` (x86-64 `.so` / `.dll`, SHA-256 pinned in
128
+ `THIRD_PARTY_NOTICES.md`). It is still **off by default**: set `FCA_E2EE_NATIVE=1` to enable it
129
+ (`FCA_E2EE_NATIVE_LIB=/path` overrides the bundled file, e.g. for ARM or macOS). Why off: the
130
+ native and vendored engines register the same E2EE device and kick each other, so enabling it
131
+ causes socket churn. Provenance of the binaries is "supplied by the maintainer, not
132
+ independently verifiable" - see `THIRD_PARTY_NOTICES.md`.
133
+
134
+ ## API surface
135
+ Package exports (verified by test): `login`, `default`, `createFcaClient`, `MessengerBot`,
136
+ `createMessengerBot`, `MessengerContext`, `attachThreadInfoRealtimeSync`,
137
+ `applyThreadInfoRealtimeEvent`, `CommandHumanizer`, `createCommandHumanizer`,
138
+ `createHumanizerMiddleware`, `humanizer`.
139
+
140
+ Methods attached to `api` after login (one per file in `src/api/`; signatures in upstream docs):
141
+ - action: `addExternalModule changeAvatar changeBio dismissScrapingWarning enableAutoSaveAppState getCurrentUserID handleFriendRequest logout refreshFb_dtsg setPostReaction unfriend`
142
+ - http: `httpGet httpPost postFormData`
143
+ - 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`
144
+ - threads: `getThreadHistory getThreadInfo getThreadList getThreadPictures`
145
+ - users: `getUserID getUserInfo getUserInfoV2`
146
+ - socket: `listenMqtt` (= `listen`), `listenE2EE`, `stopListening`, `stopListeningAsync`
147
+ (Listed from the source tree; none were exercised against live Facebook.)
148
+
149
+ ## Troubleshooting
150
+ - `Cannot find module ...` -> run `npm install`; optional E2EE deps may be absent by design.
151
+ - Login callback error -> appState expired; re-export cookies. Credential login needs `apiServer`.
152
+ - `stop_listen` event -> reconnect budget exhausted; check network/session, then call listen again.
153
+ - `account_inactive` -> Facebook invalidated the session (checkpoint/logout); re-login manually.
154
+ - A `Fca_Database/` folder appears in the working directory on first use (SQLite cache).
155
+
156
+ ## Known limitations
157
+ - No live verification of anything that talks to Facebook; Facebook changes endpoints without notice.
158
+ - Subscribe-then-publish ordering and the 8 s / 12 s timeouts follow upstream's changelog
159
+ reasoning and mqtt.js semantics; not confirmed against live servers.
160
+ - Legacy HTTP paths still use the deprecated `request` library (`nexca-utils.js`); porting to axios is future work.
161
+ - `sequelize`+`sqlite3` are hard dependencies (heavy); `index.d.ts` is upstream-derived; newer methods are typed loosely (`any`).
162
+ - Vendored E2EE bundle has no license header or source.
163
+
164
+ ## Migration from eryxenx-fca 1.x
165
+ - Package name `hridoy-ultimate`; Node >= 18.
166
+ - Humanizer and native E2EE are now **opt-in** (they were default-on in 1.1.x / 1.0.8+).
167
+ - 9.0.0: typing indicator is **on by default** (`typingIndicator: false` to disable); the native binaries are bundled again (still opt-in).
168
+ - `apiServer` has no default; autoUpdate is off.
169
+ - Reconnects are bounded: handle `{type:"stop_listen"}`.
170
+ - `api.listenMqtt(cb, options)` gains an optional second argument.
171
+
172
+ ## Develop
173
+ ```bash
174
+ npm install
175
+ npm test # unit + integration (mocked) tests
176
+ npm run lint # syntax check of every source file
177
+ npm pack # builds hridoy-ultimate-9.0.0.tgz
178
+ ```
179
+ Credits and licenses: `LICENSE`, `THIRD_PARTY_NOTICES.md`. Merge details: `MERGE_REPORT.md`.
@@ -0,0 +1,36 @@
1
+ # Third-party notices
2
+
3
+ hridoy-ultimate is MIT licensed (see `LICENSE`). It contains or builds on the following.
4
+
5
+ ## Code lineage (MIT)
6
+ - `eryxenx-fca` / `@eryxenx/fca` and its contributors (builds 1.x - 39.x were analysed and merged).
7
+ - DongDev and the original `fca-unofficial` lineage (<https://github.com/dongp06>).
8
+ - Optional dependency `fca-unofficial` from `github:VangBanLaNhat/fca-unofficial`.
9
+
10
+ ## Bundled native binaries (opt-in, `FCA_E2EE_NATIVE=1`)
11
+ Location: `src/api/socket/e2ee/native/build/`
12
+
13
+ | File | Size (bytes) | Type | SHA-256 |
14
+ |---|---|---|---|
15
+ | `messagix.so` | 17,504,872 | ELF 64-bit x86-64, stripped | `6249f50cc23de0b11a710266a2323c306d44cf46530880e58e0cd1cf4b5bf8d9` |
16
+ | `messagix.dll` | 15,802,368 | PE32+ DLL x86-64, stripped | `f8597ba86c90c39cec19b660e75eba59f2022678eb20866b740cfa321036885e` |
17
+
18
+ - Supplied by the maintainer. They are byte-identical to the copies found in every analysed
19
+ `eryxenx` package (58 `.so` and 45 `.dll` copies, no differing hash). They are stripped, so
20
+ they could **not** be audited here, and no source ships with them.
21
+ - A test (`test/integration/package.test.js`) fails if either hash changes.
22
+ - Platforms: x86-64 Linux and Windows only. macOS and ARM (e.g. Termux) need your own build via
23
+ `FCA_E2EE_NATIVE_LIB=/path/to/messagix`.
24
+ - **License question to resolve before you redistribute:** the analysed packages disagree about the
25
+ upstream. `native/NOTICE.md` describes mautrix-go / mautrix-meta as MPL-2.0, while the
26
+ `vendor/stfca-native/NOTICE.md` that shipped in some builds (39.1.0-39.1.4, 39.3.0-39.9.0) says the
27
+ `messagix` part is AGPL-3.0. AGPL-3.0 carries network-use source-offer obligations. Check the
28
+ upstream repository for the exact build you use. See also `src/api/socket/e2ee/native/NOTICE.md`.
29
+
30
+ ## Vendored E2EE bundle
31
+ `src/api/socket/e2ee/vendor/fme/dist/index.cjs` (bundled `fb-messenger-e2ee` client) has no license
32
+ header or source in the analysed packages. Treat its terms as unknown.
33
+
34
+ ## Runtime dependencies
35
+ Declared in `package.json`; each keeps its own license (axios, mqtt, ws, sequelize, sqlite3,
36
+ @signalapp/libsignal-client, protobufjs, koffi and others).
@@ -0,0 +1,68 @@
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-13T20:03Z
5
+
6
+ ## npm test (node --test, spec reporter)
7
+ ```
8
+ ✔ [mocked] logout stops MQTT, disconnects E2EE and clears every timer (50.186778ms)
9
+ ✔ [mocked] logout works when no listener was ever started (14.258077ms)
10
+ ✔ [mocked] a failed logout request is reported, not swallowed, and the session stays usable (10.037149ms)
11
+ ✔ [mocked] sync queue is published only after every SUBACK (46.187501ms)
12
+ ✔ [mocked] reconnect after socket close uses backoff, then recovers (17.548562ms)
13
+ ✔ [mocked] stopListening during a cycle must not be revived by a pending retry (race regression) (16.384888ms)
14
+ ✔ [mocked] stopListening clears timers, ends the client and is safe to call twice (21.34972ms)
15
+ ✔ [mocked] late socket 'error' after stopListening does not throw (9.571458ms)
16
+ ✔ [mocked] calling listen twice replaces the old client (no duplicate connection) (12.14378ms)
17
+ ✔ [mocked] gives up after maxReconnectAttempts and reports stop_listen (no infinite loop) (9.182964ms)
18
+ ✔ [mocked] a healthy first sync resets the backoff counter (16.256224ms)
19
+ ✔ [mocked] humanizer middleware is NOT installed by default, and is when opted in (26.861027ms)
20
+ ✔ [mocked] emitAuth stops everything and reports account_inactive (8.374336ms)
21
+ ✔ [mocked] listen(callback, options) applies reconnect options per call (12.31406ms)
22
+ ✔ package metadata: name, version, owner, entry points exist (1.413356ms)
23
+ ✔ regression: every third-party module the source requires is declared (24.539389ms)
24
+ ✔ vendored E2EE bundle: its external requires are declared too (2.38059ms)
25
+ ✔ only the pinned messagix binaries ship, native stays opt-in, no default third-party credential host (125.254664ms)
26
+ ✔ every JS file in the package parses (6235.728346ms)
27
+ ✔ [mocked] package loads with consistent exports (23.934551ms)
28
+ ✔ [mocked] login with empty options reports an error via callback and never throws (3129.536404ms)
29
+ ✔ [mocked] typing middleware is installed by default and shows typing for a command without delaying delivery (44.078959ms)
30
+ ✔ [mocked] plain chat does not trigger typing, and stopListening clears pending typing timers (16.606205ms)
31
+ ✔ [mocked] typing middleware is NOT installed when the humanizer owns typing, or when no controller exists (24.276443ms)
32
+ ✔ fingerprint: UA is the reduced Chrome/<major>.0.0.0 form and the full build only appears in client hints (2.989355ms)
33
+ ✔ humanizer: first command accepted with a bounded delay, burst inside cooldown dropped (2.724519ms)
34
+ ✔ humanizer: non-command messages pass untouched; per-thread isolation (0.56259ms)
35
+ ✔ humanizer: enabled:false never delays or drops (1.317371ms)
36
+ ✔ computeBackoff grows exponentially, is bounded and never negative (5.845535ms)
37
+ ✔ computeBackoff jitter stays within +/- jitter and clamps to max (0.418652ms)
38
+ ✔ computeBackoff tolerates garbage input (0.318463ms)
39
+ ✔ scheduleReconnect: single timer, debounce, stop, exhaustion (1.587298ms)
40
+ ✔ scheduleReconnect: a timer that fires after stop does nothing (race regression) (0.359697ms)
41
+ ✔ maxReconnectAttempts: 0 means unlimited only when explicitly set (1.961505ms)
42
+ ✔ clearListenerTimers is idempotent and clears every owned timer (0.47163ms)
43
+ ✔ detachClient: a late 'error' after detach must not throw (0.605172ms)
44
+ ✔ extractDtsg handles each supported markup shape (2.885756ms)
45
+ ✔ extractDtsg: jazoest forms, empty and non-string input (1.591823ms)
46
+ ✔ fingerprint: default UA and client hints are mutually consistent (1.64789ms)
47
+ ✔ fingerprint: Android UA yields mobile Android hints (no desktop contradiction) (0.50116ms)
48
+ ✔ typing: command-like message starts typing; plain chat / own messages / non-message events do not (1.739404ms)
49
+ ✔ typing: GoatBot prefix and extra prefixes count as commands; onlyCommands:false types for any text (0.355195ms)
50
+ ✔ typing: middleware calls next() synchronously (zero added latency) and then starts typing (1.268156ms)
51
+ ✔ typing: sending a reply clears typing after the send resolves (16.890953ms)
52
+ ✔ typing: safety timeout stops a typing indicator that never got a reply (1.652981ms)
53
+ ✔ typing: repeated starts inside minGapMs do not re-publish; after the gap they do (0.464619ms)
54
+ ✔ typing: disabled by option false, and by GoatBot enableTypingIndicator:false unless explicitly overridden (0.321804ms)
55
+ ✔ typing: configure(false) clears active timers; stopAll is idempotent and publishes nothing (0.424433ms)
56
+ ✔ typing: a throwing / rejecting sendTypingIndicator never breaks the bot (11.013855ms)
57
+ ✔ typing: withTyping shows typing around fn and clears it even when fn throws (1.512949ms)
58
+ ℹ tests 50
59
+ ℹ suites 0
60
+ ℹ pass 50
61
+ ℹ fail 0
62
+ ℹ cancelled 0
63
+ ℹ skipped 0
64
+ ℹ todo 0
65
+ ```
66
+
67
+ ## Not verified here
68
+ Live Facebook login, MQTT traffic, sending, reactions, typing indicator on the wire, E2EE and the bundled native binaries (no network, no account).