cryptpad-server 0.0.2 → 0.0.4

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.
@@ -1000,7 +1000,6 @@ function requireCore() {
1000
1000
  const Util = requireCommonUtil$1();
1001
1001
  const Constants = requireConstants();
1002
1002
  const escapeKeyCharacters = Util.escapeKeyCharacters;
1003
- __require$1();
1004
1003
  const Crypto = __require();
1005
1004
  const Keys = requireKeys();
1006
1005
  Core.DEFAULT_LIMIT = 50 * 1024 * 1024;
@@ -1120,8 +1119,7 @@ function requireCore() {
1120
1119
  cb();
1121
1120
  };
1122
1121
  Core.getPaths = (mainConfig, isEnv) => {
1123
- const {index, config} = mainConfig;
1124
- Constants.paths;
1122
+ const {config} = mainConfig;
1125
1123
  const all = {
1126
1124
  basePath: config.basePath || config.base || "./data",
1127
1125
  filePath: config.filePath || "./datastore",
@@ -2206,6 +2204,14 @@ function requireFile() {
2206
2204
  writeLinkedFile(env, path, content, cb);
2207
2205
  });
2208
2206
  };
2207
+ const hasLinkedDocuments = (env, channelId) => {
2208
+ const path = mkLinkedPath(env, channelId);
2209
+ try {
2210
+ return Fs.existsSync(path);
2211
+ } catch (e) {
2212
+ return false;
2213
+ }
2214
+ };
2209
2215
  const getLinkedDocuments = (env, channelId, cb) => {
2210
2216
  const path = mkLinkedPath(env, channelId);
2211
2217
  readLinkedFile(env, path, cb);
@@ -3278,6 +3284,7 @@ function requireFile() {
3278
3284
  writeMetadata(env, channelName, data, Util.both(cb, next));
3279
3285
  });
3280
3286
  },
3287
+ hasLinkedDocuments: channelId => hasLinkedDocuments(env, channelId),
3281
3288
  getLinkedDocuments: (channelId, cb) => {
3282
3289
  if (!isValidChannelId(channelId)) {
3283
3290
  return cb(new Error("EINVAL"));
@@ -4733,7 +4740,7 @@ function requireTasks() {
4733
4740
  return tasks.exports;
4734
4741
  }
4735
4742
 
4736
- var version = "0.0.2";
4743
+ var version = "0.0.4";
4737
4744
 
4738
4745
  var require$$2 = {
4739
4746
  version
@@ -5591,10 +5598,11 @@ function requirePinManager() {
5591
5598
  hasRequiredPinManager = 1;
5592
5599
  (function(module) {
5593
5600
  const Pins = module.exports;
5594
- __require$2();
5595
- __require$1();
5596
- requireCommonUtil$1();
5597
- requireFile();
5601
+ const Fs = __require$2();
5602
+ const Path = __require$1();
5603
+ const Util = requireCommonUtil$1();
5604
+ const Semaphore = require$$4;
5605
+ const nThen = require$$3;
5598
5606
  const createLineHandler = Pins.createLineHandler = (ref, errorHandler) => {
5599
5607
  let fileName;
5600
5608
  if (typeof errorHandler === "string") {
@@ -5714,8 +5722,72 @@ function requirePinManager() {
5714
5722
  const ref = processPinFile(pinFile, fileName);
5715
5723
  return Object.keys(ref.pins);
5716
5724
  };
5717
- Pins.load = (cb, config) => {
5718
- throw new Error("EVICTION NOT IMPLEMENTED");
5725
+ Pins.load = (Env, cb, config) => {
5726
+ const sema = Semaphore.create(config.workers || 5);
5727
+ let dirList;
5728
+ const fileList = [];
5729
+ const pinned = {};
5730
+ var done = Util.once(cb);
5731
+ var handler = config.handler;
5732
+ let store = Env.pinStore;
5733
+ let pinPath = Env.paths.pin;
5734
+ nThen(waitFor => {
5735
+ Fs.readdir(pinPath, waitFor((err, list) => {
5736
+ if (err) {
5737
+ if (err.code === "ENOENT") {
5738
+ dirList = [];
5739
+ return;
5740
+ }
5741
+ waitFor.abort();
5742
+ return void done(err);
5743
+ }
5744
+ dirList = list;
5745
+ }));
5746
+ }).nThen(waitFor => {
5747
+ dirList.forEach(f => {
5748
+ sema.take(returnAfter => {
5749
+ Fs.readdir(Path.join(pinPath, f), waitFor(returnAfter((err, list2) => {
5750
+ if (err) {
5751
+ waitFor.abort();
5752
+ return void done(err);
5753
+ }
5754
+ list2.forEach(ff => {
5755
+ if (config && config.exclude && config.exclude.indexOf(ff) > -1) {
5756
+ return;
5757
+ }
5758
+ fileList.push(ff.replace(/(\.ndjson)$/, ""));
5759
+ });
5760
+ })));
5761
+ });
5762
+ });
5763
+ }).nThen(waitFor => {
5764
+ fileList.forEach(id => {
5765
+ sema.take(returnAfter => {
5766
+ var next = waitFor(returnAfter());
5767
+ var ref = {};
5768
+ var h = createLineHandler(ref, id);
5769
+ store.readMessagesBin(id, 0, (msgObj, next) => {
5770
+ h(msgObj.buff.toString("utf8"));
5771
+ next();
5772
+ }, err => {
5773
+ if (err) {
5774
+ waitFor.abort();
5775
+ return void done(err);
5776
+ }
5777
+ if (handler) {
5778
+ return void handler(ref, id, next);
5779
+ }
5780
+ const hashes = Object.keys(ref.pins);
5781
+ hashes.forEach(x => {
5782
+ (pinned[x] = pinned[x] || {})[id] = 1;
5783
+ });
5784
+ next();
5785
+ });
5786
+ });
5787
+ });
5788
+ }).nThen(() => {
5789
+ done(void 0, pinned);
5790
+ });
5719
5791
  };
5720
5792
  })(pinManager);
5721
5793
  return pinManager.exports;
@@ -6521,6 +6593,10 @@ function requireWorker() {
6521
6593
  txid: obj.txid,
6522
6594
  pid: obj.pid,
6523
6595
  value
6596
+ }, e => {
6597
+ if (e) {
6598
+ console.error("E_RESPONSE", Util.serializeError(e));
6599
+ }
6524
6600
  });
6525
6601
  };
6526
6602
  if (!ready) {
@@ -6537,6 +6613,9 @@ function requireWorker() {
6537
6613
  }
6538
6614
  command(data, cb);
6539
6615
  });
6616
+ process.on("disconnect", () => {
6617
+ process.exit(0);
6618
+ });
6540
6619
  process.on("uncaughtException", function(err) {
6541
6620
  console.error("[%s] UNCAUGHT EXCEPTION IN DB WORKER", new Date);
6542
6621
  console.error(err);
package/index.js CHANGED
@@ -47,6 +47,14 @@ args.some(arg => {
47
47
  prev = '';
48
48
  });
49
49
 
50
+ // Clean quit: kill child processes
51
+ const childPids = [];
52
+
53
+ const cleanSubprocesses = () => childPids.forEach((pid) => process.kill(pid));
54
+
55
+ process.on('SIGTERM', cleanSubprocesses);
56
+ process.on('exit', cleanSubprocesses);
57
+
50
58
  const start = (serverConfig, infraConfig) => {
51
59
  const Log = {
52
60
  debug: console.debug,
@@ -57,9 +65,7 @@ const start = (serverConfig, infraConfig) => {
57
65
  };
58
66
 
59
67
  let serverId;
60
- const startNode = (type, index, forking, cb) => {
61
- if (typeof (cb) !== 'function') { cb = () => { }; };
62
-
68
+ const startNode = (type, index, forking) => new Promise((resolve, reject) => {
63
69
  const nodeFile = './build/' + type + '.js';
64
70
  const path = Path.join(__dirname, nodeFile);
65
71
  const initConfig = {
@@ -72,51 +78,49 @@ const start = (serverConfig, infraConfig) => {
72
78
  //Log.info(`Starting: ${initConfig.myId}`);
73
79
  if (forking) {
74
80
  let nodeProcess = fork(path);
81
+ childPids.push(nodeProcess.pid);
75
82
  nodeProcess.send(initConfig);
76
83
  nodeProcess.on('message', (message) => {
77
84
  if (message.msg === 'READY') {
78
- Log.info(`Started: ${type}:${message.index}`);
85
+ // Log.info(`Started: ${type}:${message.index}`);
79
86
  if (message.dev) {
80
87
  Log.info('DEV mode enabled');
81
88
  }
82
- cb();
89
+ resolve();
83
90
  }
84
91
  });
85
- // FIXME
86
92
  nodeProcess.on('error', (err) => {
87
93
  Log.error('Child process stopped due to error.');
88
94
  Log.error(err);
95
+ reject(`${type}:${index}: error ${err}`);
89
96
  process.exit(1);
90
97
  });
91
98
  nodeProcess.on('exit', (err) => {
92
99
  Log.error('Child process stopped due to error.');
93
100
  Log.error(err);
94
- process.exit(1);
101
+ reject(`${type}:${index}: exit(${err})`);
102
+ process.exit(err);
95
103
  });
96
104
  } else {
105
+ // Single process start
106
+ // Can only be called from CLI and not from external module
97
107
  require(path).start(initConfig);
98
108
  }
99
- };
109
+ });
100
110
 
101
111
  const coresReady = () => {
102
112
  const promises = [];
103
113
  infraConfig?.front?.forEach((data, index) => {
104
- promises.push(new Promise(resolve => {
105
- if (serverId && data.serverId !== serverId) { return resolve(); }
106
- startNode('front', index, true, resolve);
107
- }));
114
+ if (serverId && data.serverId !== serverId) { return; }
115
+ promises.push(startNode('front', index, true));
108
116
  });
109
117
  infraConfig?.storage?.forEach((data, index) => {
110
- promises.push(new Promise(resolve => {
111
- if (serverId && data.serverId !== serverId) { return resolve(); }
112
- startNode('storage', index, true, resolve);
113
- }));
118
+ if (serverId && data.serverId !== serverId) { return; }
119
+ promises.push(startNode('storage', index, true));
114
120
  });
115
- promises.push(new Promise(resolve => {
116
- if (serverId && infraConfig?.public?.httpServerId !== serverId) { return resolve(); }
117
- startNode('http', 0, true, resolve);
118
- }));
119
- Promise.all(promises).then(() => {
121
+ if (serverId && infraConfig?.public?.httpServerId !== serverId) { return; }
122
+ promises.push(startNode('http', 0, true));
123
+ return Promise.all(promises.filter(Boolean)).then(() => {
120
124
  Log.info('CryptPad server ready');
121
125
  });
122
126
  };
@@ -128,21 +132,14 @@ const start = (serverConfig, infraConfig) => {
128
132
  }
129
133
  serverConfig.private.nodes_key = Crypto.randomBytes(32).toString('base64');
130
134
  }
131
- const corePromises = infraConfig?.core.map((data, index) => new Promise((resolve, reject) => {
135
+ const corePromises = infraConfig?.core.map((data, index) => {
132
136
  // hosted on another machine?
133
- if (serverId && data.serverId !== serverId) { return resolve(); }
134
- startNode('core', index, true, (err) => {
135
- if (err) {
136
- Log.error('START_CORE_ERROR', err);
137
- return reject(err);
138
- }
139
- return resolve();
140
- });
141
- }));
137
+ if (serverId && data.serverId !== serverId) { return; }
138
+ return startNode('core', index, true);
139
+ });
142
140
 
143
- Promise.all(corePromises)
144
- .then(() => { coresReady(); })
145
- .catch((e) => { return Log.error('START_CORE_ERROR', e); });
141
+ return Promise.all(corePromises.filter(Boolean))
142
+ .then(() => coresReady());
146
143
  };
147
144
 
148
145
 
@@ -153,18 +150,18 @@ const start = (serverConfig, infraConfig) => {
153
150
  if (!serverConfig?.private?.nodes_key) {
154
151
  throw Error('E_MISSINGKEY');
155
152
  }
156
- startNode(type, index, false, (err) => {
153
+ return startNode(type, index, false).catch((err) => {
157
154
  if (err) { return Log.error('START_NODE_ERROR', err); }
158
155
  });
159
156
  } else {
160
157
  serverId = cliArgs.server;
161
- startCores();
158
+ return startCores();
162
159
  }
163
160
  };
164
161
 
165
162
  if (require.main === module) {
166
- const { config, infra } = require('./common/load-config');
167
- start(config, infra);
163
+ const { config, infra } = require('./common/load-config')();
164
+ start(config, infra).catch((e) => { console.error('CryptPad server start failed:', e); });
168
165
  } else {
169
166
  module.exports = { start };
170
167
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cryptpad-server",
3
3
  "description": "CryptPad Server",
4
- "version": "0.0.2",
4
+ "version": "0.0.4",
5
5
  "license": "AGPL-3.0+",
6
6
  "repository": {
7
7
  "type": "git",
@@ -16,12 +16,13 @@
16
16
  "build"
17
17
  ],
18
18
  "dependencies": {
19
- "body-parser": "^2.2.0",
19
+ "@mcrowe/minibloom": "^0.2.0",
20
20
  "connect-gzip-static": "^4.2.1",
21
21
  "cookie-parser": "^1.4.7",
22
- "express": "~4.22.1",
22
+ "express": "~5.2.1",
23
23
  "fs-extra": "^7.0.0",
24
24
  "http-proxy-middleware": "^3.0.3",
25
+ "mime-types": "^3.0.2",
25
26
  "nthen": "0.1.8",
26
27
  "otpauth": "^9.4.1",
27
28
  "pull-stream": "^3.6.1",
@@ -50,6 +51,7 @@
50
51
  "typescript": "^5.6.2"
51
52
  },
52
53
  "overrides": {
54
+ "qs": "^6.16.0",
53
55
  "http-proxy": "npm:http-proxy-3@^1.23.2",
54
56
  "serialize-javascript": "^7.0.4"
55
57
  },
@@ -60,9 +62,11 @@
60
62
  "build:core": "TYPE=core rollup -c",
61
63
  "build:storage": "TYPE=storage rollup -c",
62
64
  "build:http": "TYPE=http rollup -c",
65
+ "build:eviction": "TYPE=eviction rollup -c",
63
66
  "tests": "node --test tests/",
64
67
  "test": "node tests/runAll.js",
65
68
  "start": "node index.js",
66
- "dev": "DEV=1 node index.js"
69
+ "dev": "DEV=1 node index.js",
70
+ "windev": "set DEV=1& node index.js"
67
71
  }
68
72
  }
package/readme.md CHANGED
@@ -90,12 +90,8 @@ node index.js --server [serverId value]
90
90
  The directory [`tests`](tests/) contains some unit and integration tests scripts
91
91
  and files.
92
92
 
93
- - [`interface.test.js`](tests/interface.test.js): test the communication
94
- interface by implementing a simple ping-pong protocol that computes the time it
95
- takes to go back and forth in the network.
96
-
97
93
  The aforementioned tests can be run with the following command (make sure to
98
94
  have installed the dependencies with `npm install` beforehand):
99
95
  ```bash
100
- npm run tests
96
+ npm run test
101
97
  ```