@automerge/automerge-repo-network-websocket 2.0.0-alpha.2 → 2.0.0-alpha.20
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/README.md
CHANGED
|
@@ -27,12 +27,12 @@ Handshake is the following steps:
|
|
|
27
27
|
|
|
28
28
|
- Once a connection is established the initiating peer sends a
|
|
29
29
|
[join](#join) message with the `senderId` set to the initiating peers ID and
|
|
30
|
-
|
|
30
|
+
a `supportedProtocolVersions` array containing "1"
|
|
31
31
|
- The receiving peer waits until it receives a message from the initiating
|
|
32
32
|
peer, if the initiating peer receives a message before sending the join message
|
|
33
33
|
the initiating peer SHOULD terminate the connection.
|
|
34
34
|
- When the receiving peer receives the join message
|
|
35
|
-
- if the `
|
|
35
|
+
- if the `supportedProtocolVersions` does not contain "1" the receiving peer sends an
|
|
36
36
|
[error](#error) message and terminates the connection
|
|
37
37
|
- otherwise
|
|
38
38
|
- store the `senderId` as the peer ID of the initiating peer
|
|
@@ -119,7 +119,7 @@ Sent by the initiating peer in the [handshake](#handshake) phase.
|
|
|
119
119
|
{
|
|
120
120
|
type: "join",
|
|
121
121
|
senderId: peer_id,
|
|
122
|
-
supportedProtocolVersions: protocol_version
|
|
122
|
+
supportedProtocolVersions: [protocol_version]
|
|
123
123
|
? metadata: peer_metadata,
|
|
124
124
|
}
|
|
125
125
|
```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeWSServerAdapter.d.ts","sourceRoot":"","sources":["../src/NodeWSServerAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,eAAe,CAAA;AACrC,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAKpD,OAAO,EAEL,cAAc,EACd,KAAK,YAAY,EACjB,KAAK,MAAM,EACZ,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAEL,iBAAiB,EAElB,MAAM,eAAe,CAAA;AAOtB,qBAAa,mBAAoB,SAAQ,cAAc;;IAyBnD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,iBAAiB;IAzB3B,OAAO,EAAE;QAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAK;IAQ7C,OAAO;IAIP,SAAS;gBAYC,MAAM,EAAE,eAAe,EACvB,iBAAiB,SAAO;IAKlC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,YAAY;IAyCnD,UAAU;IAQV,IAAI,CAAC,OAAO,EAAE,iBAAiB;IAqB/B,cAAc,CAAC,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS;
|
|
1
|
+
{"version":3,"file":"NodeWSServerAdapter.d.ts","sourceRoot":"","sources":["../src/NodeWSServerAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,eAAe,CAAA;AACrC,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAKpD,OAAO,EAEL,cAAc,EACd,KAAK,YAAY,EACjB,KAAK,MAAM,EACZ,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAEL,iBAAiB,EAElB,MAAM,eAAe,CAAA;AAOtB,qBAAa,mBAAoB,SAAQ,cAAc;;IAyBnD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,iBAAiB;IAzB3B,OAAO,EAAE;QAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAK;IAQ7C,OAAO;IAIP,SAAS;gBAYC,MAAM,EAAE,eAAe,EACvB,iBAAiB,SAAO;IAKlC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,YAAY;IAyCnD,UAAU;IAQV,IAAI,CAAC,OAAO,EAAE,iBAAiB;IAqB/B,cAAc,CAAC,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS;CA2E3D"}
|
|
@@ -89,7 +89,15 @@ export class NodeWSServerAdapter extends NetworkAdapter {
|
|
|
89
89
|
socket.send(arrayBuf);
|
|
90
90
|
}
|
|
91
91
|
receiveMessage(messageBytes, socket) {
|
|
92
|
-
|
|
92
|
+
let message;
|
|
93
|
+
try {
|
|
94
|
+
message = decode(messageBytes);
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
log("invalid message received, closing connection");
|
|
98
|
+
socket.close();
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
93
101
|
const { type, senderId } = message;
|
|
94
102
|
const myPeerId = this.peerId;
|
|
95
103
|
assert(myPeerId);
|
package/dist/toArrayBuffer.d.ts
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* This incantation deals with websocket sending the whole underlying buffer even if we just have a
|
|
3
3
|
* uint8array view on it
|
|
4
4
|
*/
|
|
5
|
-
export declare const toArrayBuffer: (bytes: Uint8Array) => ArrayBuffer;
|
|
5
|
+
export declare const toArrayBuffer: (bytes: Uint8Array) => ArrayBuffer | SharedArrayBuffer;
|
|
6
6
|
//# sourceMappingURL=toArrayBuffer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toArrayBuffer.d.ts","sourceRoot":"","sources":["../src/toArrayBuffer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,aAAa,UAAW,UAAU,
|
|
1
|
+
{"version":3,"file":"toArrayBuffer.d.ts","sourceRoot":"","sources":["../src/toArrayBuffer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,aAAa,UAAW,UAAU,oCAG9C,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automerge/automerge-repo-network-websocket",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.20",
|
|
4
4
|
"description": "isomorphic node/browser Websocket network adapter for Automerge Repo",
|
|
5
5
|
"repository": "https://github.com/automerge/automerge-repo/tree/master/packages/automerge-repo-network-websocket",
|
|
6
6
|
"author": "Peter van Hardenberg <pvh@pvh.ca>",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"test": "vitest"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@automerge/automerge-repo": "2.0.0-alpha.
|
|
16
|
+
"@automerge/automerge-repo": "2.0.0-alpha.20",
|
|
17
17
|
"cbor-x": "^1.3.0",
|
|
18
18
|
"debug": "^4.3.4",
|
|
19
19
|
"eventemitter3": "^5.0.1",
|
|
@@ -31,5 +31,5 @@
|
|
|
31
31
|
"publishConfig": {
|
|
32
32
|
"access": "public"
|
|
33
33
|
},
|
|
34
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "d53bc37be0fd923ff40f3cf7e2bd06a0496ddb73"
|
|
35
35
|
}
|
|
@@ -123,7 +123,14 @@ export class NodeWSServerAdapter extends NetworkAdapter {
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
receiveMessage(messageBytes: Uint8Array, socket: WebSocket) {
|
|
126
|
-
|
|
126
|
+
let message: FromClientMessage
|
|
127
|
+
try {
|
|
128
|
+
message = decode(messageBytes)
|
|
129
|
+
} catch (e) {
|
|
130
|
+
log("invalid message received, closing connection")
|
|
131
|
+
socket.close()
|
|
132
|
+
return
|
|
133
|
+
}
|
|
127
134
|
|
|
128
135
|
const { type, senderId } = message
|
|
129
136
|
|
package/test/Websocket.test.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { next as A } from "@automerge/automerge"
|
|
2
2
|
import {
|
|
3
3
|
AutomergeUrl,
|
|
4
|
+
DocHandle,
|
|
4
5
|
DocumentId,
|
|
5
6
|
PeerId,
|
|
6
7
|
Repo,
|
|
@@ -21,6 +22,7 @@ import { describe, it } from "vitest"
|
|
|
21
22
|
import WebSocket from "ws"
|
|
22
23
|
import { BrowserWebSocketClientAdapter } from "../src/BrowserWebSocketClientAdapter.js"
|
|
23
24
|
import { NodeWSServerAdapter } from "../src/NodeWSServerAdapter.js"
|
|
25
|
+
import { encodeHeads } from "../../automerge-repo/dist/AutomergeUrl.js"
|
|
24
26
|
|
|
25
27
|
describe("Websocket adapters", () => {
|
|
26
28
|
const browserPeerId = "browser" as PeerId
|
|
@@ -338,6 +340,43 @@ describe("Websocket adapters", () => {
|
|
|
338
340
|
await eventPromise(serverAdapter, "peer-disconnected")
|
|
339
341
|
})
|
|
340
342
|
|
|
343
|
+
it("should disconnect from a client that sends an invalid CBOR message", async () => {
|
|
344
|
+
// Set up a server and wait for it to be ready
|
|
345
|
+
const port = await getPort()
|
|
346
|
+
const serverUrl = `ws://localhost:${port}`
|
|
347
|
+
const server = http.createServer()
|
|
348
|
+
const serverSocket = new WebSocket.Server({ server })
|
|
349
|
+
await new Promise<void>(resolve => server.listen(port, resolve))
|
|
350
|
+
|
|
351
|
+
// Create a repo listening on the socket
|
|
352
|
+
const serverAdapter = new NodeWSServerAdapter(serverSocket)
|
|
353
|
+
const serverRepo = new Repo({
|
|
354
|
+
network: [serverAdapter],
|
|
355
|
+
peerId: serverPeerId,
|
|
356
|
+
})
|
|
357
|
+
|
|
358
|
+
// Create a new socket connected to the repo
|
|
359
|
+
const browserSocket = new WebSocket(serverUrl)
|
|
360
|
+
await new Promise(resolve => browserSocket.on("open", resolve))
|
|
361
|
+
const disconnected = new Promise(resolve =>
|
|
362
|
+
browserSocket.on("close", resolve)
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
// Send an invalid CBOR message, in this case we use a definite length
|
|
366
|
+
// array with too many elements. This test should actually work for any
|
|
367
|
+
// invalid message but this reproduces a specific issue we were seeing on
|
|
368
|
+
// the sycn server
|
|
369
|
+
//
|
|
370
|
+
// 0x9 (1001) is major type 4, for an array
|
|
371
|
+
// 0xB (1011) indicates that the length will be encoded in the next 8 bytes
|
|
372
|
+
// 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 is 2**32, which is longer than allowed
|
|
373
|
+
const invalidLargeArray = new Uint8Array([
|
|
374
|
+
0x9b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
|
375
|
+
])
|
|
376
|
+
browserSocket.send(invalidLargeArray)
|
|
377
|
+
await disconnected
|
|
378
|
+
})
|
|
379
|
+
|
|
341
380
|
it("should send the negotiated protocol version in its hello message", async () => {
|
|
342
381
|
const response = await serverResponse({
|
|
343
382
|
type: "join",
|
|
@@ -582,9 +621,10 @@ describe("Websocket adapters", () => {
|
|
|
582
621
|
await pause(50)
|
|
583
622
|
}
|
|
584
623
|
|
|
624
|
+
// we encode localHeads for consistency with URL formatted heads
|
|
585
625
|
let localHeads = A.getHeads(clientDoc)
|
|
586
626
|
let remoteHeads = handle.heads()
|
|
587
|
-
if (!headsAreSame(localHeads, remoteHeads)) {
|
|
627
|
+
if (!headsAreSame(encodeHeads(localHeads), remoteHeads)) {
|
|
588
628
|
throw new Error("heads not equal")
|
|
589
629
|
}
|
|
590
630
|
})
|