From 3aa2b730bcb8d82abede27840406b3520bbc3ffc Mon Sep 17 00:00:00 2001 From: Andymick Date: Fri, 17 Jul 2026 22:31:40 +0100 Subject: [PATCH] Auto-logout users when page is closed - Create LogoutOnUnload component that triggers logout on page close - Uses beforeunload/unload events with navigator.sendBeacon() for reliability - Create /api/logout endpoint that clears both admin and customer sessions - Add LogoutOnUnload to root layout so it runs on all pages - Works for both admin and customer users Behavior: - When user closes browser tab/window, logout happens automatically - Session cookies are cleared via API endpoint - Improves security by preventing session hijacking from closed windows Co-Authored-By: Claude Haiku 4.5 --- src/app/api/logout/route.ts | 14 ++++++++++++++ src/app/layout.tsx | 2 ++ src/components/LogoutOnUnload.tsx | 27 +++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 src/app/api/logout/route.ts create mode 100644 src/components/LogoutOnUnload.tsx diff --git a/src/app/api/logout/route.ts b/src/app/api/logout/route.ts new file mode 100644 index 0000000..999f1e7 --- /dev/null +++ b/src/app/api/logout/route.ts @@ -0,0 +1,14 @@ +import { cookies } from 'next/headers'; +import { NextResponse } from 'next/server'; + +export async function POST() { + const cookieStore = await cookies(); + + // Clear admin session + cookieStore.delete('adminSession'); + + // Clear customer session + cookieStore.delete('session'); + + return NextResponse.json({ success: true }); +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index e8c5141..f8aefd7 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -6,6 +6,7 @@ import Header from '@/components/Header'; import Footer from '@/components/Footer'; import PromotionBanner from '@/components/PromotionBanner'; import MaintenancePage from '@/components/MaintenancePage'; +import LogoutOnUnload from '@/components/LogoutOnUnload'; import { CurrencyProvider } from '@/lib/CurrencyContext'; import { getSiteSettings } from '@/lib/settings'; import { isAdminAuthenticated } from '@/lib/adminAuth'; @@ -60,6 +61,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo /> + {showMaintenance ? ( diff --git a/src/components/LogoutOnUnload.tsx b/src/components/LogoutOnUnload.tsx new file mode 100644 index 0000000..8d1ecec --- /dev/null +++ b/src/components/LogoutOnUnload.tsx @@ -0,0 +1,27 @@ +'use client'; + +import { useEffect } from 'react'; + +/** + * Logs out the user when they close/leave the page + * Works for both admin and customer sessions + */ +export default function LogoutOnUnload() { + useEffect(() => { + const handleUnload = () => { + // Use sendBeacon to reliably send logout even when page is closing + // This doesn't wait for a response, which is fine for logout + navigator.sendBeacon('/api/logout'); + }; + + window.addEventListener('beforeunload', handleUnload); + window.addEventListener('unload', handleUnload); + + return () => { + window.removeEventListener('beforeunload', handleUnload); + window.removeEventListener('unload', handleUnload); + }; + }, []); + + return null; +}