From 55ea7f13fd020e33e626fcdee3fbd1a6d3a96be6 Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 22 Aug 2019 11:49:02 +0200 Subject: [PATCH 1/5] fix invalid conditional which would block task scheduling --- historyKeeper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/historyKeeper.js b/historyKeeper.js index 85e5f1dfb..aced95103 100644 --- a/historyKeeper.js +++ b/historyKeeper.js @@ -733,7 +733,7 @@ module.exports.create = function (cfg) { }); // write tasks - if(tasks && metadata.expire && metadata.expire === 'number') { + if(tasks && metadata.expire && typeof(metadata.expire) === 'number') { // the fun part... // the user has said they want this pad to expire at some point tasks.write(metadata.expire, "EXPIRE", [ channelName ], function (err) { From 3c1aadd6c13b81984412d17aa06194a20b1002d0 Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 22 Aug 2019 11:49:43 +0200 Subject: [PATCH 2/5] archive metadata even if there is no corresponding channel log --- storage/file.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/storage/file.js b/storage/file.js index def17e622..75dabf5b7 100644 --- a/storage/file.js +++ b/storage/file.js @@ -481,9 +481,13 @@ var archiveChannel = function (env, channelName, cb) { nThen(function (w) { // move the channel log and abort if anything goes wrong Fse.move(currentPath, archivePath, { overwrite: true }, w(function (err) { - if (!err) { return; } - w.abort(); - cb(err); + if (err) { + // proceed to the next block to remove metadata even if there's no channel + if (err.code === 'ENOENT') { return; } + // abort and callback for other types of errors + w.abort(); + return void cb(err); + } })); }).nThen(function (w) { // archive the dedicated metadata channel From a63bea1f59c347aa15514de626d637b13ad19698 Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 22 Aug 2019 11:50:06 +0200 Subject: [PATCH 3/5] remove invalid callback which would totally break channelBytes --- storage/file.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/file.js b/storage/file.js index 75dabf5b7..ab25b0963 100644 --- a/storage/file.js +++ b/storage/file.js @@ -603,7 +603,7 @@ var flushUnusedChannels = function (env, cb, frame) { }; /* channelBytes - calls back with the size (in bytes) of a channel and its metadata + calls back with an error or the size (in bytes) of a channel and its metadata */ var channelBytes = function (env, chanName, cb) { var channelPath = mkPath(env, chanName); @@ -627,7 +627,6 @@ var channelBytes = function (env, chanName, cb) { return void CB(err); } dataSize = stats.size; - CB(undefined, stats.size); })); }).nThen(function () { CB(void 0, channelSize + dataSize); From fc728617210e7658d9869883e6fd30adbeb21f69 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 22 Aug 2019 14:01:07 +0200 Subject: [PATCH 4/5] Prevent users from opening a pad with the wrong app --- www/common/sframe-app-framework.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/www/common/sframe-app-framework.js b/www/common/sframe-app-framework.js index e2a0bd0a2..e5a992343 100644 --- a/www/common/sframe-app-framework.js +++ b/www/common/sframe-app-framework.js @@ -314,11 +314,21 @@ define([ var newPad = false; if (newContentStr === '') { newPad = true; } + var privateDat = cpNfInner.metadataMgr.getPrivateData(); + var type = privateDat.app; + // contentUpdate may be async so we need an nthen here nThen(function (waitFor) { if (!newPad) { var newContent = JSON.parse(newContentStr); - cpNfInner.metadataMgr.updateMetadata(extractMetadata(newContent)); + var metadata = extractMetadata(newContent); + if (metadata && typeof(metadata.type) !== 'undefined' && metadata.type !== type) { + var errorText = Messages.typeError; + UI.errorLoadingScreen(errorText); + waitFor.abort(); + return; + } + cpNfInner.metadataMgr.updateMetadata(metadata); newContent = normalize(newContent); contentUpdate(newContent, waitFor); } else { @@ -356,8 +366,6 @@ define([ UI.removeLoadingScreen(emitResize); - var privateDat = cpNfInner.metadataMgr.getPrivateData(); - var type = privateDat.app; if (AppConfig.textAnalyzer && textContentGetter) { AppConfig.textAnalyzer(textContentGetter, privateDat.channel); } From 337e0bd141361d8d975a5cd1b5ac88df94725fcf Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 22 Aug 2019 14:52:11 +0200 Subject: [PATCH 5/5] update the server's cache whenever we write metadata --- historyKeeper.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/historyKeeper.js b/historyKeeper.js index aced95103..6de09a900 100644 --- a/historyKeeper.js +++ b/historyKeeper.js @@ -721,6 +721,12 @@ module.exports.create = function (cfg) { if (msgCount === 0 && !metadata_cache[channelName] && chan && chan.indexOf(user) > -1) { metadata_cache[channelName] = metadata; + + // the index will have already been constructed and cached at this point + // but it will not have detected any metadata because it hasn't been written yet + // this means that the cache starts off as invalid, so we have to correct it + if (chan && chan.index) { chan.index.metadata = metadata; } + // new channels will always have their metadata written to a dedicated metadata log // but any lines after the first which are not amendments in a particular format will be ignored. // Thus we should be safe from race conditions here if just write metadata to the log as below... @@ -728,6 +734,7 @@ module.exports.create = function (cfg) { // otherwise maybe we need to check that the metadata log is empty as well store.writeMetadata(channelName, JSON.stringify(metadata), function (err) { if (err) { + // XXX tell the user that there was a channel error? return void Log.error('HK_WRITE_METADATA'); } });