@decentnetwork/peer 0.1.24 → 0.1.25
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/dist/compat/express.js +60 -50
- package/package.json +1 -1
package/dist/compat/express.js
CHANGED
|
@@ -51,59 +51,71 @@ export class LegacyExpressClient {
|
|
|
51
51
|
if (!this.#nodes.length) {
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (!plain) {
|
|
68
|
-
continue;
|
|
54
|
+
// Pull from EVERY configured relay, not just the first reachable one. A
|
|
55
|
+
// message lives only on the relay its sender posted it to; with a mixed
|
|
56
|
+
// fleet (some peers prefer relay A, others B — e.g. during a rollout that
|
|
57
|
+
// adds a dedicated relay) the recipient must check all relays or it
|
|
58
|
+
// silently misses anything posted elsewhere. Each relay re-encrypts with
|
|
59
|
+
// its own per-recipient key, so we decrypt/ack each one independently.
|
|
60
|
+
for (const node of this.#nodes) {
|
|
61
|
+
let body;
|
|
62
|
+
try {
|
|
63
|
+
body = await this.#http(node, "GET", encodeURIComponent(this.#selfUserId));
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
continue; // relay unreachable right now — try the next
|
|
69
67
|
}
|
|
70
|
-
const
|
|
71
|
-
if (
|
|
68
|
+
const messages = parseExpressResponseFrames(body);
|
|
69
|
+
if (messages.length === 0) {
|
|
72
70
|
continue;
|
|
73
71
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
this.#debugLog(`pullOnce got ${messages.length} offline frame(s) from ${node.host}:${node.port}`);
|
|
73
|
+
let lastTimestamp = 0;
|
|
74
|
+
let requestCount = 0;
|
|
75
|
+
let messageCount = 0;
|
|
76
|
+
for (const encrypted of messages) {
|
|
77
|
+
const plain = decrypt(node.sharedKey, encrypted);
|
|
78
|
+
if (!plain) {
|
|
78
79
|
continue;
|
|
79
80
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
const friendSharedKey = nacl.box.before(friendPk, this.#selfKeyPair.secretKey);
|
|
91
|
-
const packet = decrypt(friendSharedKey, msg.payload);
|
|
92
|
-
if (!packet) {
|
|
81
|
+
const msg = decodePullMessage(plain);
|
|
82
|
+
if (!msg) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
lastTimestamp = Math.max(lastTimestamp, msg.timestamp);
|
|
86
|
+
if (msg.type === "R") {
|
|
87
|
+
if (!msg.address || msg.address !== this.#selfAddress) {
|
|
88
|
+
this.#debugLog(`drop offline request with unmatched address from ${msg.from}`);
|
|
93
89
|
continue;
|
|
94
90
|
}
|
|
95
|
-
this.#callbacks.
|
|
96
|
-
|
|
97
|
-
this.#debugLog(`offline
|
|
91
|
+
this.#callbacks.onOfflineFriendRequest(msg.from, msg.payload, msg.timestamp);
|
|
92
|
+
requestCount += 1;
|
|
93
|
+
this.#debugLog(`offline friend request from ${msg.from} ts=${msg.timestamp}`);
|
|
98
94
|
}
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
else if (msg.type === "M") {
|
|
96
|
+
try {
|
|
97
|
+
const friendPk = base58ToBytes(msg.from);
|
|
98
|
+
if (friendPk.length !== 32) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const friendSharedKey = nacl.box.before(friendPk, this.#selfKeyPair.secretKey);
|
|
102
|
+
const packet = decrypt(friendSharedKey, msg.payload);
|
|
103
|
+
if (!packet) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
this.#callbacks.onOfflineFriendMessage(msg.from, packet, msg.timestamp);
|
|
107
|
+
messageCount += 1;
|
|
108
|
+
this.#debugLog(`offline message from ${msg.from} ts=${msg.timestamp}`);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Skip invalid sender ids.
|
|
112
|
+
}
|
|
101
113
|
}
|
|
102
114
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
115
|
+
if (lastTimestamp > 0) {
|
|
116
|
+
this.#debugLog(`pull processed from ${node.host}: requests=${requestCount} messages=${messageCount}; ack until ts=${lastTimestamp}`);
|
|
117
|
+
await this.#deleteUntilOn(node, lastTimestamp).catch(() => { });
|
|
118
|
+
}
|
|
107
119
|
}
|
|
108
120
|
}
|
|
109
121
|
async #postEncrypted(to, plainData) {
|
|
@@ -113,14 +125,12 @@ export class LegacyExpressClient {
|
|
|
113
125
|
await this.#http(node, "POST", path, encrypted);
|
|
114
126
|
});
|
|
115
127
|
}
|
|
116
|
-
async #
|
|
128
|
+
async #deleteUntilOn(node, timestamp) {
|
|
117
129
|
const tsBytes = new TextEncoder().encode(String(timestamp));
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
await this.#http(node, "DELETE", path);
|
|
123
|
-
});
|
|
130
|
+
const encrypted = encrypt(node.sharedKey, tsBytes);
|
|
131
|
+
const encoded = bytesToBase58(encrypted);
|
|
132
|
+
const path = `${encodeURIComponent(this.#selfUserId)}?until=${encodeURIComponent(encoded)}`;
|
|
133
|
+
await this.#http(node, "DELETE", path);
|
|
124
134
|
}
|
|
125
135
|
async #withAnyNode(fn) {
|
|
126
136
|
if (!this.#nodes.length) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentnetwork/peer",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.25",
|
|
4
4
|
"description": "Pure TypeScript port of Elastos Carrier (toxcore-derived) P2P messaging. DHT, onion routing, TCP relay, FlatBuffers app payloads, Express offline relay. Wire-compatible with iOS Beagle and the Carrier C SDK.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|