From 471e4f32ab5e9a5675f757f640f044a46235a292 Mon Sep 17 00:00:00 2001 From: Swapnil Bendal <84583651+Swapnil155@users.noreply.github.com> Date: Thu, 12 Dec 2024 16:19:36 +0530 Subject: [PATCH] [fixed] - token server --- .env.example | 5 +- .../IO_Management/ViewIO/ViewIOTable.jsx | 1 - .../IO_Management/ViewIO/ViewIOdataHeader.jsx | 7 +- src/Services/token.serivce.js | 199 +++++++++--------- 4 files changed, 108 insertions(+), 104 deletions(-) diff --git a/.env.example b/.env.example index 1e085bc..c40434a 100644 --- a/.env.example +++ b/.env.example @@ -14,4 +14,7 @@ VITE_SUPER_ADMIN_ID=1 VITE_BAS_URL="your_base_url" # BaseURL for Images -VITE_IMAGE_URL="your_base_url" \ No newline at end of file +VITE_IMAGE_URL="your_base_url" + +# Max try re-genrate token +VITE_MAX_TRY_REGENRATE_TOKEN=3 \ No newline at end of file diff --git a/src/Pages/IO_Management/ViewIO/ViewIOTable.jsx b/src/Pages/IO_Management/ViewIO/ViewIOTable.jsx index 5dc47ff..7aefcc9 100644 --- a/src/Pages/IO_Management/ViewIO/ViewIOTable.jsx +++ b/src/Pages/IO_Management/ViewIO/ViewIOTable.jsx @@ -97,7 +97,6 @@ const ViewIOTable = () => { skip: debouncedSearchTerm === "" && searchTerm !== "", // Skip if search is empty and it's not the initial request }); - console.log(data); // ===============================[ Table Header ] const tableHeadRow = [ diff --git a/src/Pages/IO_Management/ViewIO/ViewIOdataHeader.jsx b/src/Pages/IO_Management/ViewIO/ViewIOdataHeader.jsx index d68e810..8228d31 100644 --- a/src/Pages/IO_Management/ViewIO/ViewIOdataHeader.jsx +++ b/src/Pages/IO_Management/ViewIO/ViewIOdataHeader.jsx @@ -105,12 +105,7 @@ const ViewIOdataHeader = ({ data, isLoading }) => { fontSize: "0.875rem", fontWeight: "400", }; - - console.log( - import.meta.env.VITE_IMAGE_URL + - IODetails?.artifactsImage?.[0]?.artifactPathName - ); - + const [updateTransaction] = useUpdateTransactionMutation(); const handleDistributionInvestors = async () => { diff --git a/src/Services/token.serivce.js b/src/Services/token.serivce.js index a7ce6d8..6132c26 100644 --- a/src/Services/token.serivce.js +++ b/src/Services/token.serivce.js @@ -1,115 +1,122 @@ import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; import { encryptString } from '../Constants/Constants' -// Define a base query function with token refresh logic +// Define a base query function with token refresh logic, retry mechanism, and AbortController export const baseQuery = async (args, api, extraOptions) => { - let result = await fetchBaseQuery({ - baseUrl: import.meta.env.VITE_BAS_URL, - credentials: 'include', - prepareHeaders: (headers) => { - headers.set('Content-Type', 'application/json',); - return headers; - }, - })(args, api, extraOptions); + const fetchBase = fetchBaseQuery({ + baseUrl: import.meta.env.VITE_BAS_URL, + credentials: 'include', + prepareHeaders: (headers) => { + headers.set('Content-Type', 'application/json'); + return headers; + }, + }); - if (result.error) { - if (result.error.status === 403) { - try { - const { data, error } = await fetchBaseQuery({ - baseUrl: import.meta.env.VITE_BAS_URL, - credentials: 'include', - prepareHeaders: (headers) => { - headers.set('Content-Type', 'application/json',); - return headers; - }, - })( - { - url: "/auth/user/regenerate-token", - method: "POST", - }, - api, - extraOptions - ); + const abortController = new AbortController(); + extraOptions = { + ...extraOptions, + signal: abortController.signal, + }; - if (data) { - return await fetchBaseQuery({ - baseUrl: import.meta.env.VITE_BAS_URL, - credentials: 'include', - prepareHeaders: (headers) => { - headers.set('Content-Type', 'application/json',); - return headers; - } - })(args, api, extraOptions); - } - throw error; - } catch (err) { - console.error("Failed to refresh token:", err); - localStorage.clear(); - window.location.href = '/login'; // Redirect to login page - } - } else if (result.error.status === 401) { - localStorage.clear(); - window.location.href = '/login'; - } - } - return result; + let result = await fetchBase(args, api, extraOptions); + + if (result.error) { + if (result.error.status === 403) { + let retryCount = 0; + const maxRetries = import.meta.env.VITE_MAX_TRY_REGENRATE_TOKEN || 2; + + while (retryCount < maxRetries) { + try { + const { data, error } = await fetchBase( + { + url: "/auth/user/regenerate-token", + method: "POST", + }, + api, + { ...extraOptions, signal: abortController.signal } + ); + if (data) { + // Retry the original query after successful token regeneration + return await fetchBase(args, api, { ...extraOptions, signal: abortController.signal }); + } + + throw error; + } catch (err) { + retryCount++; + if (retryCount >= maxRetries) { + console.error("Failed to refresh token after retries:", err); + abortController.abort(); + localStorage.clear(); + window.location.href = '/login'; // Redirect to login page + break; + } + } + } + } else if (result.error.status === 401) { + abortController.abort(); + localStorage.clear(); + window.location.href = '/login'; + } + } + + return result; }; // Create an RTK Query API slice export const apiSlice = createApi({ - reducerPath: "api", - baseQuery: baseQuery, - tagTypes: ["authProfile"], - endpoints: (builder) => ({ + reducerPath: "api", + baseQuery: baseQuery, + tagTypes: ["authProfile"], + endpoints: (builder) => ({ - login: builder.mutation({ - query: (credentials) => ({ - url: "/auth/admin", - method: "POST", - body: credentials, - }), - async onQueryStarted(arg, { queryFulfilled }) { - try { - const { data } = await queryFulfilled; - localStorage.setItem("role", encryptString(data?.data?.role)); - } catch (error) { - console.error("Login failed:", error); - } - }, - }), + login: builder.mutation({ + query: (credentials) => ({ + url: "/auth/admin", + method: "POST", + body: credentials, + }), + async onQueryStarted(arg, { queryFulfilled }) { + try { + const { data } = await queryFulfilled; + localStorage.setItem("role", encryptString(data?.data?.role)); + } catch (error) { + console.error("Login failed:", error); + } + }, + }), - refreshToken: builder.mutation({ - query: (refreshToken) => ({ - url: "/auth/user/regenerate-token", - method: "POST", - body: { refreshToken }, - }), - }), + refreshToken: builder.mutation({ + query: (refreshToken) => ({ + url: "/auth/user/regenerate-token", + method: "POST", + body: { refreshToken }, + }), + }), - logout: builder.mutation({ - query: () => ({ - url: "/auth/admin/logout", - method: "POST", - }), - }), + logout: builder.mutation({ + query: () => ({ + url: "/auth/admin/logout", + method: "POST", + }), + }), - authProfile: builder.query({ - query: () => `/auth/admin/profile`, - providesTags: (result) => result ? [{ type: 'Auth', id: 'profile' }] : [], - onQueryStarted: async (args, { queryFulfilled }) => { - try { - const { data } = await queryFulfilled; // Get the data from the query response - if (data?.role) { - localStorage.setItem('role', encryptString(data.role)); - } - } catch (error) { - console.error('Error setting role in localStorage:', error); - } - }, - }), + authProfile: builder.query({ + query: () => `/auth/admin/profile`, + providesTags: (result) => result ? [{ type: 'Auth', id: 'profile' }] : [], + onQueryStarted: async (args, { queryFulfilled }) => { + try { + const { data } = await queryFulfilled; // Get the data from the query response + if (data?.role) { + localStorage.setItem('role', encryptString(data.role)); + } + } catch (error) { + console.error('Error setting role in localStorage:', error); + } + }, + }), - }), + }), }); export const { useLoginMutation, useRefreshTokenMutation, useLogoutMutation, useAuthProfileQuery } = apiSlice;