From 2ad9ced644f7fee9d03902ae9a0f9f9ebfab6165 Mon Sep 17 00:00:00 2001 From: Patrick Varkoi Date: Thu, 24 Sep 2026 17:29:55 +0300 Subject: [PATCH 1/2] Add Auth refresh functionality and middleware investigation - Implement AuthRefreshTest component for manual testing of auth refresh - Integrate useRefreshAuthMutation in authApi and expose it - Add README for authentication refresh investigation detailing current implementation and middleware findings - Create tests for the refreshAuth mutation and React hook --- .../admin/_components/AuthRefreshTest.tsx | 55 +++++++++++++++++++ .../src/app/[lng]/(helper)/admin/page.tsx | 3 + .../src/entities/Auth/index.ts | 1 + .../src/entities/Auth/middlewares/README.md | 15 +++++ .../src/entities/Auth/model/authApi.test.ts | 13 +++++ .../src/entities/Auth/model/authApi.ts | 14 ++++- 6 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 frontend-next-migration/src/app/[lng]/(helper)/admin/_components/AuthRefreshTest.tsx create mode 100644 frontend-next-migration/src/entities/Auth/middlewares/README.md create mode 100644 frontend-next-migration/src/entities/Auth/model/authApi.test.ts diff --git a/frontend-next-migration/src/app/[lng]/(helper)/admin/_components/AuthRefreshTest.tsx b/frontend-next-migration/src/app/[lng]/(helper)/admin/_components/AuthRefreshTest.tsx new file mode 100644 index 000000000..200b5524d --- /dev/null +++ b/frontend-next-migration/src/app/[lng]/(helper)/admin/_components/AuthRefreshTest.tsx @@ -0,0 +1,55 @@ +'use client'; +import { useState } from 'react'; +import { useSelector } from 'react-redux'; +import { + selectAuthUserState, + useRefreshAuthMutation, + AccessTokenInfoResponse, + AuthUserSchema, +} from '@/entities/Auth'; +import { LS_KEYS } from '@/shared/const/LS_KEYS'; + +const AuthRefreshTest = () => { + const [refreshAuth, { isLoading, error }] = useRefreshAuthMutation(); + const authUser = useSelector((state: { authUser: AuthUserSchema }) => + selectAuthUserState(state), + ); + const [response, setResponse] = useState(null); + const [storedAuthUser, setStoredAuthUser] = useState(null); + + const handleRefresh = async () => { + try { + const refreshResponse = await refreshAuth().unwrap(); + setResponse(refreshResponse); + setStoredAuthUser(localStorage.getItem(LS_KEYS.AUTH_USER)); + } catch { + setResponse(null); + setStoredAuthUser(localStorage.getItem(LS_KEYS.AUTH_USER)); + } + }; + + return ( +
+

Auth refresh test

+
+ + {error &&
{JSON.stringify(error, null, 2)}
} + {response &&
{JSON.stringify(response, null, 2)}
} +
+

Redux auth state

+
{JSON.stringify(authUser, null, 2)}
+
+

localStorage AuthUser after request

+
{storedAuthUser ?? 'No localStorage snapshot yet'}
+
+
+ ); +}; + +export default AuthRefreshTest; diff --git a/frontend-next-migration/src/app/[lng]/(helper)/admin/page.tsx b/frontend-next-migration/src/app/[lng]/(helper)/admin/page.tsx index a11f237b2..97c107cc6 100644 --- a/frontend-next-migration/src/app/[lng]/(helper)/admin/page.tsx +++ b/frontend-next-migration/src/app/[lng]/(helper)/admin/page.tsx @@ -10,6 +10,7 @@ import NewsCardsGrid from './_components/NewsCardsGrid'; import DescriptionCardsSection from './_components/DescriptionCardsSection'; import MobileCardsGrid from './_components/MobileCardsGrid'; import BarIndicatorBlock from '@/app/[lng]/(helper)/admin/_components/BarIndicatorBlock'; +import AuthRefreshTest from './_components/AuthRefreshTest'; import useSizes from '@/shared/lib/hooks/useSizes'; import hannu from '@/shared/assets/images/heros/hannu-hodari/hannu-hodari.png'; import vihapuhe from '@/shared/assets/images/heros/hate-speech/Vihapuhe.png'; @@ -48,6 +49,8 @@ const Page = () => { component: , }} > + + diff --git a/frontend-next-migration/src/entities/Auth/index.ts b/frontend-next-migration/src/entities/Auth/index.ts index dcd356159..0cbd1f73a 100644 --- a/frontend-next-migration/src/entities/Auth/index.ts +++ b/frontend-next-migration/src/entities/Auth/index.ts @@ -1,6 +1,7 @@ export type { IUserRegisterDto, IUserLoginDto, + IRefreshAuthDto, IPlayerRegisterPartDto, AuthUserSchema, ILoginResponse, diff --git a/frontend-next-migration/src/entities/Auth/middlewares/README.md b/frontend-next-migration/src/entities/Auth/middlewares/README.md index 8321f377e..56905b635 100644 --- a/frontend-next-migration/src/entities/Auth/middlewares/README.md +++ b/frontend-next-migration/src/entities/Auth/middlewares/README.md @@ -2,7 +2,7 @@ ## Current implementation -`authApi.ts` exposes `refreshAuth` as a no-argument `POST /auth/refresh` mutation. It returns `AccessTokenInfoResponse`, matching the token-only response shape already used by the auth types. The mutation is intentionally not called by production authentication code yet. +`authApi.ts` exposes `refreshAuth` as a `POST /auth/refresh` mutation with the required `{ refreshToken }` JSON body. It returns `AccessTokenInfoResponse`, containing the new access and refresh tokens. The mutation is intentionally not called by production authentication code yet. The admin page contains a manual probe at `/{lng}/admin`. It displays the refresh response, the current Redux auth state, and an `AuthUser` localStorage snapshot after the request. This makes it possible to verify the backend contract without changing the normal login flow. diff --git a/frontend-next-migration/src/entities/Auth/model/authApi.ts b/frontend-next-migration/src/entities/Auth/model/authApi.ts index 28daf49c4..e57f60a1f 100644 --- a/frontend-next-migration/src/entities/Auth/model/authApi.ts +++ b/frontend-next-migration/src/entities/Auth/model/authApi.ts @@ -2,6 +2,7 @@ import { gameApi } from '@/shared/api'; import { IUserRegisterDto, IUserLoginDto, + IRefreshAuthDto, ILoginResponse, AccessTokenInfoResponse, } from '../types/authUser'; @@ -28,10 +29,11 @@ const authApi = gameApi.injectEndpoints({ method: 'POST', }), }), - refreshAuth: builder.mutation({ - query: () => ({ + refreshAuth: builder.mutation({ + query: (refreshAuthDto) => ({ url: '/auth/refresh', method: 'POST', + body: refreshAuthDto, }), }), }), diff --git a/frontend-next-migration/src/entities/Auth/types/authUser.d.ts b/frontend-next-migration/src/entities/Auth/types/authUser.d.ts index 2c8b5f67b..12a5b56f9 100644 --- a/frontend-next-migration/src/entities/Auth/types/authUser.d.ts +++ b/frontend-next-migration/src/entities/Auth/types/authUser.d.ts @@ -14,12 +14,17 @@ export type IUserRegisterDto = Pick, 'username'> & { export type IUserLoginDto = Pick, 'username'> & { password: string }; +export type IRefreshAuthDto = { + refreshToken: string; +}; + export type ILoginResponse = IProfile & { accessToken: string; }; export type AccessTokenInfoResponse = { accessToken: string; + refreshToken: string; accessTokenExpiresInSecIn: number; };