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.
- package/CHANGELOG.md +68 -40
- package/LICENSE +23 -0
- package/MERGE_REPORT.md +54 -0
- package/README.md +158 -113
- package/THIRD_PARTY_NOTICES.md +36 -0
- package/docs/TEST_RESULTS.md +68 -0
- package/docs/UPSTREAM_API_DOCS.md +2712 -0
- package/func/checkUpdate.js +6 -0
- package/func/logAdapter.js +33 -0
- package/func/logger.js +48 -0
- package/index.d.ts +812 -0
- package/index.js +30 -824
- package/module/config.js +46 -0
- package/module/login.js +136 -0
- package/module/loginHelper.js +1413 -0
- package/module/options.js +55 -0
- package/package.json +75 -22
- package/scripts/run-tests.js +19 -0
- package/scripts/syntax-check.js +22 -0
- package/src/{addExternalModule.js → api/action/addExternalModule.js} +8 -8
- package/src/{changeAvatar.js → api/action/changeAvatar.js} +32 -33
- package/src/{changeBio.js → api/action/changeBio.js} +19 -22
- package/src/api/action/dismissScrapingWarning.js +50 -0
- package/src/api/action/enableAutoSaveAppState.js +73 -0
- package/src/{getCurrentUserID.js → api/action/getCurrentUserID.js} +1 -1
- package/src/api/action/handleFriendRequest.js +57 -0
- package/src/api/action/logout.js +95 -0
- package/src/api/action/refreshFb_dtsg.js +47 -0
- package/src/{setPostReaction.js → api/action/setPostReaction.js} +23 -31
- package/src/{unfriend.js → api/action/unfriend.js} +14 -14
- package/src/api/http/httpGet.js +46 -0
- package/src/api/http/httpPost.js +52 -0
- package/src/api/http/postFormData.js +47 -0
- package/src/api/messaging/addUserToGroup.js +68 -0
- package/src/api/messaging/changeAdminStatus.js +126 -0
- package/src/{changeArchivedStatus.js → api/messaging/changeArchivedStatus.js} +15 -17
- package/src/{changeBlockedStatus.js → api/messaging/changeBlockedStatus.js} +13 -16
- package/src/api/messaging/changeGroupImage.js +91 -0
- package/src/api/messaging/changeNickname.js +70 -0
- package/src/api/messaging/changeThreadColor.js +79 -0
- package/src/api/messaging/changeThreadEmoji.js +111 -0
- package/src/{createNewGroup.js → api/messaging/createNewGroup.js} +24 -26
- package/src/api/messaging/createPoll.js +46 -0
- package/src/api/messaging/createThemeAI.js +98 -0
- package/src/api/messaging/deleteMessage.js +136 -0
- package/src/{deleteThread.js → api/messaging/deleteThread.js} +14 -16
- package/src/api/messaging/editMessage.js +105 -0
- package/src/api/messaging/forwardAttachment.js +57 -0
- package/src/api/messaging/forwardMessage.js +134 -0
- package/src/{getEmojiUrl.js → api/messaging/getEmojiUrl.js} +2 -2
- package/src/{getFriendsList.js → api/messaging/getFriendsList.js} +16 -19
- package/src/{getMessage.js → api/messaging/getMessage.js} +160 -180
- package/src/api/messaging/getThemePictures.js +62 -0
- package/src/api/messaging/handleMessageRequest.js +65 -0
- package/src/api/messaging/markAsDelivered.js +69 -0
- package/src/api/messaging/markAsRead.js +110 -0
- package/src/api/messaging/markAsReadAll.js +56 -0
- package/src/api/messaging/markAsSeen.js +68 -0
- package/src/api/messaging/muteThread.js +50 -0
- package/src/api/messaging/pinMessage.js +115 -0
- package/src/api/messaging/removeUserFromGroup.js +62 -0
- package/src/{resolvePhotoUrl.js → api/messaging/resolvePhotoUrl.js} +11 -15
- package/src/api/messaging/scheduler.js +264 -0
- package/src/{searchForThread.js → api/messaging/searchForThread.js} +12 -12
- package/src/api/messaging/sendBroadcast.js +93 -0
- package/src/api/messaging/sendMessage.js +269 -0
- package/src/api/messaging/sendTypingIndicator.js +90 -0
- package/src/api/messaging/sessionGuard.js +130 -0
- package/src/api/messaging/setMessageReaction.js +114 -0
- package/src/api/messaging/setTitle.js +124 -0
- package/src/api/messaging/shareContact.js +98 -0
- package/src/{threadColors.js → api/messaging/threadColors.js} +2 -5
- package/src/api/messaging/unsendMessage.js +105 -0
- package/src/api/messaging/uploadAttachment.js +493 -0
- package/src/api/socket/OldMessage.js +199 -0
- package/src/api/socket/core/connectMqtt.js +304 -0
- package/src/api/socket/core/emitAuth.js +95 -0
- package/src/api/socket/core/getSeqID.js +331 -0
- package/src/api/socket/core/getTaskResponseData.js +25 -0
- package/src/api/socket/core/lifecycle.js +117 -0
- package/src/api/socket/core/parseDelta.js +387 -0
- package/src/api/socket/detail/buildStream.js +215 -0
- package/src/api/socket/detail/constants.js +28 -0
- package/src/api/socket/e2ee/crypto.js +173 -0
- package/src/api/socket/e2ee/index.js +977 -0
- package/src/api/socket/e2ee/localMediaServer.js +59 -0
- package/src/api/socket/e2ee/mediaDecode.js +155 -0
- package/src/api/socket/e2ee/native/NOTICE.md +29 -0
- package/{lib → src/api/socket/e2ee/native/lib}/index.mjs +109 -66
- package/src/api/socket/e2ee/native/nativeMediaBridge.js +273 -0
- package/src/api/socket/e2ee/proto/ArmadilloApplication.proto +281 -0
- package/src/api/socket/e2ee/proto/ArmadilloICDC.proto +14 -0
- package/src/api/socket/e2ee/proto/ConsumerApplication.proto +232 -0
- package/src/api/socket/e2ee/proto/MessageApplication.proto +82 -0
- package/src/api/socket/e2ee/proto/MessageTransport.proto +77 -0
- package/src/api/socket/e2ee/proto/WACommon.proto +66 -0
- package/src/api/socket/e2ee/proto/WAMediaTransport.proto +176 -0
- package/src/api/socket/e2ee/proto/proto-writer.ts +76 -0
- package/src/api/socket/e2ee/protocol.js +196 -0
- package/src/api/socket/e2ee/ratchet.js +219 -0
- package/src/api/socket/e2ee/store.js +182 -0
- package/src/api/socket/e2ee/vendor/fme/dist/index.cjs +6477 -0
- package/src/api/socket/e2ee/vendor/fme/proto/ArmadilloApplication.proto +281 -0
- package/src/api/socket/e2ee/vendor/fme/proto/ArmadilloICDC.proto +14 -0
- package/src/api/socket/e2ee/vendor/fme/proto/ConsumerApplication.proto +232 -0
- package/src/api/socket/e2ee/vendor/fme/proto/MessageApplication.proto +82 -0
- package/src/api/socket/e2ee/vendor/fme/proto/MessageTransport.proto +77 -0
- package/src/api/socket/e2ee/vendor/fme/proto/WACommon.proto +66 -0
- package/src/api/socket/e2ee/vendor/fme/proto/WAMediaTransport.proto +176 -0
- package/src/api/socket/listenE2EE.js +87 -0
- package/src/api/socket/listenMqtt.js +499 -0
- package/src/api/socket/middleware/index.js +216 -0
- package/src/api/socket/sendMessage.js +331 -0
- package/src/api/socket/sendMessageMqtt.js +69 -0
- package/src/{getThreadHistory.js → api/threads/getThreadHistory.js} +114 -132
- package/src/api/threads/getThreadInfo.js +329 -0
- package/src/api/threads/getThreadList.js +293 -0
- package/src/api/threads/getThreadPictures.js +78 -0
- package/src/{getUserID.js → api/users/getUserID.js} +22 -18
- package/src/api/users/getUserInfo.js +402 -0
- package/src/api/users/getUserInfoV2.js +134 -0
- package/src/app/MessengerBot.js +209 -0
- package/src/app/MessengerContext.js +32 -0
- package/src/app/createFcaClient.js +136 -0
- package/src/app/threadInfoRealtimeSync.js +284 -0
- package/src/core/sendReqMqtt.js +96 -0
- package/src/database/helpers.js +53 -0
- package/src/database/models/index.js +88 -0
- package/src/database/models/thread.js +50 -0
- package/src/database/models/user.js +46 -0
- package/src/database/threadData.js +94 -0
- package/src/database/userData.js +98 -0
- package/src/remote/remoteClient.js +123 -0
- package/src/utils/antiSuspension.js +219 -0
- package/src/utils/broadcast.js +51 -0
- package/src/utils/client.js +10 -0
- package/src/utils/constants.js +23 -0
- package/src/utils/cookies.js +85 -0
- package/src/utils/fingerprint.js +110 -0
- package/src/utils/format/attachment.js +357 -0
- package/src/utils/format/cookie.js +9 -0
- package/src/utils/format/date.js +50 -0
- package/src/utils/format/decode.js +44 -0
- package/src/utils/format/delta.js +195 -0
- package/src/utils/format/ids.js +64 -0
- package/src/utils/format/index.js +64 -0
- package/src/utils/format/message.js +88 -0
- package/src/utils/format/presence.js +132 -0
- package/src/utils/format/readTyp.js +44 -0
- package/src/utils/format/thread.js +42 -0
- package/src/utils/format/utils.js +141 -0
- package/src/utils/headers.js +125 -0
- package/src/utils/humanizer.js +256 -0
- package/src/utils/loginParser/autoLogin.js +125 -0
- package/src/utils/loginParser/extractDtsg.js +44 -0
- package/src/utils/loginParser/helpers.js +43 -0
- package/src/utils/loginParser/index.js +10 -0
- package/src/utils/loginParser/parseAndCheckLogin.js +241 -0
- package/src/utils/loginParser/textUtils.js +28 -0
- package/src/utils/nexca-logger.js +144 -0
- package/src/utils/nexca-utils.js +687 -0
- package/src/utils/request/client.js +26 -0
- package/src/utils/request/config.js +23 -0
- package/src/utils/request/defaults.js +46 -0
- package/src/utils/request/helpers.js +46 -0
- package/src/utils/request/index.js +17 -0
- package/src/utils/request/methods.js +163 -0
- package/src/utils/request/proxy.js +21 -0
- package/src/utils/request/retry.js +77 -0
- package/src/utils/request/sanitize.js +49 -0
- package/src/utils/typingIndicator.js +202 -0
- package/test/helpers/stub-modules.js +122 -0
- package/test/integration/logout.test.js +69 -0
- package/test/integration/mqtt-lifecycle.test.js +195 -0
- package/test/integration/package.test.js +116 -0
- package/test/integration/typing-wiring.test.js +71 -0
- package/test/unit/fingerprint.test.js +19 -0
- package/test/unit/humanizer.test.js +32 -0
- package/test/unit/lifecycle.test.js +92 -0
- package/test/unit/parsers.test.js +43 -0
- package/test/unit/typing.test.js +136 -0
- package/ANALYSIS.md +0 -31
- package/AUDIT_REPORT.md +0 -57
- package/advancedSystem.js +0 -95
- package/checkUpdate.js +0 -47
- package/config.json +0 -51
- package/e2ee.js +0 -738
- package/examples/basic-bot.js +0 -122
- package/examples/e2ee-bot.js +0 -141
- package/fca-config.example.json +0 -73
- package/scripts/check.js +0 -38
- package/src/OldMessage.js +0 -357
- package/src/addUserToGroup.js +0 -117
- package/src/changeAdminStatus.js +0 -105
- package/src/changeAvatarV2.js +0 -86
- package/src/changeAvt.js +0 -85
- package/src/changeBlockedStatusMqtt.js +0 -75
- package/src/changeCover.js +0 -73
- package/src/changeGroupImage.js +0 -137
- package/src/changeName.js +0 -79
- package/src/changeNickname.js +0 -61
- package/src/changeThreadColor.js +0 -67
- package/src/changeThreadEmoji.js +0 -57
- package/src/changeUsername.js +0 -59
- package/src/createCommentPost.js +0 -232
- package/src/createPoll.js +0 -73
- package/src/createPost.js +0 -276
- package/src/deleteMessage.js +0 -58
- package/src/editMessage.js +0 -76
- package/src/editMessageOld.js +0 -62
- package/src/follow.js +0 -74
- package/src/forwardAttachment.js +0 -62
- package/src/friendList.js +0 -104
- package/src/getAccess.js +0 -112
- package/src/getAvatarUser.js +0 -78
- package/src/getBotInitialData.js +0 -42
- package/src/getCtx.js +0 -5
- package/src/getOptions.js +0 -5
- package/src/getRegion.js +0 -7
- package/src/getThreadHistoryDeprecated.js +0 -71
- package/src/getThreadInfo.js +0 -232
- package/src/getThreadInfoDeprecated.js +0 -56
- package/src/getThreadList.js +0 -213
- package/src/getThreadListDeprecated.js +0 -46
- package/src/getThreadPictures.js +0 -59
- package/src/getThreadTheme.js +0 -81
- package/src/getUID.js +0 -119
- package/src/getUserInfo.js +0 -66
- package/src/handleFriendRequest.js +0 -46
- package/src/handleMessageRequest.js +0 -47
- package/src/httpGet.js +0 -49
- package/src/httpPost.js +0 -48
- package/src/httpPostFormData.js +0 -70
- package/src/listenMqtt.js +0 -1081
- package/src/listenNotification.js +0 -85
- package/src/logout.js +0 -18
- package/src/markAsDelivered.js +0 -47
- package/src/markAsRead.js +0 -72
- package/src/markAsReadAll.js +0 -40
- package/src/markAsSeen.js +0 -48
- package/src/metaTheme.js +0 -189
- package/src/muteThread.js +0 -45
- package/src/note.js +0 -228
- package/src/pinMessage.js +0 -54
- package/src/refreshFb_dtsg.js +0 -49
- package/src/removeSuspiciousAccount.js +0 -78
- package/src/removeUserFromGroup.js +0 -81
- package/src/reply.js +0 -442
- package/src/searchFriends.js +0 -140
- package/src/searchStickers.js +0 -53
- package/src/send.js +0 -46
- package/src/sendButtons.js +0 -163
- package/src/sendComment.js +0 -159
- package/src/sendFriendRequest.js +0 -112
- package/src/sendMessage.js +0 -441
- package/src/sendMessageMqtt.js +0 -323
- package/src/sendTypingIndicator.js +0 -68
- package/src/sendTypingIndicatorV2.js +0 -22
- package/src/setActiveStatus.js +0 -92
- package/src/setMessageReaction.js +0 -150
- package/src/setMessageReactionMqtt.js +0 -104
- package/src/setMessageReactionSafe.js +0 -44
- package/src/setProfileGuard.js +0 -44
- package/src/setProfileLock.js +0 -97
- package/src/setStoryReaction.js +0 -133
- package/src/setStorySeen.js +0 -108
- package/src/setThreadTheme.js +0 -102
- package/src/setTitle.js +0 -92
- package/src/shareContact.js +0 -110
- package/src/shareLink.js +0 -59
- package/src/stopListenMqtt.js +0 -60
- package/src/storyManager.js +0 -357
- package/src/suggestFriend.js +0 -132
- package/src/unsendMessage.js +0 -68
- package/src/uploadAttachment.js +0 -115
- package/test/fixes-1_2_4.test.js +0 -118
- package/test/mqtt-stop.test.js +0 -32
- package/test/reaction-mqtt.test.js +0 -57
- package/utils.js +0 -3056
- /package/{build → src/api/socket/e2ee/native/build}/messagix.dll +0 -0
- /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
|
-
##
|
|
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.
|
package/MERGE_REPORT.md
ADDED
|
@@ -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
|
|
1
|
+
# hridoy-ultimate
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Version 9.0.0 - Owner/maintainer: HR ID OY**
|
|
4
4
|
|
|
5
|
-
|
|
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
|
-
##
|
|
10
|
-
|
|
11
|
-
| Feature | Status |
|
|
14
|
+
## Verification status (read this first)
|
|
15
|
+
| Area | Status |
|
|
12
16
|
|---|---|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
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
|
-
|
|
50
|
-
|
|
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 (
|
|
54
|
-
|
|
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
|
-
|
|
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
|
-
|
|
65
|
-
{
|
|
66
|
-
|
|
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
|
-
##
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
- `
|
|
106
|
-
-
|
|
107
|
-
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
-
|
|
116
|
-
- `
|
|
117
|
-
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
-
|
|
124
|
-
-
|
|
125
|
-
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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).
|