From c8a49414b1eca26fb0bd8a859edc429e5459bff7 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Wed, 7 Nov 2018 10:26:22 +0100 Subject: [PATCH] js: Append a unique container id to the Window-Id Generates a semi-random id for containers other than the menu and col1. This id is then appended to the Window-Id of every request separated by an underscore: `window-id_container-id` refs #3609 --- public/js/icinga/loader.js | 7 ++++++- public/js/icinga/ui.js | 28 +++++++++++++++++++++++++++- public/js/icinga/utils.js | 31 +++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/public/js/icinga/loader.js b/public/js/icinga/loader.js index aaccf683b..d57a0f15e 100644 --- a/public/js/icinga/loader.js +++ b/public/js/icinga/loader.js @@ -107,7 +107,12 @@ // Ask for a new window id in case we don't already have one if (this.icinga.ui.hasWindowId()) { - headers['X-Icinga-WindowId'] = this.icinga.ui.getWindowId(); + var windowId = this.icinga.ui.getWindowId(); + var containerId = this.icinga.ui.getUniqueContainerId($target); + if (containerId) { + windowId = windowId + '_' + containerId; + } + headers['X-Icinga-WindowId'] = windowId; } else { headers['X-Icinga-WindowId'] = 'undefined'; } diff --git a/public/js/icinga/ui.js b/public/js/icinga/ui.js index b0932621a..aba660d5c 100644 --- a/public/js/icinga/ui.js +++ b/public/js/icinga/ui.js @@ -196,7 +196,8 @@ 'data-icinga-url': $col.data('icingaUrl'), 'data-icinga-refresh': $col.data('icingaRefresh'), 'data-last-update': $col.data('lastUpdate'), - 'data-icinga-module': $col.data('icingaModule') + 'data-icinga-module': $col.data('icingaModule'), + 'data-icinga-container-id': $col.data('icingaContainerId') }, 'class': $col.attr('class') }; @@ -205,6 +206,7 @@ $col.removeData('icingaRefresh'); $col.removeData('lastUpdate'); $col.removeData('icingaModule'); + $col.removeData('icingaContainerId'); $col.removeAttr('class').attr('class', 'container'); return props; }, @@ -216,6 +218,7 @@ $col.data('icingaRefresh', backup['data']['data-icinga-refresh']); $col.data('lastUpdate', backup['data']['data-last-update']); $col.data('icingaModule', backup['data']['data-icinga-module']); + $col.data('icingaContainerId', backup['data']['data-icinga-container-id']); }, triggerWindowResize: function () { @@ -692,6 +695,29 @@ this.fixControls(); }, + getUniqueContainerId: function ($cont) { + if (typeof $cont === 'undefined' || !$cont.length) { + return null; + } + + var containerId = $cont.data('icingaContainerId'); + if (typeof containerId === 'undefined') { + /** + * Only generate an id if it's not for col1 or the menu (which are using the non-suffixed window id). + * This is based on the assumption that the server only knows about the menu and first column + * and therefore does not need to protect its ids. (As the menu is most likely part of the sidebar) + */ + if ($cont.attr('id') === 'menu' || $cont.attr('id') === 'col1') { + return null; + } + + containerId = this.icinga.utils.generateId(6); // Random because the content may move + $cont.data('icingaContainerId', containerId); + } + + return containerId; + }, + getWindowId: function () { if (! this.hasWindowId()) { return undefined; diff --git a/public/js/icinga/utils.js b/public/js/icinga/utils.js index 8c69485e1..962d02c42 100644 --- a/public/js/icinga/utils.js +++ b/public/js/icinga/utils.js @@ -404,6 +404,37 @@ str = padding + str; } return str; + }, + + /** + * Shuffle a string + * + * @param {String} str The string to shuffle + * + * @returns {String} The shuffled string + */ + shuffleString: function(str) { + var a = str.split(""), + n = a.length; + + for(var i = n - 1; i > 0; i--) { + var j = Math.floor(Math.random() * (i + 1)); + var tmp = a[i]; + a[i] = a[j]; + a[j] = tmp; + } + return a.join(""); + }, + + /** + * Generate an id + * + * @param {Number} len The desired length of the id + * + * @returns {String} The id + */ + generateId: function(len) { + return this.shuffleString('abcefghijklmnopqrstuvwxyz').substr(0, len); } };