From 4645bde0250d4a9cb476c01757d9f119a4cf6a35 Mon Sep 17 00:00:00 2001 From: llpingll <94099281+llpingll@users.noreply.github.com> Date: Sun, 25 Jan 2026 15:19:21 +0000 Subject: [PATCH] Allow all users to change password and handle expired sessions --- client/package-lock.json | 2 +- .../Pages/Account/components/PasswordPanel.jsx | 16 ++++++++++++++-- client/src/Pages/Account/index.jsx | 2 +- client/src/locales/en.json | 2 +- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 7f5397b7f..282ab2611 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -38,7 +38,7 @@ "react-toastify": "^10.0.5", "recharts": "2.15.2", "redux-persist": "6.0.0", - "swr": "2.3.6", + "swr": "^2.3.6", "vite-plugin-svgr": "^4.2.0", "zod": "4.1.11" }, diff --git a/client/src/Pages/Account/components/PasswordPanel.jsx b/client/src/Pages/Account/components/PasswordPanel.jsx index f54c61a16..f06555dcd 100644 --- a/client/src/Pages/Account/components/PasswordPanel.jsx +++ b/client/src/Pages/Account/components/PasswordPanel.jsx @@ -11,6 +11,8 @@ import { useDispatch, useSelector } from "react-redux"; import { createToast } from "../../../Utils/toastUtils.jsx"; import { getTouchedFieldErrors } from "../../../Validation/error.js"; import { useTranslation } from "react-i18next"; +import { useNavigate } from "react-router-dom"; +import { clearAuthState } from "../../../Features/Auth/authSlice.js"; const defaultPasswordsState = { password: "", @@ -28,11 +30,12 @@ const PasswordPanel = () => { const theme = useTheme(); const dispatch = useDispatch(); const { t } = useTranslation(); + const navigate = useNavigate(); const SPACING_GAP = theme.spacing(12); //redux state - const { isLoading } = useSelector((state) => state.auth); + const { isLoading, authToken } = useSelector((state) => state.auth); const idToName = { "edit-current-password": "password", @@ -79,6 +82,16 @@ const PasswordPanel = () => { const handleSubmit = async (event) => { event.preventDefault(); + // Check for expired/invalid token before submitting + if (!authToken) { + createToast({ + body: t("passwordPanel.sessionExpired", "Your session has expired. Please log in again."), + }); + dispatch(clearAuthState()); + navigate("/login"); + return; + } + const { error } = newOrChangedCredentials.validate(localData, { abortEarly: false, context: { password: localData.newPassword }, @@ -105,7 +118,6 @@ const PasswordPanel = () => { confirm: "", }); } else { - // TODO: Check for other errors? createToast({ body: t( "passwordPanel.passwordInputIncorrect", diff --git a/client/src/Pages/Account/index.jsx b/client/src/Pages/Account/index.jsx index ae16ff9d7..3bf480336 100644 --- a/client/src/Pages/Account/index.jsx +++ b/client/src/Pages/Account/index.jsx @@ -85,7 +85,7 @@ const Account = ({ open = "profile" }) => { ))} - {user.role.includes("superadmin") && } + {!hideTeams && } diff --git a/client/src/locales/en.json b/client/src/locales/en.json index de02815b1..7e5eb7092 100644 --- a/client/src/locales/en.json +++ b/client/src/locales/en.json @@ -555,7 +555,7 @@ "enterNewPassword": "Enter your new password", "confirmNewPassword": "Confirm new password", "passwordRequirements": "New password must contain at least 8 characters and must have at least one uppercase letter, one lowercase letter, one number and one special character (!?@#$%^&*()-_=+[]{}|;:'\",./\\~`).", - "saving": "Saving..." + "sessionExpired": "Your session has expired, please log in again to continue." }, "emailSent": "Email sent successfully", "failedToSendEmail": "Failed to send email",