From bb6dbcc8d49f33270fa5f1ebd1eeb7c6926da0c3 Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Tue, 17 Aug 2021 14:51:09 +0100 Subject: [PATCH] Ensure iframe is cleared on log out - on auth/logout ensure the iframe is removed instead of waiting for the timer - solution probably over implemented, but wanted to ensure timer is also cleared on logout --- components/EmberPage.vue | 30 +++++++++--------------------- store/auth.js | 3 +++ utils/ember-page.js | 30 ++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 utils/ember-page.js diff --git a/components/EmberPage.vue b/components/EmberPage.vue index c8b6af9081..83206bcbd6 100644 --- a/components/EmberPage.vue +++ b/components/EmberPage.vue @@ -4,18 +4,12 @@ import { mapGetters, mapState } from 'vuex'; import { NAME as MANAGER } from '@/config/product/manager'; import { CAPI, MANAGEMENT } from '@/config/types'; import { SETTING } from '@/config/settings'; +import { findEmberPage, clearEmberInactiveTimer, startEmberInactiveTimer, EMBER_FRAME } from '@/utils/ember-page'; -const EMBER_FRAME = 'ember-iframe'; const EMBER_FRAME_HIDE_CLASS = 'ember-iframe-hidden'; const PAGE_CHECK_TIMEOUT = 30000; const WINDOW_MANAGER = 'windowmanager'; -// Remove the IFrame if the user has not used an embedded page after this time -// since last visiting an embedded page -const INACTIVITY_CHECK_TIMEOUT = 60000; - -let inactiveRemoveTimer = null; - // Pages that we should intercept when loaded in the IFRAME and instead // navigate to a page in Cluster Dashboard // exmample if the Ember clusters page that is navigated to when the user presses cancel on some pages @@ -111,7 +105,7 @@ export default { this.syncSize(); } else { clearTimeout(this.heightSync); - const iframeEl = document.getElementById(EMBER_FRAME); + const iframeEl = findEmberPage(); // Reset the height when the window manager is closed this.heightSync = null; @@ -127,7 +121,7 @@ export default { mounted() { // Embedded page visited, so cancel time to remove IFRAME when inactive - clearTimeout(inactiveRemoveTimer); + clearEmberInactiveTimer(); window.addEventListener('message', this.receiveMessage); this.initFrame(); }, @@ -140,7 +134,7 @@ export default { } if (this.inline) { - const iframeEl = document.getElementById(EMBER_FRAME); + const iframeEl = findEmberPage(); // Remove the IFRAME - we can't reuse it one its been moved inline if (iframeEl) { @@ -159,13 +153,7 @@ export default { } // Set up a timer to remove the IFrame after a period of inactivity - inactiveRemoveTimer = setTimeout(() => { - const iframeEl = document.getElementById(EMBER_FRAME); - - if (iframeEl !== null) { - iframeEl.remove(); - } - }, INACTIVITY_CHECK_TIMEOUT); + startEmberInactiveTimer(); }, methods: { @@ -202,7 +190,7 @@ export default { this.loadRequired = false; // Get the existing iframe if it exists - let iframeEl = document.getElementById(EMBER_FRAME); + let iframeEl = findEmberPage(); // If the iframe already exists, check if it is ready for us to reuse // by navigating within the app that is already loaded @@ -320,7 +308,7 @@ export default { dosyncSize() { if (this.inline) { - const iframeEl = document.getElementById(EMBER_FRAME); + const iframeEl = findEmberPage(); const doc = iframeEl.contentWindow.document; const app = doc.getElementById('application'); const h = app?.offsetHeight; @@ -346,7 +334,7 @@ export default { if (wmh !== this.wmHeight) { // Adjust the bottom - const iframeEl = document.getElementById(EMBER_FRAME); + const iframeEl = findEmberPage(); iframeEl.style.height = `calc(100vh - var(--header-height) - ${ wmh }px)`; this.wmHeight = wmh; @@ -356,7 +344,7 @@ export default { }, notifyTheme(theme) { - const iframeEl = document.getElementById(EMBER_FRAME); + const iframeEl = findEmberPage(); if (iframeEl) { const emberTheme = theme === 'light' ? 'ui-light' : 'ui-dark'; diff --git a/store/auth.js b/store/auth.js index 1bed0bad49..ddce346e22 100644 --- a/store/auth.js +++ b/store/auth.js @@ -3,6 +3,7 @@ import { NORMAN } from '@/config/types'; import { addObjects, findBy } from '@/utils/array'; import { openAuthPopup, returnTo } from '@/utils/auth'; import { base64Encode } from '@/utils/crypto'; +import { removeEmberPage } from '@/utils/ember-page'; import { randomStr } from '@/utils/string'; import { addParams, parse as parseUrl, removeParam } from '@/utils/url'; @@ -315,6 +316,8 @@ export const actions = { } catch (e) { } + removeEmberPage(); + commit('loggedOut'); dispatch('onLogout', null, { root: true }); } diff --git a/utils/ember-page.js b/utils/ember-page.js new file mode 100644 index 0000000000..e1e3eb89d0 --- /dev/null +++ b/utils/ember-page.js @@ -0,0 +1,30 @@ + +export const EMBER_FRAME = 'ember-iframe'; +let inactiveRemoveTimer; + +// Remove the IFrame if the user has not used an embedded page after this time +// since last visiting an embedded page +const INACTIVITY_CHECK_TIMEOUT = 60000; + +export function findEmberPage() { + return document.getElementById(EMBER_FRAME); +} + +export function clearEmberInactiveTimer() { + clearTimeout(inactiveRemoveTimer); +} + +export function startEmberInactiveTimer() { + if (findEmberPage() !== null) { + inactiveRemoveTimer = setTimeout(removeEmberPage, INACTIVITY_CHECK_TIMEOUT); + } +} + +export function removeEmberPage() { + const iframeEl = findEmberPage(); + + if (iframeEl !== null) { + iframeEl.remove(); + clearEmberInactiveTimer(); + } +}