From f0b01827f9137e51cae800dd5b4bc335d88ad73f Mon Sep 17 00:00:00 2001 From: Diljit Date: Wed, 21 May 2025 16:32:19 +0530 Subject: [PATCH] fix: logout user if the session has expired between page switches (#40718) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description If a user's session times out and the user navigates to a new page in an application the user was not navigated to the login page. This change makes sure that the user profile is updated in the redux store on page change and the page response is validated using the response interceptors. This bug was introduced in [this PR](https://github.com/appsmithorg/appsmith/pull/36096). 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="@tag.All" ### :mag: Cypress test results > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: > Commit: a3349cda620d3af78d2604f9edea151f6f15408e > Cypress dashboard. > Tags: `@tag.All` > Spec: >
Wed, 21 May 2025 08:31:39 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No ## Summary by CodeRabbit - **Bug Fixes** - Improved error handling when loading published page resources, ensuring better management of API errors and user profile updates. - **Refactor** - Updated internal handling of API response error codes for consistency. --- app/client/src/api/ApiResponses.tsx | 2 +- app/client/src/ce/sagas/PageSagas.tsx | 35 ++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/app/client/src/api/ApiResponses.tsx b/app/client/src/api/ApiResponses.tsx index b6e0f36d2f..6d40d83ff1 100644 --- a/app/client/src/api/ApiResponses.tsx +++ b/app/client/src/api/ApiResponses.tsx @@ -1,5 +1,5 @@ export interface APIResponseError { - code: string | number; + code: string; message: string; errorType?: string; } diff --git a/app/client/src/ce/sagas/PageSagas.tsx b/app/client/src/ce/sagas/PageSagas.tsx index 145635ac0a..7271fcc293 100644 --- a/app/client/src/ce/sagas/PageSagas.tsx +++ b/app/client/src/ce/sagas/PageSagas.tsx @@ -150,6 +150,10 @@ import { } from "selectors/gitModSelectors"; import { appsmithTelemetry } from "instrumentation"; import { getLayoutSavePayload } from "ee/sagas/helpers"; +import { apiFailureResponseInterceptor } from "api/interceptors/response"; +import type { AxiosError } from "axios"; +import { handleFetchApplicationError } from "./ApplicationSagas"; +import { getCurrentUser } from "actions/authActions"; export interface HandleWidgetNameUpdatePayload { newName: string; @@ -421,13 +425,30 @@ export function* fetchPublishedPageResourcesSaga( // We need to recall consolidated view API in order to fetch actions when page is switched // As in the first call only actions of the current page are fetched // In future, we can reuse this saga to fetch other resources of the page like actionCollections etc - const { publishedActions } = response; + const { pageWithMigratedDsl, publishedActions, userProfile } = response; - yield call( - postFetchedPublishedPage, - response.pageWithMigratedDsl, - pageId, - ); + // Update the current user in the redux store. If the session has expired between page switch, the user profile will be updated + yield put(getCurrentUser(userProfile)); + + // If the pageWithMigratedDsl has an error, we need to intercept the error and return + // This makes sure that the user is navigated to the login page if page is not found + if (pageWithMigratedDsl?.responseMeta?.error) { + const { responseMeta } = pageWithMigratedDsl; + const { status } = responseMeta; + + // apiFailureResponseInterceptor throws an error if the response is not valid + // this error needs to be caught and handled by handleFetchApplicationError + yield apiFailureResponseInterceptor({ + response: { + data: { + responseMeta, + }, + status, + }, + } as AxiosError); + } + + yield call(postFetchedPublishedPage, pageWithMigratedDsl, pageId); // NOTE: fetchActionsForView is used here to update publishedActions in redux store and not to fetch actions again yield put(fetchActionsForView({ applicationId: "", publishedActions })); @@ -437,6 +458,8 @@ export function* fetchPublishedPageResourcesSaga( }); } } catch (error) { + // Handle the error thrown by apiFailureResponseInterceptor + yield call(handleFetchApplicationError, error); yield put({ type: ReduxActionErrorTypes.FETCH_PUBLISHED_PAGE_RESOURCES_ERROR, payload: {