pairnet 0.1.0 → 0.1.1

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.
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+
3
+ module.exports = require("@joepie91/eslint-config");
package/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  const crypto = require("crypto");
4
4
  const tls = require("tls");
5
- const debug = require("debug")("pairnet");
5
+ const makeDebug = require("debug-instanced")("pairnet");
6
6
  const matchValue = require("match-value");
7
7
  const pipe = require("@promistream/pipe");
8
8
  const simpleSink = require("@promistream/simple-sink");
@@ -40,7 +40,7 @@ function createQueryError(message) {
40
40
  return error;
41
41
  }
42
42
 
43
- async function makeClientSocket({ hostname, port, options, onQuery, protocolConfiguration }) {
43
+ async function makeClientSocket({ hostname, port, options, onQuery, protocolConfiguration, debug }) {
44
44
  let socket = tls.connect({
45
45
  host: hostname,
46
46
  port: port,
@@ -53,7 +53,9 @@ async function makeClientSocket({ hostname, port, options, onQuery, protocolConf
53
53
  });
54
54
 
55
55
  let api = await handleProtocol(socket, {
56
+ debug,
56
57
  protocolConfiguration: protocolConfiguration,
58
+ role: "client",
57
59
  onQuery: onQuery
58
60
  });
59
61
 
@@ -77,6 +79,8 @@ module.exports = {
77
79
  createMemoryStorage: createMemoryStorage,
78
80
  createFileStorage: createFileStorage,
79
81
  createPeer: async function createPeer(_options) {
82
+ let debug = makeDebug("peer");
83
+
80
84
  let { storage, generateClientHello, onClientHello, onServerHello } = validateOptions(arguments, {
81
85
  storage: [ required, isStorageProvider ],
82
86
  generateClientHello: [ required, isFunction ],
@@ -148,7 +152,7 @@ module.exports = {
148
152
  debug(`[pair] Initiating pairing connection to ${hostname}:${port}...`);
149
153
 
150
154
  let socket = await makeClientSocket({
151
- hostname, port, protocolConfiguration,
155
+ debug, hostname, port, protocolConfiguration,
152
156
  // We don't care about anything other than pairing messages in this mode, which are in the form of a query reply
153
157
  onQuery: () => {}
154
158
  });
@@ -201,7 +205,7 @@ module.exports = {
201
205
 
202
206
  // connect with client certificate made from own identity, and validate server pubkey
203
207
  let socket = await makeClientSocket({
204
- hostname, port, protocolConfiguration,
208
+ debug, hostname, port, protocolConfiguration,
205
209
  onQuery: onQuery
206
210
  });
207
211
 
@@ -252,7 +256,9 @@ module.exports = {
252
256
  debug(`[server] Is trusted: ${isPaired}`);
253
257
 
254
258
  let api = await handleProtocol(socket, {
259
+ debug,
255
260
  protocolConfiguration,
261
+ role: "server",
256
262
  onQuery: async (query) => {
257
263
  return matchValue(query.type, {
258
264
  PAIR: async () => {
package/lib/protocol.js CHANGED
@@ -5,16 +5,13 @@ const decodeCBOR = require("@promistream/decode-cbor");
5
5
  const pipe = require("@promistream/pipe");
6
6
  const fromNodeStream = require("@promistream/from-node-stream");
7
7
  const map = require("@promistream/map");
8
- const infiniteQueue = require("../streams/infinite-queue");
8
+ const simpleQueue = require("@promistream/simple-queue");
9
9
  const simpleSink = require("@promistream/simple-sink");
10
10
  const createDebugStream = require("@promistream/debug");
11
11
  const objid = require("@joepie91/objid");
12
12
 
13
- const debug = require("debug")("pairnet:protocol");
14
-
15
13
  const createSender = require("./sender");
16
14
  const createReplyTracker = require("./reply-tracker");
17
- const disconnectSocket = require("../promisified/disconnect-socket");
18
15
  const filter = require("@promistream/filter");
19
16
 
20
17
  let NORMAL_QUERY_TYPE = "q";
@@ -45,10 +42,10 @@ async function evaluateQuery(query, handler) {
45
42
  }
46
43
  }
47
44
 
48
- module.exports = async function handleProtocol(socket, { onQuery, protocolConfiguration } = {}) {
49
- debug("Attaching semantic protocol handler");
45
+ module.exports = async function handleProtocol(socket, { debug, onQuery, protocolConfiguration, role } = {}) {
46
+ debug(`Attaching semantic protocol handler (role = ${role})`);
50
47
 
51
- let writeQueue = infiniteQueue([]);
48
+ let writeQueue = simpleQueue([], { autoEnd: false });
52
49
  let replyTracker = createReplyTracker();
53
50
  let negotiationCompleted = false;
54
51
 
@@ -85,15 +82,16 @@ module.exports = async function handleProtocol(socket, { onQuery, protocolConfig
85
82
  // createDebugStream(`pairnet:protocol:receive-pipeline ${objid(socket)}`),
86
83
  ]);
87
84
 
88
- let clientHelloQuery = (protocolConfiguration.isClient)
85
+ let clientHelloQuery = (role === "client")
89
86
  ? sender.sendNegotiationQuery(await protocolConfiguration.generateClientHello())._queryID.toString("hex") // FIXME: Hacky
90
87
  : null;
91
88
 
92
89
  // We read messages for as long as negotiation has not been completed yet
90
+ // TODO[security]: verify that we don't allow server/client confusion anywhere
93
91
  await pipe([
94
92
  incomingMessageStream,
95
93
  simpleSink(async (message) => {
96
- debug("Received message:", message);
94
+ debug("Received message (negotiation phase):", message);
97
95
 
98
96
  let isNegotiationMessage = NEGOTIATION_TYPES.has(message.t);
99
97
  let isReplyMessage = REPLY_TYPES.has(message.t);
@@ -107,7 +105,7 @@ module.exports = async function handleProtocol(socket, { onQuery, protocolConfig
107
105
 
108
106
  if (helloDecision === false) {
109
107
  // Connection rejected
110
- return disconnectSocket(socket);
108
+ return writeQueue.end();
111
109
  } else {
112
110
  debug(`[readLoop] Negotiation completed on client side; detaching sink...`);
113
111
  return null;
@@ -140,6 +138,8 @@ module.exports = async function handleProtocol(socket, { onQuery, protocolConfig
140
138
  let eventStream = pipe([
141
139
  incomingMessageStream,
142
140
  filter(async (message) => {
141
+ debug("Received message (operating phase):", message);
142
+
143
143
  let isReplyMessage = REPLY_TYPES.has(message.t);
144
144
 
145
145
  if (message.t === NORMAL_QUERY_TYPE) {
@@ -186,6 +186,6 @@ module.exports = async function handleProtocol(socket, { onQuery, protocolConfig
186
186
  return {
187
187
  eventStream: eventStream,
188
188
  sender: sender,
189
- disconnect: () => disconnectSocket(socket)
189
+ disconnect: () => writeQueue.end()
190
190
  };
191
191
  };
package/package.json CHANGED
@@ -1,47 +1,41 @@
1
1
  {
2
2
  "name": "pairnet",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "",
5
5
  "main": "index.js",
6
+ "scripts": {
7
+ "test": "node --test"
8
+ },
6
9
  "keywords": [],
7
10
  "author": "Sven Slootweg <admin@cryto.net>",
8
11
  "license": "WTFPL",
9
12
  "dependencies": {
10
- "@joepie91/consumable": "^1.0.1",
11
13
  "@joepie91/objid": "^1.0.1",
12
- "@promistream/aborted": "^0.1.2",
13
14
  "@promistream/decode-cbor": "^0.1.0",
14
15
  "@promistream/encode-cbor": "^0.1.0",
15
- "@promistream/filter": "^0.1.1",
16
- "@promistream/from-node-stream": "^0.1.3",
17
- "@promistream/map": "^0.1.1",
18
- "@promistream/pipe": "^0.1.6",
19
- "@promistream/simple-sink": "^0.3.0",
20
- "@promistream/simple-source": "^0.1.4",
21
- "@validatem/core": "^0.5.0",
16
+ "@promistream/filter": "^0.1.3",
17
+ "@promistream/from-node-stream": "^0.1.6",
18
+ "@promistream/map": "^0.1.10",
19
+ "@promistream/pipe": "^0.1.8",
20
+ "@promistream/simple-queue": "^0.1.7",
21
+ "@promistream/simple-sink": "^0.3.5",
22
+ "@validatem/core": "^0.6.3",
22
23
  "@validatem/error": "^1.1.0",
23
24
  "@validatem/is-function": "^0.1.0",
24
25
  "@validatem/is-integer": "^0.1.0",
25
26
  "@validatem/is-non-empty-string": "^0.1.0",
26
- "@validatem/is-positive": "^1.0.0",
27
27
  "@validatem/required": "^0.1.1",
28
- "cbor": "^9.0.2",
29
- "colorette": "^2.0.20",
30
- "debug": "^4.3.4",
28
+ "cbor": "^10.0.12",
29
+ "debug": "^4.4.3",
30
+ "debug-instanced": "^1.0.0",
31
31
  "match-value": "^1.1.0",
32
- "nanoid": "^3.3.7",
33
- "p-defer": "^3",
34
- "p-event": "^4",
35
- "range": "^0.0.3",
36
- "sanitize-filename": "^1.6.3"
32
+ "nanoid": "^3.3.18",
33
+ "p-defer": "^3.0.0",
34
+ "sanitize-filename": "^1.6.4"
37
35
  },
38
36
  "devDependencies": {
39
- "@joepie91/eslint-config": "^1.1.1",
40
- "@promistream/debug": "^0.1.0",
41
- "@promistream/from-iterable": "^0.1.0",
42
- "@promistream/spy": "^0.1.0"
43
- },
44
- "scripts": {
45
- "test": "node --test"
37
+ "@joepie91/eslint-config": "^2.0.3",
38
+ "@promistream/debug": "^0.1.2",
39
+ "eslint": "^10.8.1"
46
40
  }
47
- }
41
+ }
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
 
3
- const pEvent = require("p-event");
3
+ const { once } = require("node:events");
4
4
 
5
5
  module.exports = async function serverClose(server) {
6
6
  server.close();
7
- await pEvent(server, "close");
7
+ await once(server, "close");
8
8
  };
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
 
3
- const pEvent = require("p-event");
3
+ const { once } = require("node:events");
4
4
  const debug = require("debug")("pairnet:server-listen");
5
5
 
6
6
  module.exports = async function serverListen(server, port, hostname) {
7
7
  server.listen(port, hostname);
8
- await pEvent(server, "listening");
8
+ await once(server, "listening");
9
9
  debug(`[createServer] Listening on ${hostname}:${port}...`);
10
10
  };
package/.eslintrc DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "extends": "@joepie91/eslint-config"
3
- }
@@ -1,11 +0,0 @@
1
- "use strict";
2
-
3
- const debug = require("debug")("pairnet");
4
- const pEvent = require("p-event");
5
-
6
- module.exports = async function disconnect(socket) {
7
- debug(`[disconnectSocket] Disconnecting...`);
8
- socket.destroySoon();
9
- await pEvent(socket, "close");
10
- debug(`[disconnectSocket] Disconnected!`);
11
- };
@@ -1,37 +0,0 @@
1
- "use strict";
2
-
3
- const simpleSource = require("@promistream/simple-source");
4
- const Aborted = require("@promistream/aborted");
5
- const pDefer = require("p-defer");
6
-
7
- module.exports = function createInfiniteQueue(initialItems = []) {
8
- let queue = initialItems.slice();
9
- let defers = [];
10
-
11
- return {
12
- push: function (value) {
13
- if (defers.length > 0) {
14
- defers.shift().resolve(value);
15
- } else {
16
- queue.push(value);
17
- }
18
- },
19
- stream: simpleSource({
20
- onRequest: () => {
21
- if (queue.length > 0) {
22
- return queue.shift();
23
- } else {
24
- let defer = pDefer();
25
- defers.push(defer);
26
- return defer.promise;
27
- }
28
- },
29
- onAbort: (reason) => {
30
- for (let defer of defers) {
31
- // TODO: Test properly
32
- defer.reject(new Aborted("Stream was aborted"));
33
- }
34
- }
35
- })
36
- };
37
- };