cryptpad-server 0.0.1 → 0.0.3
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/build/core.js +61 -66
- package/build/core.worker.js +53 -44
- package/build/front.js +62 -58
- package/build/http.js +61 -54
- package/build/http.worker.js +33 -11
- package/build/storage.cluster.js +78 -53
- package/build/storage.js +99 -65
- package/build/storage.worker.js +55 -48
- package/index.js +3 -2
- package/package.json +6 -4
- package/readme.md +41 -44
package/build/storage.js
CHANGED
|
@@ -998,7 +998,6 @@ function requireCore() {
|
|
|
998
998
|
const Util = requireCommonUtil$1();
|
|
999
999
|
const Constants = requireConstants();
|
|
1000
1000
|
const escapeKeyCharacters = Util.escapeKeyCharacters;
|
|
1001
|
-
__require$5();
|
|
1002
1001
|
const Crypto = __require$6();
|
|
1003
1002
|
const Keys = requireKeys();
|
|
1004
1003
|
Core.DEFAULT_LIMIT = 50 * 1024 * 1024;
|
|
@@ -1118,8 +1117,7 @@ function requireCore() {
|
|
|
1118
1117
|
cb();
|
|
1119
1118
|
};
|
|
1120
1119
|
Core.getPaths = (mainConfig, isEnv) => {
|
|
1121
|
-
const {
|
|
1122
|
-
Constants.paths;
|
|
1120
|
+
const {config} = mainConfig;
|
|
1123
1121
|
const all = {
|
|
1124
1122
|
basePath: config.basePath || config.base || "./data",
|
|
1125
1123
|
filePath: config.filePath || "./datastore",
|
|
@@ -5475,6 +5473,27 @@ function requireBlock$1() {
|
|
|
5475
5473
|
}, cb);
|
|
5476
5474
|
});
|
|
5477
5475
|
};
|
|
5476
|
+
Block.rootPlaceholderCreate = (Env, _cb) => {
|
|
5477
|
+
const cb = Util.once(Util.mkAsync(_cb));
|
|
5478
|
+
nThen(w => {
|
|
5479
|
+
Fse.mkdirp(Env.paths.block, w(err => {
|
|
5480
|
+
if (err) {
|
|
5481
|
+
Env.Log.error("BLOCK_FOLDER_CREATE_FAILED", err);
|
|
5482
|
+
w.abort();
|
|
5483
|
+
return cb(err);
|
|
5484
|
+
}
|
|
5485
|
+
}));
|
|
5486
|
+
}).nThen(w => {
|
|
5487
|
+
const fullPath = Path.join(Env.paths.block, "placeholder.txt");
|
|
5488
|
+
Fs.writeFile(fullPath, "PLACEHOLDER\n", w(err => {
|
|
5489
|
+
if (err) {
|
|
5490
|
+
Env.Log.error("BLOCK_PLACEHOLDER_CREATE_FAILED", err);
|
|
5491
|
+
w.abort();
|
|
5492
|
+
return cb(err);
|
|
5493
|
+
}
|
|
5494
|
+
}));
|
|
5495
|
+
}).nThen(() => cb());
|
|
5496
|
+
};
|
|
5478
5497
|
})(block$1);
|
|
5479
5498
|
return block$1.exports;
|
|
5480
5499
|
}
|
|
@@ -5926,60 +5945,69 @@ var hasRequiredCrypto;
|
|
|
5926
5945
|
function requireCrypto() {
|
|
5927
5946
|
if (hasRequiredCrypto) return crypto;
|
|
5928
5947
|
hasRequiredCrypto = 1;
|
|
5929
|
-
|
|
5930
|
-
let
|
|
5931
|
-
exports.decodeBase64 = msg => Buffer.from(msg, "base64");
|
|
5932
|
-
exports.encodeBase64 = msg => Buffer.from(msg).toString("base64");
|
|
5933
|
-
exports.decodeUTF8 = msg => Buffer.from(msg, "utf8");
|
|
5934
|
-
exports.encodeUTF8 = msg => Buffer.from(msg).toString("utf8");
|
|
5948
|
+
const loadSodium = cryptoLib => {
|
|
5949
|
+
let sodiumLib = {};
|
|
5935
5950
|
let SodiumNative, NaCl;
|
|
5936
5951
|
switch (cryptoLib) {
|
|
5937
5952
|
case "sodiumnative":
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
};
|
|
5947
|
-
exports.detachedVerify = (signedBuffer, signatureBuffer, validateKey) => SodiumNative.crypto_sign_verify_detached(signatureBuffer, signedBuffer, validateKey);
|
|
5948
|
-
exports.secretbox = (message, nonce, secretKey) => {
|
|
5949
|
-
let secretBox = Buffer.alloc(message.length + SodiumNative.crypto_box_MACBYTES);
|
|
5950
|
-
SodiumNative.crypto_secretbox_easy(secretBox, message, nonce, secretKey);
|
|
5951
|
-
return secretBox;
|
|
5952
|
-
};
|
|
5953
|
-
exports.secretboxOpen = (secretBox, nonce, secretKey) => {
|
|
5954
|
-
let msg = Buffer.alloc(secretBox.length - SodiumNative.crypto_secretbox_MACBYTES);
|
|
5955
|
-
if (SodiumNative.crypto_secretbox_open_easy(msg, secretBox, nonce, secretKey)) {
|
|
5953
|
+
try {
|
|
5954
|
+
SodiumNative = require("sodium-native");
|
|
5955
|
+
sodiumLib.sigVerify = (signedMessage, validateKey) => {
|
|
5956
|
+
let msg = signedMessage.subarray(64);
|
|
5957
|
+
let ok = SodiumNative.crypto_sign_open(msg, signedMessage, validateKey);
|
|
5958
|
+
if (!ok) {
|
|
5959
|
+
return false;
|
|
5960
|
+
}
|
|
5956
5961
|
return msg;
|
|
5957
|
-
}
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5962
|
+
};
|
|
5963
|
+
sodiumLib.detachedVerify = (signedBuffer, signatureBuffer, validateKey) => SodiumNative.crypto_sign_verify_detached(signatureBuffer, signedBuffer, validateKey);
|
|
5964
|
+
sodiumLib.secretbox = (message, nonce, secretKey) => {
|
|
5965
|
+
let secretBox = Buffer.alloc(message.length + SodiumNative.crypto_box_MACBYTES);
|
|
5966
|
+
SodiumNative.crypto_secretbox_easy(secretBox, message, nonce, secretKey);
|
|
5967
|
+
return secretBox;
|
|
5968
|
+
};
|
|
5969
|
+
sodiumLib.secretboxOpen = (secretBox, nonce, secretKey) => {
|
|
5970
|
+
let msg = Buffer.alloc(secretBox.length - SodiumNative.crypto_secretbox_MACBYTES);
|
|
5971
|
+
if (SodiumNative.crypto_secretbox_open_easy(msg, secretBox, nonce, secretKey)) {
|
|
5972
|
+
return msg;
|
|
5973
|
+
} else {
|
|
5974
|
+
return void 0;
|
|
5975
|
+
}
|
|
5976
|
+
};
|
|
5977
|
+
sodiumLib.publicKeyFromSecretKey = secretKey => {
|
|
5978
|
+
let pk = new Uint8Array(SodiumNative.crypto_sign_PUBLICKEYBYTES);
|
|
5979
|
+
SodiumNative.crypto_sign_ed25519_sk_to_pk(pk, secretKey);
|
|
5980
|
+
return pk;
|
|
5981
|
+
};
|
|
5982
|
+
sodiumLib.hash = message => {
|
|
5983
|
+
let out = Buffer.alloc(SodiumNative.crypto_hash_sha512_BYTES);
|
|
5984
|
+
SodiumNative.crypto_hash_sha512(out, message);
|
|
5985
|
+
return out;
|
|
5986
|
+
};
|
|
5987
|
+
} catch (err) {
|
|
5988
|
+
console.error("Error in loading sodium-native: fallback on tweetnacl");
|
|
5989
|
+
return loadSodium("");
|
|
5990
|
+
}
|
|
5971
5991
|
break;
|
|
5972
5992
|
|
|
5973
5993
|
default:
|
|
5974
5994
|
NaCl = require$$6;
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5995
|
+
sodiumLib.sigVerify = NaCl.sign.open;
|
|
5996
|
+
sodiumLib.detachedVerify = NaCl.sign.detached.verify;
|
|
5997
|
+
sodiumLib.secretbox = NaCl.secretbox;
|
|
5998
|
+
sodiumLib.secretboxOpen = (secretBox, nonce, secretKey) => Buffer.from(NaCl.secretbox.open(secretBox, nonce, secretKey));
|
|
5999
|
+
sodiumLib.publicKeyFromSecretKey = secretKey => NaCl.sign?.keyPair?.fromSecretKey(secretKey)?.publicKey;
|
|
6000
|
+
sodiumLib.hash = msg => Buffer.from(NaCl.hash(msg));
|
|
5981
6001
|
break;
|
|
5982
6002
|
}
|
|
6003
|
+
return sodiumLib;
|
|
6004
|
+
};
|
|
6005
|
+
crypto = cryptoLib => {
|
|
6006
|
+
const exports = loadSodium(cryptoLib);
|
|
6007
|
+
exports.decodeBase64 = msg => Buffer.from(msg, "base64");
|
|
6008
|
+
exports.encodeBase64 = msg => Buffer.from(msg).toString("base64");
|
|
6009
|
+
exports.decodeUTF8 = msg => Buffer.from(msg, "utf8");
|
|
6010
|
+
exports.encodeUTF8 = msg => Buffer.from(msg).toString("utf8");
|
|
5983
6011
|
return exports;
|
|
5984
6012
|
};
|
|
5985
6013
|
return crypto;
|
|
@@ -6667,7 +6695,7 @@ function requireMfaManager() {
|
|
|
6667
6695
|
return mfaManager;
|
|
6668
6696
|
}
|
|
6669
6697
|
|
|
6670
|
-
var version = "0.0.
|
|
6698
|
+
var version = "0.0.3";
|
|
6671
6699
|
|
|
6672
6700
|
var require$$2 = {
|
|
6673
6701
|
version
|
|
@@ -7485,13 +7513,13 @@ function require_interface() {
|
|
|
7485
7513
|
return;
|
|
7486
7514
|
}
|
|
7487
7515
|
const {type: rcvType, idx, challenge: challengeBase64, nonce: nonceBase64} = data;
|
|
7488
|
-
const challenge = new Uint8Array(
|
|
7489
|
-
const nonce = new Uint8Array(
|
|
7516
|
+
const challenge = new Uint8Array(Crypto.decodeBase64(challengeBase64));
|
|
7517
|
+
const nonce = new Uint8Array(Crypto.decodeBase64(nonceBase64));
|
|
7490
7518
|
if (ctx.ChallengesCache[challengeBase64]) {
|
|
7491
7519
|
other.disconnect();
|
|
7492
7520
|
return ctx.Log.error("INTERFACE_CHALLENGE_ERROR", "Reused challenge");
|
|
7493
7521
|
}
|
|
7494
|
-
const msg =
|
|
7522
|
+
const msg = Crypto.secretboxOpen(challenge, nonce, ctx.nodes_key);
|
|
7495
7523
|
if (!msg) {
|
|
7496
7524
|
other.disconnect();
|
|
7497
7525
|
return ctx.Log.error("INTERFACE_CHALLENGE_ERROR", "Bad challenge answer");
|
|
@@ -7566,13 +7594,13 @@ function require_interface() {
|
|
|
7566
7594
|
let uid = Util.guid(ctx.pendingConnections);
|
|
7567
7595
|
ctx.pendingConnections[uid] = coreId;
|
|
7568
7596
|
const nonce = NodeCrypto.randomBytes(24);
|
|
7569
|
-
const msg =
|
|
7570
|
-
const challenge = Crypto.secretbox(msg, nonce, ctx.nodes_key)
|
|
7597
|
+
const msg = Crypto.decodeUTF8(`${ctx.myType}:${ctx.myNumber}:${String(Date.now())}`);
|
|
7598
|
+
const challenge = Crypto.encodeBase64(Crypto.secretbox(msg, nonce, ctx.nodes_key));
|
|
7571
7599
|
createHandlers(ctx, other);
|
|
7572
7600
|
other.send([ uid, "IDENTITY", {
|
|
7573
7601
|
type: ctx.myType,
|
|
7574
7602
|
idx: ctx.myNumber,
|
|
7575
|
-
nonce:
|
|
7603
|
+
nonce: Crypto.encodeBase64(nonce),
|
|
7576
7604
|
challenge
|
|
7577
7605
|
} ]);
|
|
7578
7606
|
};
|
|
@@ -10615,6 +10643,17 @@ function requireAdmin() {
|
|
|
10615
10643
|
const {key} = data;
|
|
10616
10644
|
MFA.revoke(Env, key, cb);
|
|
10617
10645
|
};
|
|
10646
|
+
const onGetCachedChannelMetadata = (Env, id, cb) => {
|
|
10647
|
+
const index = Env.metadata_cache?.[id];
|
|
10648
|
+
if (!index) {
|
|
10649
|
+
return void cb("ENOENT");
|
|
10650
|
+
}
|
|
10651
|
+
cb(void 0, index);
|
|
10652
|
+
};
|
|
10653
|
+
const onClearCachedChannelMetadata = (Env, id, cb) => {
|
|
10654
|
+
delete Env.metadata_cache[id];
|
|
10655
|
+
cb();
|
|
10656
|
+
};
|
|
10618
10657
|
const onArchiveBlock = (Env, data, cb) => {
|
|
10619
10658
|
const {key, reason} = data;
|
|
10620
10659
|
const archiveReason = {
|
|
@@ -11004,17 +11043,6 @@ function requireAdmin() {
|
|
|
11004
11043
|
}
|
|
11005
11044
|
cb(void 0, index);
|
|
11006
11045
|
};
|
|
11007
|
-
const onGetCachedChannelMetadata = (Env, id, cb) => {
|
|
11008
|
-
const index = Env.metadata_cache?.[id];
|
|
11009
|
-
if (!index) {
|
|
11010
|
-
return void cb("ENOENT");
|
|
11011
|
-
}
|
|
11012
|
-
cb(void 0, index);
|
|
11013
|
-
};
|
|
11014
|
-
const onClearCachedChannelMetadata = (Env, id, cb) => {
|
|
11015
|
-
delete Env.metadata_cache[id];
|
|
11016
|
-
cb();
|
|
11017
|
-
};
|
|
11018
11046
|
const onGetActiveChannelCount = (Env, _id, cb) => {
|
|
11019
11047
|
if (!Env.channel_cache) {
|
|
11020
11048
|
return void cb("ENOENT");
|
|
@@ -12050,6 +12078,12 @@ function requireStorage() {
|
|
|
12050
12078
|
const bearerSecret = Util.encodeBase64(Crypto.randomBytes(32));
|
|
12051
12079
|
const decree = [ "SET_BEARER_SECRET", [ bearerSecret ], "INTERNAL", +new Date ];
|
|
12052
12080
|
Decrees.onNewDecree(Env, decree, "", waitFor());
|
|
12081
|
+
}).nThen(w => {
|
|
12082
|
+
BlockStore.rootPlaceholderCreate(Env, w(err => {
|
|
12083
|
+
if (err) {
|
|
12084
|
+
console.warn(`${myId}: Impossible to create block's placeholder. Please check the value of blockPath in your config.js file and if you have write access on it.`);
|
|
12085
|
+
}
|
|
12086
|
+
}));
|
|
12053
12087
|
}).nThen(() => {
|
|
12054
12088
|
if (index !== 0) {
|
|
12055
12089
|
return;
|
package/build/storage.worker.js
CHANGED
|
@@ -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 {
|
|
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",
|
|
@@ -4733,7 +4731,7 @@ function requireTasks() {
|
|
|
4733
4731
|
return tasks.exports;
|
|
4734
4732
|
}
|
|
4735
4733
|
|
|
4736
|
-
var version = "0.0.
|
|
4734
|
+
var version = "0.0.3";
|
|
4737
4735
|
|
|
4738
4736
|
var require$$2 = {
|
|
4739
4737
|
version
|
|
@@ -5512,60 +5510,69 @@ var hasRequiredCrypto;
|
|
|
5512
5510
|
function requireCrypto() {
|
|
5513
5511
|
if (hasRequiredCrypto) return crypto;
|
|
5514
5512
|
hasRequiredCrypto = 1;
|
|
5515
|
-
|
|
5516
|
-
let
|
|
5517
|
-
exports.decodeBase64 = msg => Buffer.from(msg, "base64");
|
|
5518
|
-
exports.encodeBase64 = msg => Buffer.from(msg).toString("base64");
|
|
5519
|
-
exports.decodeUTF8 = msg => Buffer.from(msg, "utf8");
|
|
5520
|
-
exports.encodeUTF8 = msg => Buffer.from(msg).toString("utf8");
|
|
5513
|
+
const loadSodium = cryptoLib => {
|
|
5514
|
+
let sodiumLib = {};
|
|
5521
5515
|
let SodiumNative, NaCl;
|
|
5522
5516
|
switch (cryptoLib) {
|
|
5523
5517
|
case "sodiumnative":
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
|
|
5532
|
-
};
|
|
5533
|
-
exports.detachedVerify = (signedBuffer, signatureBuffer, validateKey) => SodiumNative.crypto_sign_verify_detached(signatureBuffer, signedBuffer, validateKey);
|
|
5534
|
-
exports.secretbox = (message, nonce, secretKey) => {
|
|
5535
|
-
let secretBox = Buffer.alloc(message.length + SodiumNative.crypto_box_MACBYTES);
|
|
5536
|
-
SodiumNative.crypto_secretbox_easy(secretBox, message, nonce, secretKey);
|
|
5537
|
-
return secretBox;
|
|
5538
|
-
};
|
|
5539
|
-
exports.secretboxOpen = (secretBox, nonce, secretKey) => {
|
|
5540
|
-
let msg = Buffer.alloc(secretBox.length - SodiumNative.crypto_secretbox_MACBYTES);
|
|
5541
|
-
if (SodiumNative.crypto_secretbox_open_easy(msg, secretBox, nonce, secretKey)) {
|
|
5518
|
+
try {
|
|
5519
|
+
SodiumNative = require("sodium-native");
|
|
5520
|
+
sodiumLib.sigVerify = (signedMessage, validateKey) => {
|
|
5521
|
+
let msg = signedMessage.subarray(64);
|
|
5522
|
+
let ok = SodiumNative.crypto_sign_open(msg, signedMessage, validateKey);
|
|
5523
|
+
if (!ok) {
|
|
5524
|
+
return false;
|
|
5525
|
+
}
|
|
5542
5526
|
return msg;
|
|
5543
|
-
}
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5527
|
+
};
|
|
5528
|
+
sodiumLib.detachedVerify = (signedBuffer, signatureBuffer, validateKey) => SodiumNative.crypto_sign_verify_detached(signatureBuffer, signedBuffer, validateKey);
|
|
5529
|
+
sodiumLib.secretbox = (message, nonce, secretKey) => {
|
|
5530
|
+
let secretBox = Buffer.alloc(message.length + SodiumNative.crypto_box_MACBYTES);
|
|
5531
|
+
SodiumNative.crypto_secretbox_easy(secretBox, message, nonce, secretKey);
|
|
5532
|
+
return secretBox;
|
|
5533
|
+
};
|
|
5534
|
+
sodiumLib.secretboxOpen = (secretBox, nonce, secretKey) => {
|
|
5535
|
+
let msg = Buffer.alloc(secretBox.length - SodiumNative.crypto_secretbox_MACBYTES);
|
|
5536
|
+
if (SodiumNative.crypto_secretbox_open_easy(msg, secretBox, nonce, secretKey)) {
|
|
5537
|
+
return msg;
|
|
5538
|
+
} else {
|
|
5539
|
+
return void 0;
|
|
5540
|
+
}
|
|
5541
|
+
};
|
|
5542
|
+
sodiumLib.publicKeyFromSecretKey = secretKey => {
|
|
5543
|
+
let pk = new Uint8Array(SodiumNative.crypto_sign_PUBLICKEYBYTES);
|
|
5544
|
+
SodiumNative.crypto_sign_ed25519_sk_to_pk(pk, secretKey);
|
|
5545
|
+
return pk;
|
|
5546
|
+
};
|
|
5547
|
+
sodiumLib.hash = message => {
|
|
5548
|
+
let out = Buffer.alloc(SodiumNative.crypto_hash_sha512_BYTES);
|
|
5549
|
+
SodiumNative.crypto_hash_sha512(out, message);
|
|
5550
|
+
return out;
|
|
5551
|
+
};
|
|
5552
|
+
} catch (err) {
|
|
5553
|
+
console.error("Error in loading sodium-native: fallback on tweetnacl");
|
|
5554
|
+
return loadSodium("");
|
|
5555
|
+
}
|
|
5557
5556
|
break;
|
|
5558
5557
|
|
|
5559
5558
|
default:
|
|
5560
5559
|
NaCl = require$$3$1;
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5560
|
+
sodiumLib.sigVerify = NaCl.sign.open;
|
|
5561
|
+
sodiumLib.detachedVerify = NaCl.sign.detached.verify;
|
|
5562
|
+
sodiumLib.secretbox = NaCl.secretbox;
|
|
5563
|
+
sodiumLib.secretboxOpen = (secretBox, nonce, secretKey) => Buffer.from(NaCl.secretbox.open(secretBox, nonce, secretKey));
|
|
5564
|
+
sodiumLib.publicKeyFromSecretKey = secretKey => NaCl.sign?.keyPair?.fromSecretKey(secretKey)?.publicKey;
|
|
5565
|
+
sodiumLib.hash = msg => Buffer.from(NaCl.hash(msg));
|
|
5567
5566
|
break;
|
|
5568
5567
|
}
|
|
5568
|
+
return sodiumLib;
|
|
5569
|
+
};
|
|
5570
|
+
crypto = cryptoLib => {
|
|
5571
|
+
const exports = loadSodium(cryptoLib);
|
|
5572
|
+
exports.decodeBase64 = msg => Buffer.from(msg, "base64");
|
|
5573
|
+
exports.encodeBase64 = msg => Buffer.from(msg).toString("base64");
|
|
5574
|
+
exports.decodeUTF8 = msg => Buffer.from(msg, "utf8");
|
|
5575
|
+
exports.encodeUTF8 = msg => Buffer.from(msg).toString("utf8");
|
|
5569
5576
|
return exports;
|
|
5570
5577
|
};
|
|
5571
5578
|
return crypto;
|
package/index.js
CHANGED
|
@@ -8,8 +8,9 @@ const Path = require('node:path');
|
|
|
8
8
|
const showHelp = () => {
|
|
9
9
|
console.log(`Usage ${process.argv[1]}:`);
|
|
10
10
|
console.log("\t--help, -h\tDisplay this help");
|
|
11
|
-
console.log("\t--type,-t\tSet the
|
|
12
|
-
console.log("\t--index,-i\tSet the
|
|
11
|
+
console.log("\t--type,-t\tSet the node type (if unset, starts every node)");
|
|
12
|
+
console.log("\t--index,-i\tSet the node index (default: 0)");
|
|
13
|
+
console.log("\t--server,-s\tStart the set of nodes identified with serverId");
|
|
13
14
|
process.exit(1);
|
|
14
15
|
};
|
|
15
16
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cryptpad-server",
|
|
3
3
|
"description": "CryptPad Server",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.3",
|
|
5
5
|
"license": "AGPL-3.0+",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
"build"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"body-parser": "^2.2.0",
|
|
20
19
|
"connect-gzip-static": "^4.2.1",
|
|
21
20
|
"cookie-parser": "^1.4.7",
|
|
22
|
-
"express": "~
|
|
21
|
+
"express": "~5.2.1",
|
|
22
|
+
"mime-types": "^3.0.2",
|
|
23
23
|
"fs-extra": "^7.0.0",
|
|
24
24
|
"http-proxy-middleware": "^3.0.3",
|
|
25
25
|
"nthen": "0.1.8",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"typescript": "^5.6.2"
|
|
51
51
|
},
|
|
52
52
|
"overrides": {
|
|
53
|
+
"qs": "^6.16.0",
|
|
53
54
|
"http-proxy": "npm:http-proxy-3@^1.23.2",
|
|
54
55
|
"serialize-javascript": "^7.0.4"
|
|
55
56
|
},
|
|
@@ -63,6 +64,7 @@
|
|
|
63
64
|
"tests": "node --test tests/",
|
|
64
65
|
"test": "node tests/runAll.js",
|
|
65
66
|
"start": "node index.js",
|
|
66
|
-
"dev": "DEV=1 node index.js"
|
|
67
|
+
"dev": "DEV=1 node index.js",
|
|
68
|
+
"windev": "set DEV=1& node index.js"
|
|
67
69
|
}
|
|
68
70
|
}
|
package/readme.md
CHANGED
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
4
|
-->
|
|
5
|
-
# Prototype: Scalable Server for CryptPad
|
|
6
5
|
|
|
7
|
-
This repository contains
|
|
8
|
-
still in progress exploratory work.
|
|
6
|
+
This repository contains the code for CryptPad server.
|
|
9
7
|
|
|
10
8
|
## Architecture
|
|
11
9
|
|
|
@@ -23,54 +21,32 @@ they can be done in place without too much pressure on them.
|
|
|
23
21
|
|
|
24
22
|
### Topology
|
|
25
23
|
|
|
26
|
-
The core nodes are connected to both
|
|
27
|
-
cannot communicate directly.
|
|
24
|
+
The core nodes are connected to both front and storage nodes, but the latter two
|
|
25
|
+
cannot communicate directly (only on the same layer).
|
|
28
26
|
|
|
29
27
|
## Configuration
|
|
30
28
|
|
|
31
|
-
The configuration can be done
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
Using websockets for communication, this variable looks like this:
|
|
35
|
-
|
|
36
|
-
```javascript
|
|
37
|
-
let Config = {
|
|
38
|
-
infra: {
|
|
39
|
-
ws: [{
|
|
40
|
-
host: 'localhost',
|
|
41
|
-
port: 3010
|
|
42
|
-
}],
|
|
43
|
-
core: [{
|
|
44
|
-
host: 'localhost',
|
|
45
|
-
port: 3011
|
|
46
|
-
}, {
|
|
47
|
-
host: 'localhost',
|
|
48
|
-
port: 3012
|
|
49
|
-
}],
|
|
50
|
-
storage: [{
|
|
51
|
-
host: 'localhost',
|
|
52
|
-
port: 3014
|
|
53
|
-
}]
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
The above configuration describes a network comprised of 4 nodes, having one
|
|
59
|
-
front node on port `3010`, 2 core servers on port `3011` and `3012`
|
|
60
|
-
and a storage node accessible via port `3014`.
|
|
29
|
+
The configuration can be done in `config/infra.js`, which will store the graph
|
|
30
|
+
topology of the nodes and how to connect to them.
|
|
61
31
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
node (the node listening on port `3011`), it would be `Config.myId = 'core:0'`.
|
|
32
|
+
Using websockets for communication, please look at `config/infra.example.js` for
|
|
33
|
+
explanations.
|
|
65
34
|
|
|
66
35
|
## Usage
|
|
67
36
|
|
|
68
|
-
|
|
37
|
+
To be used in CryptPad, this repository releases are available on npm:
|
|
38
|
+
https://www.npmjs.com/package/cryptpad-server
|
|
39
|
+
|
|
40
|
+
You can also use it in standalone mode for development purpose. The client code
|
|
41
|
+
should be present in `../cryptpad/` or in a `clientRoot` property as a string in
|
|
42
|
+
`config/config.js`. Before first use, you may want to install the dependencies
|
|
43
|
+
and build the code with:
|
|
69
44
|
```bash
|
|
70
45
|
npm install
|
|
46
|
+
npm run build
|
|
71
47
|
```
|
|
72
48
|
|
|
73
|
-
To spawn the server topology described in `
|
|
49
|
+
To spawn the server topology described in `infra/config.js`, run the start script:
|
|
74
50
|
```bash
|
|
75
51
|
npm run start
|
|
76
52
|
```
|
|
@@ -78,14 +54,35 @@ npm run start
|
|
|
78
54
|
Alternatively, you can the new servers manually. You first need to start the
|
|
79
55
|
`core` nodes with the following command.
|
|
80
56
|
|
|
57
|
+
For that to work, you need to have a shared key between the different nodes to
|
|
58
|
+
authenticate them, which can be generated with:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
openssl rand -base64 32
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Then add the resulting random bytes in `private.nodes_key` property in your
|
|
65
|
+
`config/config.js`.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
node index.js --type core --index 0
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Then you can start a `front` and `storage` nodes in any order:
|
|
81
72
|
```bash
|
|
82
|
-
node
|
|
73
|
+
node index.js --type front --index 0
|
|
74
|
+
node index.js --type storage --index 0
|
|
75
|
+
node index.js --type front --index 1
|
|
76
|
+
node index.js --type storage --index 2
|
|
77
|
+
node index.js --type storage --index 1
|
|
83
78
|
```
|
|
84
79
|
|
|
85
|
-
|
|
80
|
+
Alternatively, you can identify different sets of nodes with the `serverId`
|
|
81
|
+
property of their corresponding nodes in `config/infra.js`, and start a subset
|
|
82
|
+
of them sharing the same `serverId` with:
|
|
83
|
+
|
|
86
84
|
```bash
|
|
87
|
-
node
|
|
88
|
-
node front/index.js
|
|
85
|
+
node index.js --server [serverId value]
|
|
89
86
|
```
|
|
90
87
|
|
|
91
88
|
## Tests
|