From 041dcbf44ba4d4f5864015577e63e72aa0b9e4d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kruli=C5=A1?= Date: Thu, 5 Feb 2026 17:36:46 +0100 Subject: [PATCH 1/2] Fixing bug with expired token cookie. --- src/redux/middleware/authMiddleware.js | 16 ++++++++++++++++ src/redux/modules/auth.js | 6 +++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/redux/middleware/authMiddleware.js b/src/redux/middleware/authMiddleware.js index f6d9e668d..7b7fd58a6 100644 --- a/src/redux/middleware/authMiddleware.js +++ b/src/redux/middleware/authMiddleware.js @@ -8,6 +8,7 @@ import { setLang } from '../modules/app.js'; import { CALL_API } from './apiMiddleware.js'; import { safeGet, canUseDOM } from '../../helpers/common.js'; import { getConfigVar } from '../../helpers/config.js'; +import { decode, isTokenValid } from '../helpers/token'; const PERSISTENT_TOKENS_KEY_PREFIX = getConfigVar('PERSISTENT_TOKENS_KEY_PREFIX') || 'recodex'; @@ -67,6 +68,19 @@ export const getToken = () => { return null; }; +const checkAccessTokenCookie = token => { + const cookieToken = cookies.get(TOKEN_COOKIES_KEY); + const decodedCookieToken = cookieToken && decode(cookieToken); + if (!decodedCookieToken || !isTokenValid(decodedCookieToken)) { + const decodedToken = token && decode(token); + if (decodedToken && isTokenValid(decodedToken)) { + storeToken(token); + } else { + removeToken(); + } + } +}; + /** * Store instance ID to both local storage and cookies. */ @@ -155,6 +169,8 @@ const middleware = store => next => action => { } } + checkAccessTokenCookie(action.request.accessToken); + break; } diff --git a/src/redux/modules/auth.js b/src/redux/modules/auth.js index b6ea61a1f..3f1c1b9e1 100644 --- a/src/redux/modules/auth.js +++ b/src/redux/modules/auth.js @@ -139,8 +139,8 @@ export const selectInstance = createAction(actionTypes.SELECT_INSTANCE, instance /** * Authentication reducer. - * @param {string} accessToken An access token to initialise the reducer - * @return {function} The initialised reducer + * @param {string} accessToken An access token to initialize the reducer + * @return {function} The initialized reducer */ const auth = (accessToken, instanceId, now = Date.now()) => { const decodedToken = decodeAndValidateAccessToken(accessToken, now); @@ -168,7 +168,7 @@ const auth = (accessToken, instanceId, now = Date.now()) => { [actionTypes.LOGIN_FULFILLED]: (state, { payload: { accessToken, user }, meta: { service, popupWindow } }) => { closeAuthPopupWindow(popupWindow); - return state.getIn(['status', service]) === statusTypes.LOGGING_IN // this should prevent re-login, when explicit logout ocurred whilst refreshing token + return state.getIn(['status', service]) === statusTypes.LOGGING_IN // this should prevent re-login, when explicit logout occurred whilst refreshing token ? state .setIn(['status', service], statusTypes.LOGGED_IN) .deleteIn(['errors', service]) From f3add06ace7f5bfbdeeff6722c323fd6bcf4838e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kruli=C5=A1?= Date: Thu, 5 Feb 2026 18:05:25 +0100 Subject: [PATCH 2/2] Setting token cookie expiration time to token expiration time. --- src/redux/middleware/authMiddleware.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/redux/middleware/authMiddleware.js b/src/redux/middleware/authMiddleware.js index 7b7fd58a6..9cbb20f1a 100644 --- a/src/redux/middleware/authMiddleware.js +++ b/src/redux/middleware/authMiddleware.js @@ -27,8 +27,13 @@ export const storeToken = accessToken => { localStorage.setItem(TOKEN_LOCAL_STORAGE_KEY, accessToken); } - // @todo: expire after 'exp' in the token - cookies.set(TOKEN_COOKIES_KEY, accessToken, { expires: 14 }); // expires after 14 days + const decodedToken = decode(accessToken); + if (decodedToken && isTokenValid(decodedToken)) { + const expDate = new Date(decodedToken.exp * 1000); + cookies.set(TOKEN_COOKIES_KEY, accessToken, { expires: expDate }); // expires with token expiration + } else { + cookies.erase(TOKEN_COOKIES_KEY); + } } };