fb-messenger-e2ee 0.1.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/DOCS.md +310 -0
- package/LICENSE +660 -0
- package/README.md +153 -0
- package/bun.lock +1014 -0
- package/examples/basic-usage.ts +52 -0
- package/jest.config.ts +18 -0
- package/package.json +56 -0
- package/src/config/env.ts +15 -0
- package/src/controllers/client.controller.ts +805 -0
- package/src/controllers/dgw-handler.ts +171 -0
- package/src/controllers/e2ee-handler.ts +832 -0
- package/src/controllers/event-mapper.ts +327 -0
- package/src/core/client.ts +151 -0
- package/src/e2ee/application/e2ee-client.ts +376 -0
- package/src/e2ee/application/fanout-planner.ts +79 -0
- package/src/e2ee/application/outbound-message-cache.ts +58 -0
- package/src/e2ee/application/prekey-maintenance.ts +55 -0
- package/src/e2ee/application/retry-manager.ts +156 -0
- package/src/e2ee/facebook/facebook-protocol-utils.ts +230 -0
- package/src/e2ee/facebook/icdc-payload.ts +31 -0
- package/src/e2ee/index.ts +76 -0
- package/src/e2ee/internal.ts +27 -0
- package/src/e2ee/media/media-crypto.ts +147 -0
- package/src/e2ee/media/media-upload.ts +90 -0
- package/src/e2ee/message/builders/client-payload.ts +54 -0
- package/src/e2ee/message/builders/consumer-application.ts +362 -0
- package/src/e2ee/message/builders/message-application.ts +64 -0
- package/src/e2ee/message/builders/message-transport.ts +84 -0
- package/src/e2ee/message/codecs/protobuf-codecs.ts +101 -0
- package/src/e2ee/message/constants.ts +4 -0
- package/src/e2ee/message/message-builder.ts +15 -0
- package/src/e2ee/message/proto/ArmadilloApplication.proto +281 -0
- package/src/e2ee/message/proto/ArmadilloICDC.proto +14 -0
- package/src/e2ee/message/proto/ConsumerApplication.proto +232 -0
- package/src/e2ee/message/proto/MessageApplication.proto +82 -0
- package/src/e2ee/message/proto/MessageTransport.proto +77 -0
- package/src/e2ee/message/proto/WACommon.proto +66 -0
- package/src/e2ee/message/proto/WAMediaTransport.proto +176 -0
- package/src/e2ee/message/proto/proto-writer.ts +76 -0
- package/src/e2ee/signal/prekey-manager.ts +140 -0
- package/src/e2ee/signal/signal-manager.ts +365 -0
- package/src/e2ee/store/device-json.ts +47 -0
- package/src/e2ee/store/device-repository.ts +12 -0
- package/src/e2ee/store/device-store.ts +538 -0
- package/src/e2ee/transport/binary/decoder.ts +180 -0
- package/src/e2ee/transport/binary/encoder.ts +143 -0
- package/src/e2ee/transport/binary/stanzas.ts +97 -0
- package/src/e2ee/transport/binary/tokens.ts +64 -0
- package/src/e2ee/transport/binary/wa-binary.ts +8 -0
- package/src/e2ee/transport/dgw/dgw-socket.ts +345 -0
- package/src/e2ee/transport/noise/noise-handshake.ts +417 -0
- package/src/e2ee/transport/noise/noise-socket.ts +230 -0
- package/src/index.ts +34 -0
- package/src/models/client.ts +26 -0
- package/src/models/config.ts +14 -0
- package/src/models/domain.ts +299 -0
- package/src/models/e2ee.ts +295 -0
- package/src/models/media.ts +41 -0
- package/src/models/messaging.ts +88 -0
- package/src/models/thread.ts +69 -0
- package/src/repositories/session.repository.ts +20 -0
- package/src/services/auth.service.ts +55 -0
- package/src/services/e2ee.service.ts +174 -0
- package/src/services/facebook-gateway.service.ts +245 -0
- package/src/services/icdc.service.ts +177 -0
- package/src/services/media.service.ts +304 -0
- package/src/services/messaging.service.ts +28 -0
- package/src/services/thread.service.ts +199 -0
- package/src/types/advanced-types.ts +61 -0
- package/src/types/fca-unofficial.d.ts +212 -0
- package/src/types/protocol-types.ts +43 -0
- package/src/utils/fca-utils.ts +30 -0
- package/src/utils/logger.ts +24 -0
- package/src/utils/mime.ts +51 -0
- package/tests/.env.example +87 -0
- package/tests/data/1x1.png +0 -0
- package/tests/data/example.txt +1 -0
- package/tests/data/file_example.mp3 +0 -0
- package/tests/data/file_example.mp4 +0 -0
- package/tests/integration.test.ts +498 -0
- package/tests/script/echo-e2ee.ts +174 -0
- package/tests/script/send-e2ee-media.ts +227 -0
- package/tests/script/send-e2ee-reaction.ts +108 -0
- package/tests/script/send-e2ee-unsend.ts +115 -0
- package/tests/script/send-typing.ts +107 -0
- package/tests/script/test-group-send.ts +105 -0
- package/tests/setup.ts +3 -0
- package/tests/types.test.ts +57 -0
- package/tests/unit/controllers/dgw-handler.test.ts +60 -0
- package/tests/unit/controllers/e2ee-handler.test.ts +293 -0
- package/tests/unit/controllers/event-mapper.test.ts +252 -0
- package/tests/unit/e2ee/application-helpers.test.ts +418 -0
- package/tests/unit/e2ee/device-store.test.ts +126 -0
- package/tests/unit/e2ee/facebook-protocol-utils.test.ts +134 -0
- package/tests/unit/e2ee/media-crypto.test.ts +55 -0
- package/tests/unit/e2ee/media-upload.test.ts +60 -0
- package/tests/unit/e2ee/message-builder.test.ts +42 -0
- package/tests/unit/e2ee/message-builders.test.ts +230 -0
- package/tests/unit/e2ee/noise-handshake.test.ts +260 -0
- package/tests/unit/e2ee/prekey-manager.test.ts +55 -0
- package/tests/unit/e2ee/wa-binary.test.ts +127 -0
- package/tests/unit/services/e2ee.service.test.ts +101 -0
- package/tests/unit/services/facebook-gateway.service.test.ts +138 -0
- package/tests/unit/services/media.service.test.ts +169 -0
- package/tests/unit/utils/fca-utils.test.ts +48 -0
- package/tsconfig.json +19 -0
package/README.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# FME - FB Messenger E2EE
|
|
2
|
+
|
|
3
|
+
[](https://www.typescriptlang.org/)
|
|
4
|
+
[](https://bun.sh/)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
**FME - FB Messenger E2EE** is a TypeScript/Bun toolkit focused on Facebook Messenger E2EE flows built on Noise, WA-binary, protobuf, and the Signal Protocol. Plaintext/non-E2EE messaging is intentionally left to `fca-unofficial` directly.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Key Features
|
|
12
|
+
|
|
13
|
+
- **Native E2EE path**: Signal Protocol sessions, prekeys, sender keys, Noise socket frames, and WA-binary nodes for encrypted Messenger chats.
|
|
14
|
+
- **Group sender-key support**: group `skmsg` decrypt/encrypt plus participant fanout of sender-key distribution messages (`skdm`).
|
|
15
|
+
- **Device persistence**: JSON-backed `DeviceStore` keeps Noise keys, Signal identity, sessions, prekeys, signed prekeys, and sender keys across restarts.
|
|
16
|
+
- **Automatic prekey maintenance**: replenishes server-side one-time prekeys without deleting or re-registering the E2EE device.
|
|
17
|
+
- **Typed E2EE events**: catch-all and typed event subscriptions for E2EE messages, receipts, reactions, errors, and raw frames.
|
|
18
|
+
- **DGW support**: optional Direct Gateway / LightSpeed socket helpers.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Tech Stack
|
|
23
|
+
|
|
24
|
+
- **Runtime**: [Bun](https://bun.sh/) / Node-compatible APIs
|
|
25
|
+
- **Language**: [TypeScript](https://www.typescriptlang.org/)
|
|
26
|
+
- **Encryption**: [@signalapp/libsignal-client](https://github.com/signalapp/libsignal-client)
|
|
27
|
+
- **Protocol**: ProtobufJS + manual WA-binary/protobuf encoders
|
|
28
|
+
- **Auth bootstrap bridge**: [fca-unofficial](https://github.com/VangBanLaNhat/fca-unofficial) is used internally only for appState login/CAT bootstrap; use it directly for non-E2EE messaging.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Getting Started
|
|
33
|
+
|
|
34
|
+
### 1. Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install fb-messenger-e2ee
|
|
38
|
+
# or
|
|
39
|
+
bun add fb-messenger-e2ee
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 2. Basic Usage
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { FBClient } from "fb-messenger-e2ee";
|
|
46
|
+
|
|
47
|
+
const client = new FBClient({
|
|
48
|
+
appStatePath: "./appstate.json",
|
|
49
|
+
sessionStorePath: "./session.json",
|
|
50
|
+
platform: "facebook",
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const { userId } = await client.connect();
|
|
54
|
+
|
|
55
|
+
// Keep this file. It is the registered E2EE device identity and Signal state.
|
|
56
|
+
await client.connectE2EE("./device-store.json", userId);
|
|
57
|
+
|
|
58
|
+
client.onEvent((event) => {
|
|
59
|
+
if (event.type === "e2ee_connected") {
|
|
60
|
+
console.log("E2EE stream is ready");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (event.type === "e2ee_message") {
|
|
64
|
+
console.log(`[E2EE] ${event.data.threadId} ${event.data.senderJid}: ${event.data.text}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (event.type === "error") {
|
|
68
|
+
console.error("Client error:", event.data.message);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
await client.sendMessage({
|
|
73
|
+
threadId: "1234567890", // user ID, *.@msgr JID, or group JID
|
|
74
|
+
text: "Hello from the secure side!",
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Device Store & Key Maintenance
|
|
81
|
+
|
|
82
|
+
`connectE2EE(deviceStorePath, userId)` loads or creates a persistent device store. Do **not** delete it as a normal recovery step:
|
|
83
|
+
|
|
84
|
+
- Deleting it generates a new Noise key, Signal identity, registration ID, `facebook_uuid`, and device registration.
|
|
85
|
+
- Keeping it lets the same registered E2EE device continue using existing sessions and sender keys.
|
|
86
|
+
- The client now refreshes one-time prekeys automatically and does not need a new device registration for normal prekey exhaustion.
|
|
87
|
+
|
|
88
|
+
Configurable environment variables:
|
|
89
|
+
|
|
90
|
+
| Env | Default | Purpose |
|
|
91
|
+
|---|---:|---|
|
|
92
|
+
| `FB_E2EE_PREKEY_SYNC_INTERVAL_MS` | `1800000` | Periodic prekey check interval. Set `0` to disable. |
|
|
93
|
+
| `FB_E2EE_PREKEY_MIN_COUNT` | `5` | Upload more prekeys when server count falls below this. |
|
|
94
|
+
| `FB_E2EE_PREKEY_UPLOAD_COUNT` | `50` | Number of fresh one-time prekeys to upload per refill. |
|
|
95
|
+
|
|
96
|
+
Group decrypt note: if local `sender_keys` for a group/sender are truly missing, the client cannot derive that key locally. On retryable decrypt failures it sends an E2EE retry receipt to request a resend/SKDM from the sender/server. The send path also keeps a short in-memory retry cache so incoming `receipt type="retry"` requests for recently-sent messages can be re-encrypted directly to the requesting device. This is different from prekey exhaustion.
|
|
97
|
+
|
|
98
|
+
E2EE event identity model:
|
|
99
|
+
|
|
100
|
+
- `threadId`: stable conversation ID. For DMs this is the bare Facebook user ID; for groups it is the group JID.
|
|
101
|
+
- `chatJid`: canonical E2EE chat JID. For DMs this is `user.0@msgr`; for groups it is `group@g.us`.
|
|
102
|
+
- `senderJid`: device-specific sender JID such as `user.160@msgr`.
|
|
103
|
+
- `senderDeviceId`: numeric Messenger E2EE device ID when available.
|
|
104
|
+
- `kind`: normalized content kind (`text`, `image`, `reaction`, `edit`, etc.). Empty optional fields are omitted from the event payload.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Project Structure
|
|
109
|
+
|
|
110
|
+
```text
|
|
111
|
+
src/
|
|
112
|
+
├── controllers/ # Thin orchestration + receive handlers
|
|
113
|
+
├── core/ # Public FBClient facade
|
|
114
|
+
├── e2ee/
|
|
115
|
+
│ ├── application/ # E2EEClient, retry/prekey/cache/fanout runtime helpers
|
|
116
|
+
│ ├── store/ # DeviceStore + JSON migration/repository
|
|
117
|
+
│ ├── transport/ # Noise, WA-binary, DGW sockets
|
|
118
|
+
│ ├── signal/ # Signal sessions, prekeys, sender keys
|
|
119
|
+
│ ├── message/ # Protobuf writer/builders/codecs/schemas
|
|
120
|
+
│ ├── media/ # Media crypto/upload
|
|
121
|
+
│ └── facebook/ # FB-specific SKMSG/SKDM/ICDC helpers
|
|
122
|
+
├── models/ # TypeScript interfaces & domain models
|
|
123
|
+
├── services/ # Auth/CAT bridge, ICDC, E2EE facade, media helpers
|
|
124
|
+
├── repositories/ # Session persistence
|
|
125
|
+
└── utils/ # Logger and conversion helpers
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Testing
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npm run typecheck
|
|
134
|
+
npm test -- --runInBand
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Manual echo script:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
bun run tests/script/echo-e2ee.ts
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Documentation
|
|
146
|
+
|
|
147
|
+
For the API reference and operational notes, see [DOCS.md](./DOCS.md).
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## License
|
|
152
|
+
|
|
153
|
+
MIT © [VangBanLaNhat](https://github.com/VangBanLaNhat)
|