فهرست منبع

feat: Auto-logout on session expiry

- Add useSessionExpiry hook that listens for 'baas:session-expired' event
- When session expires, automatically logout and redirect to login
- Show session expiry message on login page via navigation state
Fszontagh 3 روز پیش
والد
کامیت
8e26a46c4f
2فایلهای تغییر یافته به همراه47 افزوده شده و 2 حذف شده
  1. 32 1
      src/App.tsx
  2. 15 1
      src/pages/LoginPage.tsx

+ 32 - 1
src/App.tsx

@@ -1,4 +1,5 @@
-import { Routes, Route, Navigate } from 'react-router-dom';
+import { useEffect, useCallback } from 'react';
+import { Routes, Route, Navigate, useNavigate } from 'react-router-dom';
 import { useAuth } from '@picobaas/client/react';
 import Layout from './components/Layout';
 import HomePage from './pages/HomePage';
@@ -10,6 +11,33 @@ import ImageDetailPage from './pages/ImageDetailPage';
 import SharedImagePage from './pages/SharedImagePage';
 import ImageAnalyticsPage from './pages/ImageAnalyticsPage';
 
+// Hook to handle session expiry - auto logout when session expires
+function useSessionExpiry() {
+  const { logout, isAuthenticated } = useAuth();
+  const navigate = useNavigate();
+
+  const handleSessionExpired = useCallback(async (event: Event) => {
+    const customEvent = event as CustomEvent<{ reason: string }>;
+    console.warn('Session expired:', customEvent.detail?.reason);
+
+    // Only handle if user was authenticated
+    if (isAuthenticated) {
+      await logout();
+      navigate('/login', {
+        replace: true,
+        state: { message: 'Your session has expired. Please log in again.' }
+      });
+    }
+  }, [logout, navigate, isAuthenticated]);
+
+  useEffect(() => {
+    window.addEventListener('baas:session-expired', handleSessionExpired);
+    return () => {
+      window.removeEventListener('baas:session-expired', handleSessionExpired);
+    };
+  }, [handleSessionExpired]);
+}
+
 // Protected route wrapper
 function ProtectedRoute({ children }: { children: React.ReactNode }) {
   const { isAuthenticated, isLoading } = useAuth();
@@ -30,6 +58,9 @@ function ProtectedRoute({ children }: { children: React.ReactNode }) {
 }
 
 function App() {
+  // Auto-logout when session expires
+  useSessionExpiry();
+
   return (
     <Routes>
       {/* Public routes */}

+ 15 - 1
src/pages/LoginPage.tsx

@@ -1,16 +1,25 @@
 import { useState } from 'react';
-import { Link, useNavigate } from 'react-router-dom';
+import { Link, useNavigate, useLocation } from 'react-router-dom';
 import { useAuth } from '@picobaas/client/react';
 import LoadingSpinner from '../components/LoadingSpinner';
 
+interface LocationState {
+  message?: string;
+}
+
 export default function LoginPage() {
   const navigate = useNavigate();
+  const location = useLocation();
   const { login, isAuthenticated } = useAuth();
   const [email, setEmail] = useState('');
   const [password, setPassword] = useState('');
   const [error, setError] = useState<string | null>(null);
   const [isLoading, setIsLoading] = useState(false);
 
+  // Get session expiry message from navigation state
+  const locationState = location.state as LocationState | null;
+  const sessionMessage = locationState?.message;
+
   // Redirect if already authenticated
   if (isAuthenticated) {
     navigate('/dashboard', { replace: true });
@@ -49,6 +58,11 @@ export default function LoginPage() {
 
         <div className="card p-6">
           <form onSubmit={handleSubmit} className="space-y-4">
+            {sessionMessage && (
+              <div className="p-3 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg text-amber-700 dark:text-amber-400 text-sm">
+                {sessionMessage}
+              </div>
+            )}
             {error && (
               <div className="p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg text-red-700 dark:text-red-400 text-sm">
                 {error}