/*jshint esversion: 6 */ const Block = module.exports; const Util = require("../common-util"); const Path = require("path"); const Fs = require("fs"); const Fse = require("fs-extra"); const nThen = require("nthen"); Block.mkPath = function (Env, publicKey) { // prepare publicKey to be used as a file name var safeKey = Util.escapeKeyCharacters(publicKey); // validate safeKey if (typeof(safeKey) !== 'string') { return; } // derive the full path // /home/cryptpad/cryptpad/block/fg/fg32kefksjdgjkewrjksdfksjdfsdfskdjfsfd return Path.join(Env.paths.block, safeKey.slice(0, 2), safeKey); }; Block.mkArchivePath = function (Env, publicKey) { // prepare publicKey to be used as a file name var safeKey = Util.escapeKeyCharacters(publicKey); // validate safeKey if (typeof(safeKey) !== 'string') { return; } // derive the full path // /home/cryptpad/cryptpad/block/fg/fg32kefksjdgjkewrjksdfksjdfsdfskdjfsfd return Path.join(Env.paths.archive, 'block', safeKey.slice(0, 2), safeKey); }; Block.archive = function (Env, publicKey, _cb) { var cb = Util.once(Util.mkAsync(_cb)); // derive the filepath var currentPath = Block.mkPath(Env, publicKey); // make sure the path is valid if (typeof(currentPath) !== 'string') { return void cb('E_INVALID_BLOCK_PATH'); } var archivePath = Block.mkArchivePath(Env, publicKey); // make sure the path is valid if (typeof(archivePath) !== 'string') { return void cb('E_INVALID_BLOCK_ARCHIVAL_PATH'); } // TODO Env.incrementBytesWritten Fse.move(currentPath, archivePath, { overwrite: true, }, cb); }; Block.check = function (Env, publicKey, _cb) { // 'check' because 'exists' implies boolean var cb = Util.once(Util.mkAsync(_cb)); var path = Block.mkPath(Env, publicKey); Fs.access(path, Fs.constants.F_OK, cb); }; Block.write = function (Env, publicKey, buffer, _cb) { var cb = Util.once(Util.mkAsync(_cb)); var path = Block.mkPath(Env, publicKey); if (typeof(path) !== 'string') { return void cb('INVALID_PATH'); } var parsed = Path.parse(path); nThen(function (w) { Fse.mkdirp(parsed.dir, w(function (err) { if (!err) { return; } w.abort(); cb(err); })); }).nThen(function (w) { Block.archive(Env, publicKey, w(function (/* err */) { /* we proceed even if there are errors. it might be ENOENT (there is no file to archive) or EACCES (bad filesystem permissions for the existing archived block?) or lots of other things, none of which justify preventing the write */ })); }).nThen(function () { Fs.writeFile(path, buffer, { encoding: 'binary' }, cb); Env.incrementBytesWritten(buffer && buffer.length); }); };