67 lines
2.2 KiB
TypeScript
67 lines
2.2 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useRef } from "react";
|
|
import { useRouter } from "next/navigation";
|
|
|
|
const INACTIVITY_TIMEOUT_MS = 2 * 60 * 60 * 1000; // 2 Stunden
|
|
const WARNING_BEFORE_LOGOUT_MS = 15 * 60 * 1000; // 15 Minuten vor Logout warnen
|
|
|
|
export function SessionTimeoutProvider({ children }: { children: React.ReactNode }) {
|
|
const router = useRouter();
|
|
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
|
|
const warningTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
|
const warningShownRef = useRef<boolean>(false);
|
|
const lastActivityRef = useRef<number>(Date.now());
|
|
|
|
function resetTimeout() {
|
|
// Alte Timer löschen
|
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
if (warningTimeoutRef.current) clearTimeout(warningTimeoutRef.current);
|
|
|
|
lastActivityRef.current = Date.now();
|
|
warningShownRef.current = false;
|
|
|
|
// Warnung nach (TIMEOUT - 15min)
|
|
warningTimeoutRef.current = setTimeout(() => {
|
|
if (!warningShownRef.current) {
|
|
warningShownRef.current = true;
|
|
alert(
|
|
"⚠️ Ihre Session läuft in 15 Minuten ab. " +
|
|
"Bitte klicken Sie auf eine Taste oder bewegen Sie die Maus, um weiterzuarbeiten."
|
|
);
|
|
}
|
|
}, INACTIVITY_TIMEOUT_MS - WARNING_BEFORE_LOGOUT_MS);
|
|
|
|
// Logout nach TIMEOUT
|
|
timeoutRef.current = setTimeout(async () => {
|
|
// Session auf dem Server beenden
|
|
await fetch("/api/admin/login", { method: "DELETE" });
|
|
// Redirect zur Login-Seite mit Hinweis
|
|
router.push("/admin/login?session_expired=true");
|
|
}, INACTIVITY_TIMEOUT_MS);
|
|
}
|
|
|
|
useEffect(() => {
|
|
const events = ["mousedown", "keydown", "scroll", "touchstart"];
|
|
|
|
function handleActivity() {
|
|
resetTimeout();
|
|
}
|
|
|
|
// Event-Listener registrieren
|
|
events.forEach((event) => window.addEventListener(event, handleActivity));
|
|
|
|
// Initial timeout setzen
|
|
resetTimeout();
|
|
|
|
// Cleanup
|
|
return () => {
|
|
events.forEach((event) => window.removeEventListener(event, handleActivity));
|
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
if (warningTimeoutRef.current) clearTimeout(warningTimeoutRef.current);
|
|
};
|
|
}, [router]);
|
|
|
|
return <>{children}</>;
|
|
}
|