diff --git a/rpc.js b/rpc.js index a69bfc4ef..f2ba8e93e 100644 --- a/rpc.js +++ b/rpc.js @@ -817,6 +817,16 @@ var makeFileStream = function (root, id, cb) { }); }; +var isFile = function (filePath /*:string*/, cb) { + Fs.stat(filePath, function (e, stats) { + if (e) { + if (e.code === 'ENOENT') { return void cb(void 0, false); } + return void cb(e.message); + } + return void cb(void 0, stats.isFile()); + }); +}; + var clearOwnedChannel = function (Env, channelId, unsafeKey, cb) { if (typeof(channelId) !== 'string' || channelId.length !== 32) { return cb('INVALID_ARGUMENTS'); @@ -840,11 +850,65 @@ var clearOwnedChannel = function (Env, channelId, unsafeKey, cb) { }); }; +var removeOwnedBlob = function (Env, blobId, unsafeKey, cb) { + var safeKey = escapeKeyCharacters(unsafeKey); + var safeKeyPrefix = safeKey.slice(0,3); + var blobPrefix = blobId.slice(0,2); + + var blobPath = makeFilePath(Env.paths.blob, blobId); + var ownPath = Path.join(Env.paths.blob, safeKeyPrefix, safeKey, blobPrefix, blobId); + + nThen(function (w) { + // Check if the blob exists + isFile(blobPath, w(function (e, isFile) { + if (e) { + w.abort(); + return void cb(e); + } + if (!isFile) { + WARN('removeOwnedBlob', 'The provided blob ID is not a file!'); + w.abort(); + return void cb('EINVAL_BLOBID'); + } + })); + }).nThen(function (w) { + // Check if you're the owner + isFile(ownPath, w(function (e, isFile) { + if (e) { + w.abort(); + return void cb(e); + } + if (!isFile) { + WARN('removeOwnedBlob', 'Incorrect owner'); + w.abort(); + return void cb('INSUFFICIENT_PERMISSIONS'); + } + })); + }).nThen(function (w) { + // Delete the blob + Fs.unlink(blobPath, w(function (e) { + if (e) { + w.abort(); + return void cb(e); + } + })); + }).nThen(function () { + // Delete the proof of ownership + Fs.unlink(ownPath, function (e) { + cb(e); + }); + }); +}; + var removeOwnedChannel = function (Env, channelId, unsafeKey, cb) { - if (typeof(channelId) !== 'string' || channelId.length !== 32) { + if (typeof(channelId) !== 'string' || !isValidId(channelId)) { return cb('INVALID_ARGUMENTS'); } + if (testFileId(channelId)) { + return void removeOwnedBlob(Env, channelId, unsafeKey, cb); + } + if (!(Env.msgStore && Env.msgStore.removeChannel && Env.msgStore.getChannelMetadata)) { return cb("E_NOT_IMPLEMENTED"); } @@ -929,16 +993,6 @@ var upload_cancel = function (Env, publicKey, fileSize, cb) { }); }; -var isFile = function (filePath, cb) { - Fs.stat(filePath, function (e, stats) { - if (e) { - if (e.code === 'ENOENT') { return void cb(void 0, false); } - return void cb(e.message); - } - return void cb(void 0, stats.isFile()); - }); -}; - var upload_complete = function (Env, publicKey, id, cb) { var paths = Env.paths; var session = getSession(Env.Sessions, publicKey); @@ -1098,7 +1152,7 @@ var owned_upload_complete = function (Env, safeKey, cb) { }); }; -var owned_upload_complete_2 = function (Env, safeKey, id, cb) { +owned_upload_complete = function (Env, safeKey, id, cb) { var session = getSession(Env.Sessions, safeKey); // the file has already been uploaded to the staging area @@ -1617,7 +1671,7 @@ RPC.create = function ( }); case 'OWNED_UPLOAD_COMPLETE': if (!privileged) { return deny(); } - return void owned_upload_complete_2(Env, safeKey, msg[1], function (e, blobId) { + return void owned_upload_complete(Env, safeKey, msg[1], function (e, blobId) { WARN(e, blobId); Respond(e, blobId); }); diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index cb8d94bf8..f91f050e8 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -205,7 +205,7 @@ define([ }; common.uploadComplete = function (id, owned, cb) { - postMessage("UPLOAD_COMPLETE", {id: id, owned, owned}, function (obj) { + postMessage("UPLOAD_COMPLETE", {id: id, owned: owned}, function (obj) { if (obj && obj.error) { return void cb(obj.error); } cb(null, obj); }); diff --git a/www/common/pinpad.js b/www/common/pinpad.js index 6d6295989..957f5d1d6 100644 --- a/www/common/pinpad.js +++ b/www/common/pinpad.js @@ -151,7 +151,7 @@ define([ }; exp.removeOwnedChannel = function (channel, cb) { - if (typeof(channel) !== 'string' || channel.length !== 32) { + if (typeof(channel) !== 'string' || [32,48].indexOf(channel.length) === -1) { // can't use this on files because files can't be owned... return void cb('INVALID_ARGUMENTS'); } diff --git a/www/file/inner.js b/www/file/inner.js index f9b2a462a..41517a036 100644 --- a/www/file/inner.js +++ b/www/file/inner.js @@ -96,21 +96,26 @@ define([ } return void console.error(e); } + + // Add pad attributes when the file is saved in the drive + Title.onTitleChange(function () { + var owners = metadata.owners; + if (owners) { + common.setPadAttribute('owners', owners); + } + common.setPadAttribute('fileType', metadata.type); + }); + + // Save to the drive or update the acces time var title = document.title = metadata.name; Title.updateTitle(title || Title.defaultTitle); + toolbar.addElement(['pageTitle'], {pageTitle: title}); toolbar.$rightside.append(common.createButton('forget', true)); if (common.isLoggedIn()) { toolbar.$rightside.append(common.createButton('hashtag', true)); } - var owners = metadata.owners; - if (owners) { - common.setPadAttribute('owners', owners); - } - - common.setPadAttribute('fileType', metadata.type); - var displayFile = function (ev, sizeMb, CB) { var called_back; var cb = function (e) {