From bfe6b5b480bf5aa2e1e0a0773589c5c6ef6c1c80 Mon Sep 17 00:00:00 2001 From: Shekar Siri Date: Fri, 27 Oct 2023 11:23:54 +0200 Subject: [PATCH] fix(ui): iframe and jwt behaviour --- frontend/app/Router.js | 82 ++++++++++++++------------- frontend/app/constants/storageKeys.ts | 3 +- frontend/app/utils/index.ts | 40 +++++++++++++ 3 files changed, 85 insertions(+), 40 deletions(-) diff --git a/frontend/app/Router.js b/frontend/app/Router.js index 0082dbe09..8394dbc0f 100644 --- a/frontend/app/Router.js +++ b/frontend/app/Router.js @@ -18,9 +18,10 @@ import Signup from 'Components/Signup'; import { fetchTenants, setJwt } from 'Duck/user'; import { setSessionPath } from 'Duck/sessions'; import { ModalProvider } from './components/Modal'; -import { GLOBAL_DESTINATION_PATH, GLOBAL_HAS_NO_RECORDINGS, IFRAME } from 'App/constants/storageKeys'; +import { GLOBAL_DESTINATION_PATH, GLOBAL_HAS_NO_RECORDINGS, IFRAME, JWT_PARAM } from 'App/constants/storageKeys'; import SupportCallout from 'Shared/SupportCallout'; import NotFoundPage from 'Shared/NotFoundPage'; +import { checkParam } from 'App/utils'; const Login = lazy(() => import('Components/Login/Login')); const ForgotPassword = lazy(() => import('Components/ForgotPassword/ForgotPassword')); @@ -130,29 +131,16 @@ class Router extends React.Component { this.fetchInitialData(); } - const urlJWT = new URLSearchParams(window.location.search).get('jwt'); - - if (urlJWT && !props.isLoggedIn) { - props.setJwt(urlJWT) - } - this.state = { - isIframe: this.checkIframe(), + isIframe: checkParam('iframe', IFRAME), + isJwt: checkParam('jwt', JWT_PARAM) }; - } - checkIframe = () => { - const urlParams = new URLSearchParams(window.location.search); - const iframe = urlParams.get('iframe'); - - if (iframe && iframe === 'true') { - localStorage.setItem(IFRAME, true); - return true; - } else { - localStorage.removeItem(IFRAME); - return false; + const urlJWT = new URLSearchParams(window.location.search).get('jwt'); + if (urlJWT && !props.isLoggedIn) { + props.setJwt(urlJWT); } - }; + } fetchInitialData = async () => { const siteIdFromPath = parseInt(window.location.pathname.split('/')[1]); @@ -189,7 +177,7 @@ class Router extends React.Component { destinationPath !== routes.login() && destinationPath !== '/' ) { - history.push(destinationPath + window.location.search); + this.props.history.push(destinationPath + window.location.search); } if (!prevProps.isLoggedIn && this.props.isLoggedIn) { @@ -221,28 +209,44 @@ class Router extends React.Component { || isRoute(MULTIVIEW_INDEX_PATH, location.pathname); const redirectToOnboarding = !onboarding && localStorage.getItem(GLOBAL_HAS_NO_RECORDINGS) === 'true'; - const { isIframe } = this.state; + const { isIframe, isJwt } = this.state; + + const renderAuthenticatedIframeRoutes = () => ( + + + }> + + + + + + + + + ); + + const renderUnauthenticatedIframeRoutes = () => ( + }> + + + + + + + {!isEnterprise && } + + ); if (isIframe) { if (isLoggedIn) { - return ( - - - }> - - - - - - - - - ); - } else { - return ( - - ); + return renderAuthenticatedIframeRoutes(); } + + if (isJwt) { + return ; + } + + return renderUnauthenticatedIframeRoutes(); } return isLoggedIn ? ( diff --git a/frontend/app/constants/storageKeys.ts b/frontend/app/constants/storageKeys.ts index 9406d38b9..c07f9c9a3 100644 --- a/frontend/app/constants/storageKeys.ts +++ b/frontend/app/constants/storageKeys.ts @@ -7,4 +7,5 @@ export const GLOBAL_HAS_NO_RECORDINGS = "__$global-hasNoRecordings$__" export const SITE_ID_STORAGE_KEY = "__$user-siteId$__" export const GETTING_STARTED = "__$user-gettingStarted$__" export const MOUSE_TRAIL = "__$session-mouseTrail$__" -export const IFRAME = "__$session-iframe$__" \ No newline at end of file +export const IFRAME = "__$session-iframe$__" +export const JWT_PARAM = "__$session-jwt-param$__" \ No newline at end of file diff --git a/frontend/app/utils/index.ts b/frontend/app/utils/index.ts index 47b40aa70..42fe50029 100644 --- a/frontend/app/utils/index.ts +++ b/frontend/app/utils/index.ts @@ -426,3 +426,43 @@ export function deleteCookie(name: string, path: string, domain: string) { (domain ? ';domain=' + domain : '') + ';expires=Thu, 01 Jan 1970 00:00:01 GMT'; } + +/** + * Checks if a specified query parameter exists in the URL and if its value is set to 'true'. + * If a storageKey is provided, stores the result in localStorage under that key. + * + * @function + * @param {string} paramName - The name of the URL parameter to check. + * @param {string} [storageKey] - The optional key to use for storing the result in localStorage. + * @returns {boolean} - Returns true if the parameter exists and its value is 'true'. Otherwise, returns false. + * + * @example + * // Assuming URL is: http://example.com/?iframe=true + * const isIframeEnabled = checkParam('iframe'); // Returns true, doesn't store in localStorage + * const isIframeEnabledWithStorage = checkParam('iframe', 'storageKey'); // Returns true, stores in localStorage + * + * @description + * The function inspects the current URL's query parameters. If the specified parameter exists + * and its value is set to 'true', and a storageKey is provided, the function stores 'true' under + * the provided storage key in the localStorage. If the condition is not met, or if the parameter + * does not exist, and a storageKey is provided, any existing localStorage entry with the storageKey + * is removed. + */ +export const checkParam = (paramName: string, storageKey?: string): boolean => { + const urlParams = new URLSearchParams(window.location.search); + const paramValue = urlParams.get(paramName); + + const existsAndTrue = paramValue && paramValue === 'true' || paramValue?.length > 0; + + if (storageKey) { + if (existsAndTrue) { + localStorage.setItem(storageKey, 'true'); + } else { + localStorage.removeItem(storageKey); + } + } + + return existsAndTrue; +}; + +