From 293e6ae7a2c7d2c88fa699febf94ac47d1f5ec8f Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 8 Apr 2021 12:55:47 +0200 Subject: [PATCH 1/4] Hide maintenance icon when the maintenance is over --- www/common/toolbar.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/www/common/toolbar.js b/www/common/toolbar.js index 07eda5b2e..e2ad32ea6 100644 --- a/www/common/toolbar.js +++ b/www/common/toolbar.js @@ -1045,6 +1045,7 @@ MessengerUI, Messages) { ]), null, true); }); + var to; Common.makeUniversal('broadcast', { onEvent: function (obj) { var cmd = obj.ev; @@ -1053,13 +1054,25 @@ MessengerUI, Messages) { if (!data) { return void $notif.hide(); } + if ((+new Date()) > data.end) { + return void $notif.hide(); + } m = data; + clearTimeout(to); + to = setTimeout(function () { + m = undefined; + $notif.hide(); + }, m.end-(+new Date())); $notif.css('display', ''); } }); if (m && m.start && m.end) { $notif.css('display', ''); + to = setTimeout(function () { + m = undefined; + $notif.hide(); + }, m.end-(+new Date())); } else { $notif.hide(); } From 7f4400961793aedb29da39d84e6773ecb0a0f5ee Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 8 Apr 2021 13:04:12 +0200 Subject: [PATCH 2/4] Better validation function in decrees --- lib/decrees.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/decrees.js b/lib/decrees.js index 9ee294608..09bf1926e 100644 --- a/lib/decrees.js +++ b/lib/decrees.js @@ -129,13 +129,19 @@ commands.SET_ACCOUNT_RETENTION_TIME = makeIntegerSetter('accountRetentionTime'); var args_isString = function (args) { return Array.isArray(args) && typeof(args[0]) === "string"; }; + +// Maintenance: Empty string or an object with a start and end time +var isNumber = function (value) { + return typeof(value) === "number" && !isNaN(value); +}; var args_isMaintenance = function (args) { - return Array.isArray(args) && args[0] && args[0].end && args[0].start; // XXX we could validate that these are numbers && !isNaN + return Array.isArray(args) && args[0] && + (args[0] === "" || (isNumber(args[0].end) && isNumber(args[0].start))); }; -var makeBroadcastSetter = function (attr) { // XXX could pass extra validation here? +var makeBroadcastSetter = function (attr, validation) { return function (Env, args) { - if (!args_isString(args) && !args_isMaintenance(args)) { + if ((validation && !validation(args)) || !args_isString(args)) { throw new Error('INVALID_ARGS'); } var str = args[0]; @@ -154,7 +160,7 @@ commands.SET_SURVEY_URL = makeBroadcastSetter('surveyURL'); // XXX anticipate la // CryptPad_AsyncStore.rpc.send('ADMIN', [ 'ADMIN_DECREE', ['SET_MAINTENANCE', [{start: +Date, end: +Date}]]], console.log) // CryptPad_AsyncStore.rpc.send('ADMIN', [ 'ADMIN_DECREE', ['SET_MAINTENANCE', [""]]], console.log) -commands.SET_MAINTENANCE = makeBroadcastSetter('maintenance'); +commands.SET_MAINTENANCE = makeBroadcastSetter('maintenance', args_isMaintenance); var Quota = require("./commands/quota"); var Keys = require("./keys"); From c43c1a447d520a4f37adb65939cdda7ec75b917e Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 8 Apr 2021 13:18:27 +0200 Subject: [PATCH 3/4] Fix possible memory leak in inner and worker --- www/admin/inner.js | 83 +++++++++++++++++++-------------- www/common/outer/async-store.js | 13 ++++++ 2 files changed, 60 insertions(+), 36 deletions(-) diff --git a/www/admin/inner.js b/www/admin/inner.js index 4642296db..acf7e084f 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -972,6 +972,19 @@ define([ require(['/api/broadcast?'+ (+new Date())], function (Broadcast) { // XXX require.s.contexts._ can be used to erase old loaded objects cb(Broadcast); + setTimeout(function () { + try { + var ctx = require.s.contexts._; + var defined = ctx.defined; + Object.keys(defined).forEach(function (href) { + if (/^\/api\/broadcast\?[0-9]{13}/.test(href)) { + console.error(href); + delete defined[href]; + return; + } + }); + } catch (e) {} + }); }); }; }; @@ -1061,7 +1074,7 @@ define([ var form = h('div.cp-admin-broadcast-form'); var $form = $(form).appendTo($div); - var refresh = getApi(function (/* Broadcast */) { // XXX unused argument + var refresh = getApi(function (Broadcast) { var button = h('button.btn.btn-primary', Messages.admin_broadcastButton); var $button = $(button); var removeButton = h('button.btn.btn-danger', Messages.admin_broadcastCancel); @@ -1071,44 +1084,42 @@ define([ var deleted = []; // Render active message (if there is one) - require(['/api/broadcast?'+ (+new Date())], function (BCast) { - var hash = BCast.lastBroadcastHash || '1'; // Truthy value if no lastKnownHash - common.mailbox.getNotificationsHistory('broadcast', null, hash, function (e, msgs) { - if (e) { return void console.error(e); } - if (!Array.isArray(msgs)) { return; } - if (!msgs.length) { - $active.hide(); + var hash = Broadcast.lastBroadcastHash || '1'; // Truthy value if no lastKnownHash + common.mailbox.getNotificationsHistory('broadcast', null, hash, function (e, msgs) { + if (e) { return void console.error(e); } + if (!Array.isArray(msgs)) { return; } + if (!msgs.length) { + $active.hide(); + } + msgs.reverse().some(function (data) { + var c = data.content; + var msg = c && c.msg; + if (!msg) { return; } + if (msg.type === "BROADCAST_DELETE") { + deleted.push(Util.find(msg, ['content', 'uid'])); } - msgs.reverse().some(function (data) { - var c = data.content; - var msg = c && c.msg; - if (!msg) { return; } - if (msg.type === "BROADCAST_DELETE") { - deleted.push(Util.find(msg, ['content', 'uid'])); - } - if (msg.type !== "BROADCAST_CUSTOM") { return; } - if (deleted.indexOf(msg.uid) !== -1) { return true; } - - // We found an active custom message, show it - var el = common.mailbox.createElement(data); - var table = h('table.cp-broadcast-delete'); - var $table = $(table); - var uid = Util.find(data, ['content', 'msg', 'uid']); - var time = Util.find(data, ['content', 'msg', 'content', 'time']); - var tr = h('tr', { 'data-uid': uid }, [ - h('td', 'ID: '+uid), - h('td', new Date(time || 0).toLocaleString()), - h('td', el), - h('td.delete', removeButton), - ]); - $table.append(tr); - $active.append(table); - activeUid = uid; + if (msg.type !== "BROADCAST_CUSTOM") { return; } + if (deleted.indexOf(msg.uid) !== -1) { return true; } - return true; - }); - if (!activeUid) { $active.hide(); } + // We found an active custom message, show it + var el = common.mailbox.createElement(data); + var table = h('table.cp-broadcast-delete'); + var $table = $(table); + var uid = Util.find(data, ['content', 'msg', 'uid']); + var time = Util.find(data, ['content', 'msg', 'content', 'time']); + var tr = h('tr', { 'data-uid': uid }, [ + h('td', 'ID: '+uid), + h('td', new Date(time || 0).toLocaleString()), + h('td', el), + h('td.delete', removeButton), + ]); + $table.append(tr); + $active.append(table); + activeUid = uid; + + return true; }); + if (!activeUid) { $active.hide(); } }); // Custom message diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 9a6a30faf..a586f26dc 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -630,6 +630,7 @@ define([ // use uid in /api/broadcast so that all connected users will use the same cached // version on the server require(['/api/broadcast?'+uid], function (Broadcast) { + if (!Broadcast) { return; } broadcast([], 'UNIVERSAL_EVENT', { type: 'broadcast', data: { @@ -637,6 +638,18 @@ define([ data: Broadcast.maintenance } }); + setTimeout(function () { + try { + var ctx = require.s.contexts._; + var defined = ctx.defined; + Object.keys(defined).forEach(function (href) { + if (/^\/api\/broadcast\?[a-z0-9]+/.test(href)) { + delete defined[href]; + return; + } + }); + } catch (e) {} + }); }); }; Store.onSurveyUpdate = function (uid) { From 2aadb460b985884468770af250fcb4083c005835 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 8 Apr 2021 13:20:56 +0200 Subject: [PATCH 4/4] Remove some XXX --- www/admin/inner.js | 2 -- www/common/application_config_internal.js | 2 -- www/common/outer/async-store.js | 3 --- www/common/outer/mailbox-handlers.js | 1 - 4 files changed, 8 deletions(-) diff --git a/www/admin/inner.js b/www/admin/inner.js index acf7e084f..beafdf0b1 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -970,7 +970,6 @@ define([ var getApi = function (cb) { return function () { require(['/api/broadcast?'+ (+new Date())], function (Broadcast) { - // XXX require.s.contexts._ can be used to erase old loaded objects cb(Broadcast); setTimeout(function () { try { @@ -978,7 +977,6 @@ define([ var defined = ctx.defined; Object.keys(defined).forEach(function (href) { if (/^\/api\/broadcast\?[0-9]{13}/.test(href)) { - console.error(href); delete defined[href]; return; } diff --git a/www/common/application_config_internal.js b/www/common/application_config_internal.js index 4ac3554cd..7c6ea59bb 100644 --- a/www/common/application_config_internal.js +++ b/www/common/application_config_internal.js @@ -162,8 +162,6 @@ define(function() { // making it much faster to open new tabs. config.disableWorkers = false; - //config.surveyURL = ""; // XXX remove this? - // Teams are always loaded during the initial loading screen (for the first tab only if // SharedWorkers are available). Allowing users to be members of multiple teams can // make them have a very slow loading time. To avoid impacting the user experience diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index a586f26dc..8a892e2f1 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -3169,9 +3169,6 @@ define([ }); }; - Store.newVersionReload = function () { // XXX not used anymore? - broadcast([], "NETWORK_RECONNECT"); - }; Store.disconnect = function () { if (self.accountDeletion) { return; } if (!store.network) { return; } diff --git a/www/common/outer/mailbox-handlers.js b/www/common/outer/mailbox-handlers.js index 7db5a3119..7f7e20d2a 100644 --- a/www/common/outer/mailbox-handlers.js +++ b/www/common/outer/mailbox-handlers.js @@ -687,7 +687,6 @@ define([ // Broadcast - //var broadcasts = {}; // XXX defined but never used ? handlers['BROADCAST_MAINTENANCE'] = function (ctx, box, data, cb) { var msg = data.msg; var uid = msg.uid;