From 22321a7ac996d160f29b4eb471ea606d13e3bb7f Mon Sep 17 00:00:00 2001 From: ISA Date: Mon, 8 Sep 2025 07:08:59 +0200 Subject: [PATCH] =?UTF-8?q?Admin=20User=20nach=20einer=20Zeit=20von=20eine?= =?UTF-8?q?r=20Stunde=20l=C3=B6schen=20(Cookie=20oder=20Local=20Storrage)?= =?UTF-8?q?=20,=20automatisch=20abmelden?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 2 +- .env.production | 2 +- CHANGELOG.md | 5 ++ components/header/Header.tsx | 59 ++++++++++++++++++- .../UserManagementSettings.tsx | 15 ++++- package-lock.json | 4 +- package.json | 2 +- 7 files changed, 80 insertions(+), 9 deletions(-) diff --git a/.env.development b/.env.development index f6f7f61..bb67e0d 100644 --- a/.env.development +++ b/.env.development @@ -6,6 +6,6 @@ NEXT_PUBLIC_USE_MOCK_BACKEND_LOOP_START=false NEXT_PUBLIC_EXPORT_STATIC=false NEXT_PUBLIC_USE_CGI=false # App-Versionsnummer -NEXT_PUBLIC_APP_VERSION=1.6.855 +NEXT_PUBLIC_APP_VERSION=1.6.856 NEXT_PUBLIC_CPL_MODE=json # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter) diff --git a/.env.production b/.env.production index 38ed96b..14d6a12 100644 --- a/.env.production +++ b/.env.production @@ -5,5 +5,5 @@ NEXT_PUBLIC_CPL_API_PATH=/CPL NEXT_PUBLIC_EXPORT_STATIC=true NEXT_PUBLIC_USE_CGI=true # App-Versionsnummer -NEXT_PUBLIC_APP_VERSION=1.6.855 +NEXT_PUBLIC_APP_VERSION=1.6.856 NEXT_PUBLIC_CPL_MODE=production \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 0259c61..ef1fc76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## [1.6.856] – 2025-09-08 + +- chore: Jenkinsfile + +--- ## [1.6.855] – 2025-09-05 - fix: allow scripts in woodpecker diff --git a/components/header/Header.tsx b/components/header/Header.tsx index 81f706b..4458bcf 100644 --- a/components/header/Header.tsx +++ b/components/header/Header.tsx @@ -1,5 +1,5 @@ "use client"; // components/Header.jsx -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useRef, useCallback } from "react"; import { Icon } from "@iconify/react"; import Image from "next/image"; import { useRouter } from "next/router"; @@ -15,16 +15,18 @@ function Header() { const router = useRouter(); const [showSettingsModal, setShowSettingsModal] = useState(false); const [isAdminLoggedIn, setIsAdminLoggedIn] = useState(false); + const autoLogoutTimerRef = useRef | null>(null); // Removed duplicate declaration of deviceName const handleCloseSettingsModal = () => setShowSettingsModal(false); - const handleLogout = () => { + const handleLogout = useCallback(() => { sessionStorage.removeItem("token"); // Token entfernen localStorage.setItem("isAdminLoggedIn", "false"); // Admin-Status entfernen + localStorage.removeItem("adminLoginTime"); // Login-Zeitpunkt entfernen setIsAdminLoggedIn(false); // Zustand sofort aktualisieren router.push("/offline.html"); // Weiterleitung - }; + }, [router]); useEffect(() => { // Initialer Check beim Laden der Komponente @@ -43,6 +45,56 @@ function Header() { clearInterval(interval); // Intervall stoppen, wenn die Komponente entladen wird }; }, [isAdminLoggedIn]); + + // Auto-Logout nach 1 Minute (Test): nutzt adminLoginTime aus localStorage + useEffect(() => { + // Timer bereinigen, wenn sich der Status ändert + if (autoLogoutTimerRef.current) { + clearTimeout(autoLogoutTimerRef.current); + autoLogoutTimerRef.current = null; + } + + if (!isAdminLoggedIn) return; + + const iso = localStorage.getItem("adminLoginTime"); + const loginTime = iso ? new Date(iso).getTime() : Date.now(); + if (!iso) { + // Falls älterer Login ohne Zeitstempel, setze jetzt + try { + localStorage.setItem( + "adminLoginTime", + new Date(loginTime).toISOString() + ); + } catch { + void 0; // ignore write errors (e.g., storage disabled) + } + } + + // 1 Minute ab Login (60_000 ms), eine Stunde (3_600_000 ms) im Produktivbetrieb + const target = loginTime + 3_600_000; + const delay = Math.max(0, target - Date.now()); + + // Fallback: wenn Datum in Vergangenheit (z.B. Uhrzeit geändert), sofort abmelden + autoLogoutTimerRef.current = setTimeout(() => { + // Versuche den Button zu klicken, falls vorhanden + const btn = document.querySelector( + 'button[aria-label="Abmelden"]' + ); + if (btn) { + btn.click(); + } else { + // Fallback direkt + handleLogout(); + } + }, delay); + + return () => { + if (autoLogoutTimerRef.current) { + clearTimeout(autoLogoutTimerRef.current); + autoLogoutTimerRef.current = null; + } + }; + }, [isAdminLoggedIn, handleLogout]); //---------------------------------------------------------------- const dispatch = useDispatch(); @@ -139,6 +191,7 @@ function Header() {
diff --git a/package-lock.json b/package-lock.json index a68813d..ec0fb7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cpl-v4", - "version": "1.6.855", + "version": "1.6.856", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cpl-v4", - "version": "1.6.855", + "version": "1.6.856", "dependencies": { "@fontsource/roboto": "^5.1.0", "@headlessui/react": "^2.2.4", diff --git a/package.json b/package.json index 840927e..6d7d3ba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cpl-v4", - "version": "1.6.855", + "version": "1.6.856", "private": true, "scripts": { "dev": "next dev -p 3000",