diff --git a/docs/backlog.md b/docs/backlog.md index 61fa59f..00ca1e6 100644 --- a/docs/backlog.md +++ b/docs/backlog.md @@ -205,8 +205,8 @@ - [x] **TASK-26.5 [Remove OTP Console Log]:** حذف لاگ شدن کد OTP در کنسول سرور جهت جلوگیری از افشای امنیتی. - [ ] **TASK-26.6 [JWT Refresh Token Implementation]:** پیاده‌سازی مکانیزم کامل Refresh Token برای تمدید خودکار نشست کاربر. - [ ] **TASK-26.7 [SSR & HttpOnly Cookie Auth]:** ذخیره توکن‌ها درون HttpOnly Cookie جهت همگام‌سازی کامل Server & Client Components در Next.js. -- [ ] **TASK-26.8 [Logout State Cleanup]:** پاکسازی کامل کاتالوگ، سبد خرید و تمام کش‌های کاربر هنگام خروج (Logout Cleanup). -- [ ] **TASK-26.9 [Admin Token Validation Guard]:** اعتبارسنجی واقعی توکن ادمین در `ProtectedRoute.tsx` از طریق فراخوانی API پروفایل در هنگام لود پنل. +- [x] **TASK-26.8 [Logout State Cleanup]:** پاکسازی کامل کاتالوگ، سبد خرید و تمام کش‌های کاربر هنگام خروج (Logout Cleanup). +- [x] **TASK-26.9 [Admin Token Validation Guard]:** اعتبارسنجی واقعی توکن ادمین در `ProtectedRoute.tsx` از طریق فراخوانی API پروفایل در هنگام لود پنل. - [ ] **TASK-26.10 [Fix Pagination & Search Query Overwrite]:** اصلاح منطق `whereClause` در `products.service.ts` جهت جلوگیری از اوررایت شدن فیلترها. - [ ] **TASK-26.11 [Price Range & Sorting Filters]:** افزودن فیلتر محدوده قیمت (`minPrice`, `maxPrice`) و مرتب‌سازی (`sort`) به DTO و اندپویینت‌های محصولات. - [ ] **TASK-26.12 [Sync Fallback IDs with Database]:** همگام‌سازی شناسه محصولات استاتیک فرانت‌اند با دیتابیس واقعی جهت جلوگیری از 404 در سفارش. diff --git a/frontend/admin-panel/src/components/ProtectedRoute.tsx b/frontend/admin-panel/src/components/ProtectedRoute.tsx index 2fc85db..1bc4dc4 100644 --- a/frontend/admin-panel/src/components/ProtectedRoute.tsx +++ b/frontend/admin-panel/src/components/ProtectedRoute.tsx @@ -1,11 +1,43 @@ +import { useState, useEffect } from 'react'; import { Navigate, Outlet } from 'react-router-dom'; +import api from '../services/api'; export default function ProtectedRoute() { const token = localStorage.getItem('adminToken'); - - if (!token) { + const [isValidating, setIsValidating] = useState(true); + const [isValid, setIsValid] = useState(true); + + useEffect(() => { + if (!token) { + setIsValid(false); + setIsValidating(false); + return; + } + + api.get('/users/profile') + .then(() => { + setIsValid(true); + }) + .catch(() => { + localStorage.removeItem('adminToken'); + setIsValid(false); + }) + .finally(() => { + setIsValidating(false); + }); + }, [token]); + + if (!token || !isValid) { return ; } - + + if (isValidating) { + return ( +
+
+
+ ); + } + return ; } diff --git a/frontend/application/lib/store/userStore.ts b/frontend/application/lib/store/userStore.ts index 8149338..7cb780f 100644 --- a/frontend/application/lib/store/userStore.ts +++ b/frontend/application/lib/store/userStore.ts @@ -164,7 +164,9 @@ export const useUserStore = create()( logout: () => { authService.logout(); try { usePetStore.getState().reset(); } catch {} + try { useCartStore.getState().clearCart(); } catch {} try { localStorage.removeItem("canina-pets"); } catch {} + try { localStorage.removeItem("canina-cart-storage"); } catch {} set({ role: "User_Guest", isLoggedIn: false,