From 3e7b933382cf02123ba8b5799110501a397d2a62 Mon Sep 17 00:00:00 2001 From: Trisha Anand Date: Tue, 25 Mar 2025 16:48:49 +0530 Subject: [PATCH] chore: Client side changes to send organizationId in verify email flow (#39898) ## Description > [!TIP] > _Add a TL;DR when the description is longer than 500 words or extremely technical (helps the content, marketing, and DevRel team)._ > > _Please also include relevant motivation and context. List any dependencies that are required for this change. Add links to Notion, Figma or any other documents that might be relevant to the PR._ Fixes #`Issue Number` _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ ## Automation /ok-to-test tags="" ### :mag: Cypress test results > [!WARNING] > Tests have not run on the HEAD a1634ecc781f96fe87cdfb59a6bb0f9dda054abd yet >
Tue, 25 Mar 2025 09:26:39 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No ## Summary by CodeRabbit - **New Features** - Introduced a session token validation step during initialization to ensure the app handles token issues gracefully. - Enhanced error management during startup, allowing the app to continue loading smoothly even if session token validation encounters problems. - Added a dedicated utility for managing session tokens extracted from URL parameters. - Expanded the `VerifyUser` component to accept an additional `organizationId` property for improved user authentication. --------- Co-authored-by: Albin --- app/client/src/pages/UserAuth/VerifyUser.tsx | 1 + app/client/src/sagas/InitSagas.ts | 10 +++++ app/client/src/utils/SessionUtils.ts | 42 ++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 app/client/src/utils/SessionUtils.ts diff --git a/app/client/src/pages/UserAuth/VerifyUser.tsx b/app/client/src/pages/UserAuth/VerifyUser.tsx index 8800a8e60e..81e669c49d 100644 --- a/app/client/src/pages/UserAuth/VerifyUser.tsx +++ b/app/client/src/pages/UserAuth/VerifyUser.tsx @@ -13,6 +13,7 @@ const VerifyUser = ( email: string; token: string; redirectUrl: string; + organizationId: string; }>, ) => { const queryParams = new URLSearchParams(props.location.search); diff --git a/app/client/src/sagas/InitSagas.ts b/app/client/src/sagas/InitSagas.ts index 3b3f635ec9..edf4e42df0 100644 --- a/app/client/src/sagas/InitSagas.ts +++ b/app/client/src/sagas/InitSagas.ts @@ -92,6 +92,7 @@ import { import type { ApplicationPayload } from "entities/Application"; import type { Page } from "entities/Page"; import type { PACKAGE_PULL_STATUS } from "ee/constants/ModuleConstants"; +import { validateSessionToken } from "utils/SessionUtils"; export const URL_CHANGE_ACTIONS = [ ReduxActionTypes.CURRENT_APPLICATION_NAME_UPDATE, @@ -462,6 +463,15 @@ function* appEngineSaga(action: ReduxAction) { } function* eagerPageInitSaga() { + try { + // Validate session token if present + yield call(validateSessionToken); + } catch (error) { + // Log error but don't block the rest of the initialization + log.error("Error validating session token:", error); + Sentry.captureException(error); + } + const url = window.location.pathname; const search = window.location.search; diff --git a/app/client/src/utils/SessionUtils.ts b/app/client/src/utils/SessionUtils.ts new file mode 100644 index 0000000000..7855b68ea1 --- /dev/null +++ b/app/client/src/utils/SessionUtils.ts @@ -0,0 +1,42 @@ +import Api from "api/Api"; +import type { ApiResponse } from "api/types"; + +export const SESSION_TOKEN_PARAM = "sessionToken"; + +/** + * Validates a session token from the URL and sets up the session. + * This is used during cross-domain session transfers. + * + * @returns A promise that resolves to true if the session was validated successfully + */ +export const validateSessionToken = async (): Promise => { + try { + const urlParams = new URLSearchParams(window.location.search); + const sessionToken = urlParams.get("sessionToken"); + + if (!sessionToken) { + return false; + } + + // Get the response from the API + const response = (await Api.get( + `v1/session/validate?sessionToken=${sessionToken}`, + )) as unknown as ApiResponse; + + // Check if the request was successful + if (!response?.responseMeta?.success) { + return false; + } + + // Remove the session token from the URL + const url = new URL(window.location.href); + + url.searchParams.delete("sessionToken"); + window.history.replaceState({}, "", url.toString()); + + // The data field contains the boolean result directly + return !!response.data; + } catch (error) { + return false; + } +};