|
|
|
@ -19,6 +19,7 @@ const getFolderSize = require("get-folder-size");
|
|
|
|
|
const Pins = require("./lib/pins");
|
|
|
|
|
const Meta = require("./lib/metadata");
|
|
|
|
|
const WriteQueue = require("./lib/write-queue");
|
|
|
|
|
const BatchRead = require("./lib/batch-read");
|
|
|
|
|
|
|
|
|
|
var RPC = module.exports;
|
|
|
|
|
|
|
|
|
@ -231,6 +232,7 @@ var checkSignature = function (signedMsg, signature, publicKey) {
|
|
|
|
|
return Nacl.sign.detached.verify(signedBuffer, signatureBuffer, pubBuffer);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const batchUserPins = BatchRead("LOAD_USER_PINS");
|
|
|
|
|
var loadUserPins = function (Env, publicKey, cb) {
|
|
|
|
|
var session = getSession(Env.Sessions, publicKey);
|
|
|
|
|
|
|
|
|
@ -238,6 +240,7 @@ var loadUserPins = function (Env, publicKey, cb) {
|
|
|
|
|
return cb(session.channels);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
batchUserPins(publicKey, cb, function (done) {
|
|
|
|
|
var ref = {};
|
|
|
|
|
var lineHandler = Pins.createLineHandler(ref, function (label, data) {
|
|
|
|
|
Log.error(label, {
|
|
|
|
@ -252,7 +255,8 @@ var loadUserPins = function (Env, publicKey, cb) {
|
|
|
|
|
|
|
|
|
|
// only put this into the cache if it completes
|
|
|
|
|
session.channels = ref.pins;
|
|
|
|
|
cb(ref.pins);
|
|
|
|
|
done(ref.pins); // FIXME no error handling?
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -268,12 +272,12 @@ var getChannelList = function (Env, publicKey, cb) {
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var makeFilePath = function (root, id) {
|
|
|
|
|
var makeFilePath = function (root, id) { // FIXME FILES
|
|
|
|
|
if (typeof(id) !== 'string' || id.length <= 2) { return null; }
|
|
|
|
|
return Path.join(root, id.slice(0, 2), id);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var getUploadSize = function (Env, channel, cb) {
|
|
|
|
|
var getUploadSize = function (Env, channel, cb) { // FIXME FILES
|
|
|
|
|
var paths = Env.paths;
|
|
|
|
|
var path = makeFilePath(paths.blob, channel);
|
|
|
|
|
if (!path) {
|
|
|
|
@ -290,45 +294,49 @@ var getUploadSize = function (Env, channel, cb) {
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const batchFileSize = BatchRead("GET_FILE_SIZE");
|
|
|
|
|
var getFileSize = function (Env, channel, cb) {
|
|
|
|
|
if (!isValidId(channel)) { return void cb('INVALID_CHAN'); }
|
|
|
|
|
|
|
|
|
|
batchFileSize(channel, cb, function (done) {
|
|
|
|
|
if (channel.length === 32) {
|
|
|
|
|
if (typeof(Env.msgStore.getChannelSize) !== 'function') {
|
|
|
|
|
return cb('GET_CHANNEL_SIZE_UNSUPPORTED');
|
|
|
|
|
return done('GET_CHANNEL_SIZE_UNSUPPORTED');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return void Env.msgStore.getChannelSize(channel, function (e, size /*:number*/) {
|
|
|
|
|
if (e) {
|
|
|
|
|
if (e.code === 'ENOENT') { return void cb(void 0, 0); }
|
|
|
|
|
return void cb(e.code);
|
|
|
|
|
if (e.code === 'ENOENT') { return void done(void 0, 0); }
|
|
|
|
|
return void done(e.code);
|
|
|
|
|
}
|
|
|
|
|
cb(void 0, size);
|
|
|
|
|
done(void 0, size);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 'channel' refers to a file, so you need another API
|
|
|
|
|
getUploadSize(Env, channel, function (e, size) {
|
|
|
|
|
if (typeof(size) === 'undefined') { return void cb(e); }
|
|
|
|
|
cb(void 0, size);
|
|
|
|
|
if (typeof(size) === 'undefined') { return void done(e); }
|
|
|
|
|
done(void 0, size);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const batchMetadata = BatchRead("GET_METADATA");
|
|
|
|
|
var getMetadata = function (Env, channel, cb) {
|
|
|
|
|
if (!isValidId(channel)) { return void cb('INVALID_CHAN'); }
|
|
|
|
|
|
|
|
|
|
if (channel.length !== 32) { return cb("INVALID_CHAN"); }
|
|
|
|
|
|
|
|
|
|
batchMetadata(channel, cb, function (done) {
|
|
|
|
|
var ref = {};
|
|
|
|
|
var lineHandler = Meta.createLineHandler(ref, Log.error);
|
|
|
|
|
|
|
|
|
|
return void Env.msgStore.readChannelMetadata(channel, lineHandler, function (err) {
|
|
|
|
|
if (err) {
|
|
|
|
|
// stream errors?
|
|
|
|
|
return void cb(err);
|
|
|
|
|
return void done(err);
|
|
|
|
|
}
|
|
|
|
|
cb(void 0, ref.meta);
|
|
|
|
|
done(void 0, ref.meta);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -470,19 +478,22 @@ var getDeletedPads = function (Env, channels, cb) {
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const batchTotalSize = BatchRead("GET_TOTAL_SIZE");
|
|
|
|
|
var getTotalSize = function (Env, publicKey, cb) {
|
|
|
|
|
batchTotalSize(publicKey, cb, function (done) {
|
|
|
|
|
var bytes = 0;
|
|
|
|
|
return void getChannelList(Env, publicKey, function (channels) {
|
|
|
|
|
if (!channels) { return cb('INVALID_PIN_LIST'); } // unexpected
|
|
|
|
|
if (!channels) { return done('INVALID_PIN_LIST'); } // unexpected
|
|
|
|
|
|
|
|
|
|
var count = channels.length;
|
|
|
|
|
if (!count) { cb(void 0, 0); }
|
|
|
|
|
if (!count) { return void done(void 0, 0); }
|
|
|
|
|
|
|
|
|
|
channels.forEach(function (channel) {
|
|
|
|
|
channels.forEach(function (channel) { // FIXME this might as well be nThen
|
|
|
|
|
getFileSize(Env, channel, function (e, size) {
|
|
|
|
|
count--;
|
|
|
|
|
if (!e) { bytes += size; }
|
|
|
|
|
if (count === 0) { return cb(void 0, bytes); }
|
|
|
|
|
if (count === 0) { return done(void 0, bytes); }
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
@ -538,7 +549,7 @@ var applyCustomLimits = function (Env, config) {
|
|
|
|
|
|
|
|
|
|
// The limits object contains storage limits for all the publicKey that have paid
|
|
|
|
|
// To each key is associated an object containing the 'limit' value and a 'note' explaining that limit
|
|
|
|
|
var updateLimits = function (Env, config, publicKey, cb /*:(?string, ?any[])=>void*/) {
|
|
|
|
|
var updateLimits = function (Env, config, publicKey, cb /*:(?string, ?any[])=>void*/) { // FIXME BATCH?
|
|
|
|
|
|
|
|
|
|
if (config.adminEmail === false) {
|
|
|
|
|
applyCustomLimits(Env, config);
|
|
|
|
@ -831,7 +842,7 @@ var resetUserPins = function (Env, publicKey, channelList, cb) {
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var makeFileStream = function (root, id, cb) {
|
|
|
|
|
var makeFileStream = function (root, id, cb) { // FIXME FILES
|
|
|
|
|
var stub = id.slice(0, 2);
|
|
|
|
|
var full = makeFilePath(root, id);
|
|
|
|
|
if (!full) {
|
|
|
|
@ -862,7 +873,7 @@ var makeFileStream = function (root, id, cb) {
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var isFile = function (filePath, cb) {
|
|
|
|
|
var isFile = function (filePath, cb) { // FIXME FILES
|
|
|
|
|
/*:: if (typeof(filePath) !== 'string') { throw new Error('should never happen'); } */
|
|
|
|
|
Fs.stat(filePath, function (e, stats) {
|
|
|
|
|
if (e) {
|
|
|
|
@ -892,8 +903,7 @@ var clearOwnedChannel = function (Env, channelId, unsafeKey, cb) {
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var removeOwnedBlob = function (Env, blobId, unsafeKey, cb) {
|
|
|
|
|
// FIXME METADATA
|
|
|
|
|
var removeOwnedBlob = function (Env, blobId, unsafeKey, cb) { // FIXME FILES // FIXME METADATA
|
|
|
|
|
var safeKey = escapeKeyCharacters(unsafeKey);
|
|
|
|
|
var safeKeyPrefix = safeKey.slice(0,3);
|
|
|
|
|
var blobPrefix = blobId.slice(0,2);
|
|
|
|
@ -1009,7 +1019,7 @@ var removePins = function (Env, safeKey, cb) {
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var upload = function (Env, publicKey, content, cb) {
|
|
|
|
|
var upload = function (Env, publicKey, content, cb) { // FIXME FILES
|
|
|
|
|
var paths = Env.paths;
|
|
|
|
|
var dec;
|
|
|
|
|
try { dec = Buffer.from(content, 'base64'); }
|
|
|
|
@ -1045,7 +1055,7 @@ var upload = function (Env, publicKey, content, cb) {
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var upload_cancel = function (Env, publicKey, fileSize, cb) {
|
|
|
|
|
var upload_cancel = function (Env, publicKey, fileSize, cb) { // FIXME FILES
|
|
|
|
|
var paths = Env.paths;
|
|
|
|
|
|
|
|
|
|
var session = getSession(Env.Sessions, publicKey);
|
|
|
|
@ -1069,7 +1079,7 @@ var upload_cancel = function (Env, publicKey, fileSize, cb) {
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var upload_complete = function (Env, publicKey, id, cb) { // FIXME logging
|
|
|
|
|
var upload_complete = function (Env, publicKey, id, cb) { // FIXME FILES
|
|
|
|
|
var paths = Env.paths;
|
|
|
|
|
var session = getSession(Env.Sessions, publicKey);
|
|
|
|
|
|
|
|
|
@ -1085,7 +1095,7 @@ var upload_complete = function (Env, publicKey, id, cb) { // FIXME logging
|
|
|
|
|
|
|
|
|
|
var oldPath = makeFilePath(paths.staging, publicKey);
|
|
|
|
|
if (!oldPath) {
|
|
|
|
|
WARN('safeMkdir', "oldPath is null"); // FIXME logging
|
|
|
|
|
WARN('safeMkdir', "oldPath is null");
|
|
|
|
|
return void cb('RENAME_ERR');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1093,13 +1103,13 @@ var upload_complete = function (Env, publicKey, id, cb) { // FIXME logging
|
|
|
|
|
var prefix = id.slice(0, 2);
|
|
|
|
|
var newPath = makeFilePath(paths.blob, id);
|
|
|
|
|
if (typeof(newPath) !== 'string') {
|
|
|
|
|
WARN('safeMkdir', "newPath is null"); // FIXME logging
|
|
|
|
|
WARN('safeMkdir', "newPath is null");
|
|
|
|
|
return void cb('RENAME_ERR');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Fse.mkdirp(Path.join(paths.blob, prefix), function (e) {
|
|
|
|
|
if (e || !newPath) {
|
|
|
|
|
WARN('safeMkdir', e); // FIXME logging
|
|
|
|
|
WARN('safeMkdir', e);
|
|
|
|
|
return void cb('RENAME_ERR');
|
|
|
|
|
}
|
|
|
|
|
isFile(newPath, function (e, yes) {
|
|
|
|
@ -1122,7 +1132,6 @@ var upload_complete = function (Env, publicKey, id, cb) { // FIXME logging
|
|
|
|
|
return void cb(e || 'PATH_ERR');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// lol wut handle ur errors
|
|
|
|
|
Fse.move(oldPath, newPath, function (e) {
|
|
|
|
|
if (e) {
|
|
|
|
|
WARN('rename', e);
|
|
|
|
@ -1135,7 +1144,7 @@ var upload_complete = function (Env, publicKey, id, cb) { // FIXME logging
|
|
|
|
|
tryLocation(handleMove);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
/* FIXME FILES
|
|
|
|
|
var owned_upload_complete = function (Env, safeKey, cb) {
|
|
|
|
|
var session = getSession(Env.Sessions, safeKey);
|
|
|
|
|
|
|
|
|
@ -1230,7 +1239,7 @@ var owned_upload_complete = function (Env, safeKey, cb) {
|
|
|
|
|
};
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
var owned_upload_complete = function (Env, safeKey, id, cb) { // FIXME logging
|
|
|
|
|
var owned_upload_complete = function (Env, safeKey, id, cb) { // FIXME FILES
|
|
|
|
|
var session = getSession(Env.Sessions, safeKey);
|
|
|
|
|
|
|
|
|
|
// the file has already been uploaded to the staging area
|
|
|
|
@ -1341,7 +1350,7 @@ var owned_upload_complete = function (Env, safeKey, id, cb) { // FIXME logging
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var upload_status = function (Env, publicKey, filesize, cb) {
|
|
|
|
|
var upload_status = function (Env, publicKey, filesize, cb) { // FIXME FILES
|
|
|
|
|
var paths = Env.paths;
|
|
|
|
|
|
|
|
|
|
// validate that the provided size is actually a positive number
|
|
|
|
@ -1387,7 +1396,7 @@ var upload_status = function (Env, publicKey, filesize, cb) {
|
|
|
|
|
author of the block, since we assume that the block will have been
|
|
|
|
|
encrypted with xsalsa20-poly1305 which is authenticated.
|
|
|
|
|
*/
|
|
|
|
|
var validateLoginBlock = function (Env, publicKey, signature, block, cb) {
|
|
|
|
|
var validateLoginBlock = function (Env, publicKey, signature, block, cb) { // FIXME BLOCKS
|
|
|
|
|
// convert the public key to a Uint8Array and validate it
|
|
|
|
|
if (typeof(publicKey) !== 'string') { return void cb('E_INVALID_KEY'); }
|
|
|
|
|
|
|
|
|
@ -1428,7 +1437,7 @@ var validateLoginBlock = function (Env, publicKey, signature, block, cb) {
|
|
|
|
|
return void cb(null, u8_block);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var createLoginBlockPath = function (Env, publicKey) {
|
|
|
|
|
var createLoginBlockPath = function (Env, publicKey) { // FIXME BLOCKS
|
|
|
|
|
// prepare publicKey to be used as a file name
|
|
|
|
|
var safeKey = escapeKeyCharacters(publicKey);
|
|
|
|
|
|
|
|
|
@ -1442,7 +1451,7 @@ var createLoginBlockPath = function (Env, publicKey) {
|
|
|
|
|
return Path.join(Env.paths.block, safeKey.slice(0, 2), safeKey);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var writeLoginBlock = function (Env, msg, cb) {
|
|
|
|
|
var writeLoginBlock = function (Env, msg, cb) { // FIXME BLOCKS
|
|
|
|
|
//console.log(msg);
|
|
|
|
|
var publicKey = msg[0];
|
|
|
|
|
var signature = msg[1];
|
|
|
|
@ -1473,7 +1482,7 @@ var writeLoginBlock = function (Env, msg, cb) {
|
|
|
|
|
cb(e);
|
|
|
|
|
}
|
|
|
|
|
}));
|
|
|
|
|
}).nThen(function () { // FIXME logging
|
|
|
|
|
}).nThen(function () {
|
|
|
|
|
// actually write the block
|
|
|
|
|
|
|
|
|
|
// flow is dumb and I need to guard against this which will never happen
|
|
|
|
@ -1497,7 +1506,7 @@ var writeLoginBlock = function (Env, msg, cb) {
|
|
|
|
|
information, we can just sign some constant and use that as proof.
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
var removeLoginBlock = function (Env, msg, cb) {
|
|
|
|
|
var removeLoginBlock = function (Env, msg, cb) { // FIXME BLOCKS
|
|
|
|
|
var publicKey = msg[0];
|
|
|
|
|
var signature = msg[1];
|
|
|
|
|
var block = Nacl.util.decodeUTF8('DELETE_BLOCK'); // clients and the server will have to agree on this constant
|
|
|
|
@ -1605,7 +1614,9 @@ var writePrivateMessage = function (Env, args, nfwssCtx, cb) {
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const batchDiskUsage = BatchRead("GET_DISK_USAGE");
|
|
|
|
|
var getDiskUsage = function (Env, cb) {
|
|
|
|
|
batchDiskUsage('', cb, function (done) {
|
|
|
|
|
var data = {};
|
|
|
|
|
nThen(function (waitFor) {
|
|
|
|
|
getFolderSize('./', waitFor(function(err, info) {
|
|
|
|
@ -1627,10 +1638,14 @@ var getDiskUsage = function (Env, cb) {
|
|
|
|
|
data.datastore = info;
|
|
|
|
|
}));
|
|
|
|
|
}).nThen(function () {
|
|
|
|
|
cb (void 0, data);
|
|
|
|
|
done(void 0, data);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const batchRegisteredUsers = BatchRead("GET_REGISTERED_USERS");
|
|
|
|
|
var getRegisteredUsers = function (Env, cb) {
|
|
|
|
|
batchRegisteredUsers('', cb, function (done) {
|
|
|
|
|
var dir = Env.paths.pin;
|
|
|
|
|
var folders;
|
|
|
|
|
var users = 0;
|
|
|
|
@ -1638,7 +1653,7 @@ var getRegisteredUsers = function (Env, cb) {
|
|
|
|
|
Fs.readdir(dir, waitFor(function (err, list) {
|
|
|
|
|
if (err) {
|
|
|
|
|
waitFor.abort();
|
|
|
|
|
return void cb(err);
|
|
|
|
|
return void done(err);
|
|
|
|
|
}
|
|
|
|
|
folders = list;
|
|
|
|
|
}));
|
|
|
|
@ -1651,7 +1666,8 @@ var getRegisteredUsers = function (Env, cb) {
|
|
|
|
|
}));
|
|
|
|
|
});
|
|
|
|
|
}).nThen(function () {
|
|
|
|
|
cb(void 0, users);
|
|
|
|
|
done(void 0, users);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
var getActiveSessions = function (Env, ctx, cb) {
|
|
|
|
@ -1821,6 +1837,7 @@ RPC.create = function (
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var handleUnauthenticatedMessage = function (msg, respond, nfwssCtx) {
|
|
|
|
|
Log.silly('LOG_RPC', msg[0]);
|
|
|
|
|
switch (msg[0]) {
|
|
|
|
|
case 'GET_HISTORY_OFFSET': {
|
|
|
|
|
if (typeof(msg[1]) !== 'object' || typeof(msg[1].channelName) !== 'string') {
|
|
|
|
@ -1844,7 +1861,7 @@ RPC.create = function (
|
|
|
|
|
respond(e, [null, size, null]);
|
|
|
|
|
});
|
|
|
|
|
case 'GET_METADATA':
|
|
|
|
|
return void getMetadata(Env, msg[1], function (e, data) { // FIXME METADATA
|
|
|
|
|
return void getMetadata(Env, msg[1], function (e, data) {
|
|
|
|
|
WARN(e, msg[1]);
|
|
|
|
|
respond(e, [null, data, null]);
|
|
|
|
|
});
|
|
|
|
|