From 92d1310bca1243af8fc43c4e0e5a8d6adcbeb2be Mon Sep 17 00:00:00 2001 From: ISA Date: Sun, 17 Nov 2024 13:46:09 +0100 Subject: [PATCH 1/7] feat: Token in SessionStorage gespeichert und Passwort gehasht MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Admin-Token wird nun in SessionStorage anstelle von LocalStorage gespeichert. - Passwort für Admin-Benutzer ist jetzt mit bcrypt gehasht. - Verbesserte Sicherheit durch die Verwendung von SessionStorage (Daten werden beim Schließen des Tabs gelöscht). - Anpassung von Funktionen zur Token-Verwaltung für SessionStorage. --- .../modales/settingsModal/SettingsModal.jsx | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/components/modales/settingsModal/SettingsModal.jsx b/components/modales/settingsModal/SettingsModal.jsx index 244b160..991bc11 100644 --- a/components/modales/settingsModal/SettingsModal.jsx +++ b/components/modales/settingsModal/SettingsModal.jsx @@ -11,12 +11,16 @@ import handleSubmit from "./handlers/handleSubmit"; import { useRouter } from "next/router"; import { setAdminLoggedIn } from "../../../store/authSlice"; import { useDispatch } from "react-redux"; +import bcrypt from "bcryptjs"; ReactModal.setAppElement("#__next"); - const USERS = { - Admin: { username: "admin", password: "admin", role: "Admin" }, - Ismail: { username: "ismail", password: "ismail", role: "Admin" }, + Admin: { + username: "admin", + // Gehashte Version von "admin" mit bcrypt + password: "$2a$10$xpq/.tcOJN/LXfzdCcCVrenlBh2nRlM1R1ISY7dd1q2qGWC9Fyd2G", + role: "Admin", + }, }; // Function to generate JWT token function generateToken(user) { @@ -38,24 +42,23 @@ function SettingModal({ showModal, onClose }) { const [showLoginForm, setShowLoginForm] = useState(false); // Zustand für Login-Formular const router = useRouter(); - const handleAdminLogin = (e) => { + function handleAdminLogin(e) { e.preventDefault(); - const user = Object.values(USERS).find( - (u) => u.username === username && u.password === password - ); - - if (user) { - const token = generateToken(user); - localStorage.setItem("token", token); - dispatch(setAdminLoggedIn(true)); - setShowLoginForm(false); - onClose(); - } else { - setError( - "Login fehlgeschlagen. Bitte überprüfen Sie Benutzername und Passwort." - ); - } - }; + const user = USERS.Admin; // Finde den Admin-Benutzer + bcrypt.compare(password, user.password, (err, isMatch) => { + if (isMatch) { + const token = generateToken(user); + sessionStorage.setItem("token", token); // Speichere Token in SessionStorage + dispatch(setAdminLoggedIn(true)); + setShowLoginForm(false); + onClose(); + } else { + setError( + "Login fehlgeschlagen. Bitte überprüfen Sie Benutzername und Passwort." + ); + } + }); + } const deviceName_Redux = useSelector((state) => state.variables.deviceName); const mac1_Redux = useSelector((state) => state.variables.mac1); const ip_Redux = useSelector((state) => state.variables.ip); From ade87db2cf374abaccb4b68d4bc021e49b209bd9 Mon Sep 17 00:00:00 2001 From: ISA Date: Mon, 18 Nov 2024 07:58:55 +0100 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20Entfernen=20der=20Redux-Abh=C3=A4ng?= =?UTF-8?q?igkeit=20f=C3=BCr=20Admin-Login=20in=20der=20Header-Komponente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Redux-State durch lokalen useState für `isAdminLoggedIn` ersetzt. - Token-Validierung über sessionStorage mit useEffect hinzugefügt. - Alle Redux-Selectoren entfernt und unnötige Importe bereinigt. - Verbesserte Fehlerbehandlung bei der Token-Verarbeitung, um Abstürze zu vermeiden. - Logout-Funktionalität vereinfacht, indem sessionStorage direkt geleert wird. --- components/Header.jsx | 29 +++++++++++++----------- components/modales/kueModal/KueModal.jsx | 2 +- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/components/Header.jsx b/components/Header.jsx index 46f5b16..af4be78 100644 --- a/components/Header.jsx +++ b/components/Header.jsx @@ -4,33 +4,36 @@ import Image from "next/image"; import { useRouter } from "next/router"; import "bootstrap-icons/font/bootstrap-icons.css"; import SettingsModal from "./modales/settingsModal/SettingsModal"; -import { useSelector } from "react-redux"; function Header() { - const isAdminLoggedIn = useSelector((state) => state.auth.isAdminLoggedIn); const router = useRouter(); - const deviceName = useSelector((state) => state.variables.deviceName); const [showSettingsModal, setShowSettingsModal] = useState(false); - //const [isAdminLoggedIn, setIsAdminLoggedIn] = useState(false); + const [isAdminLoggedIn, setIsAdminLoggedIn] = useState(false); // Lokaler Zustand + const deviceName = "Station XY"; // Dummy-Daten, da Redux entfernt wurde const handleSettingsClick = () => setShowSettingsModal(true); const handleCloseSettingsModal = () => setShowSettingsModal(false); const handleLogout = () => { - localStorage.removeItem("token"); // Token entfernen beim Abmelden - //setIsAdminLoggedIn(false); + sessionStorage.removeItem("token"); // Token entfernen beim Abmelden + setIsAdminLoggedIn(false); // Admin-Status zurücksetzen window.location.href = "/offline.html"; }; // Funktion, um den Token-Status zu prüfen useEffect(() => { - const token = localStorage.getItem("token"); + const token = sessionStorage.getItem("token"); if (token) { - const { exp } = JSON.parse(atob(token)); - if (Date.now() < exp) { - //setIsAdminLoggedIn(true); - } else { - localStorage.removeItem("token"); // Entferne abgelaufenen Token - //setIsAdminLoggedIn(false); + try { + const { exp } = JSON.parse(atob(token)); + if (Date.now() < exp) { + setIsAdminLoggedIn(true); // Admin eingeloggt + } else { + sessionStorage.removeItem("token"); // Entferne abgelaufenen Token + setIsAdminLoggedIn(false); + } + } catch (error) { + console.error("Fehler beim Verarbeiten des Tokens:", error); + setIsAdminLoggedIn(false); } } }, []); diff --git a/components/modales/kueModal/KueModal.jsx b/components/modales/kueModal/KueModal.jsx index ffa0051..dd7d2b7 100644 --- a/components/modales/kueModal/KueModal.jsx +++ b/components/modales/kueModal/KueModal.jsx @@ -97,7 +97,7 @@ function KueModal({ showModal, onClose, slot, onModulNameChange }) { }, [showModal]); // nur von showModal abhängig ansonsten wird alle 10 Sekunden die Werte zurückgesetzt in Modal //------------------------------------------------------------------------------------------------------------ useEffect(() => { - const token = localStorage.getItem("token"); + const token = sessionStorage.getItem("token"); if (token) { const decoded = decodeToken(token); if (decoded && decoded.role === "Admin") { From 15584e12fbc5569cb3bb2dca689fd597a33a6e92 Mon Sep 17 00:00:00 2001 From: ISA Date: Mon, 18 Nov 2024 13:20:46 +0100 Subject: [PATCH 3/7] Admi-Modus noch nicht fertig --- components/Header.jsx | 3 ++- .../modales/settingsModal/SettingsModal.jsx | 19 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/components/Header.jsx b/components/Header.jsx index af4be78..75a5f1c 100644 --- a/components/Header.jsx +++ b/components/Header.jsx @@ -4,12 +4,13 @@ import Image from "next/image"; import { useRouter } from "next/router"; import "bootstrap-icons/font/bootstrap-icons.css"; import SettingsModal from "./modales/settingsModal/SettingsModal"; +import { useSelector } from "react-redux"; function Header() { const router = useRouter(); const [showSettingsModal, setShowSettingsModal] = useState(false); const [isAdminLoggedIn, setIsAdminLoggedIn] = useState(false); // Lokaler Zustand - const deviceName = "Station XY"; // Dummy-Daten, da Redux entfernt wurde + const deviceName = useSelector((state) => state.variables.deviceName); const handleSettingsClick = () => setShowSettingsModal(true); const handleCloseSettingsModal = () => setShowSettingsModal(false); diff --git a/components/modales/settingsModal/SettingsModal.jsx b/components/modales/settingsModal/SettingsModal.jsx index 991bc11..89d91b6 100644 --- a/components/modales/settingsModal/SettingsModal.jsx +++ b/components/modales/settingsModal/SettingsModal.jsx @@ -9,8 +9,7 @@ import handleReboot from "./handlers/handleReboot"; import handleSetDateTime from "./handlers/handleSetDateTime"; import handleSubmit from "./handlers/handleSubmit"; import { useRouter } from "next/router"; -import { setAdminLoggedIn } from "../../../store/authSlice"; -import { useDispatch } from "react-redux"; + import bcrypt from "bcryptjs"; ReactModal.setAppElement("#__next"); @@ -33,12 +32,12 @@ function generateToken(user) { } function SettingModal({ showModal, onClose }) { - const isAdminLoggedIn = useSelector((state) => state.auth.isAdminLoggedIn); - const dispatch = useDispatch(); + const [isAdminLoggedIn, setAdminLoggedIn] = useState(false); + //const isAdminLoggedIn = sessionStorage.getItem("token"); + const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [error, setError] = useState(""); - const [isLoggedIn, setIsLoggedIn] = useState(false); const [showLoginForm, setShowLoginForm] = useState(false); // Zustand für Login-Formular const router = useRouter(); @@ -49,7 +48,7 @@ function SettingModal({ showModal, onClose }) { if (isMatch) { const token = generateToken(user); sessionStorage.setItem("token", token); // Speichere Token in SessionStorage - dispatch(setAdminLoggedIn(true)); + setShowLoginForm(false); onClose(); } else { @@ -99,7 +98,6 @@ function SettingModal({ showModal, onClose }) { }; const handleAdminLogout = () => { localStorage.removeItem("token"); // Remove token on logout - dispatch(setAdminLoggedIn(false)); // Update Redux state }; useEffect(() => { @@ -143,13 +141,14 @@ function SettingModal({ showModal, onClose }) { ]); useEffect(() => { // Check if a valid token exists in localStorage - const token = localStorage.getItem("token"); + const token = sessionStorage.getItem("token"); if (token) { + setAdminLoggedIn(true); const { exp } = JSON.parse(atob(token)); if (Date.now() < exp) { - setIsLoggedIn(true); + setAdminLoggedIn(true); } else { - localStorage.removeItem("token"); // Remove expired token + // localStorage.removeItem("token"); // Remove expired token } } }, []); From be7c769de80c7f98be3d9b72579e91ed3cbf4335 Mon Sep 17 00:00:00 2001 From: ISA Date: Mon, 18 Nov 2024 14:08:33 +0100 Subject: [PATCH 4/7] =?UTF-8?q?fix:=20goTDR=20und=20goLoop=20modul=208=20u?= =?UTF-8?q?nd=209=20f=C3=BChrende=20Nullen=20entfernt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/modules/Kue705FO.jsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/components/modules/Kue705FO.jsx b/components/modules/Kue705FO.jsx index 19a2b51..4874b3c 100644 --- a/components/modules/Kue705FO.jsx +++ b/components/modules/Kue705FO.jsx @@ -92,7 +92,8 @@ function Kue705FO({ return; } - let slotFormat = slot < 10 ? `0${slot}` : `${slot}`; + // Entfernt führende Nullen, falls vorhanden + let slotFormat = slot < 10 ? `${parseInt(slot, 10)}` : `${slot}`; setLoading(true); // Setze den Ladezustand auf true alert(`Schleifenmessung wird für Slot ${slot + 1} gestartet...`); @@ -115,6 +116,7 @@ function Kue705FO({ }) .finally(() => setLoading(false)); // Ladezustand zurücksetzen }; + // Funktion für die TDR-Messung const goTDR = () => { //------------------------------------------------- @@ -124,7 +126,8 @@ function Kue705FO({ return; } - let slotFormat = slot < 10 ? `0${slot}` : `${slot}`; + // Entfernt führende Nullen, falls vorhanden + let slotFormat = slot < 10 ? `${parseInt(slot, 10)}` : `${slot}`; setLoading(true); alert(`TDR wird für Slot ${slot + 1} gestartet...`); From ed80aa38a8546d175f943143630781cd64ef3c6a Mon Sep 17 00:00:00 2001 From: ISA Date: Mon, 18 Nov 2024 20:43:43 +0100 Subject: [PATCH 5/7] fix: Echtzeit-Aktualisierung des Admin-Status implementiert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Intervall-basierte Überprüfung von `localStorage` hinzugefügt, um Änderungen am Admin-Status (`isAdminLoggedIn`) sofort zu synchronisieren. - Zustand `isAdminLoggedIn` wird nun direkt nach Login/Logout aktualisiert. - Weiterleitung zu `/offline.html` nach Logout integriert. - Problem behoben, dass "Admin-Modus aktiv" erst nach einem Neuladen angezeigt wurde. --- components/Header.jsx | 69 ++++++++++++------- .../modales/settingsModal/SettingsModal.jsx | 4 +- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/components/Header.jsx b/components/Header.jsx index 75a5f1c..61cc3d9 100644 --- a/components/Header.jsx +++ b/components/Header.jsx @@ -9,35 +9,43 @@ import { useSelector } from "react-redux"; function Header() { const router = useRouter(); const [showSettingsModal, setShowSettingsModal] = useState(false); - const [isAdminLoggedIn, setIsAdminLoggedIn] = useState(false); // Lokaler Zustand + const [isAdminLoggedIn, setIsAdminLoggedIn] = useState(false); const deviceName = useSelector((state) => state.variables.deviceName); const handleSettingsClick = () => setShowSettingsModal(true); const handleCloseSettingsModal = () => setShowSettingsModal(false); + const handleLogout = () => { - sessionStorage.removeItem("token"); // Token entfernen beim Abmelden - setIsAdminLoggedIn(false); // Admin-Status zurücksetzen - window.location.href = "/offline.html"; + sessionStorage.removeItem("token"); // Token entfernen + localStorage.setItem("isAdminLoggedIn", "false"); // Admin-Status entfernen + setIsAdminLoggedIn(false); // Zustand sofort aktualisieren + router.push("/offline.html"); // Weiterleitung + }; + + const handleLogin = () => { + const token = JSON.stringify({ exp: Date.now() + 5 * 60 * 1000 }); // Beispiel-Token mit 5 Minuten Ablaufzeit + sessionStorage.setItem("token", token); // Token speichern + localStorage.setItem("isAdminLoggedIn", "true"); // Admin-Status setzen + setIsAdminLoggedIn(true); // Zustand sofort aktualisieren }; - // Funktion, um den Token-Status zu prüfen useEffect(() => { - const token = sessionStorage.getItem("token"); - if (token) { - try { - const { exp } = JSON.parse(atob(token)); - if (Date.now() < exp) { - setIsAdminLoggedIn(true); // Admin eingeloggt - } else { - sessionStorage.removeItem("token"); // Entferne abgelaufenen Token - setIsAdminLoggedIn(false); - } - } catch (error) { - console.error("Fehler beim Verarbeiten des Tokens:", error); - setIsAdminLoggedIn(false); + // Initialer Check beim Laden der Komponente + const isAdmin = localStorage.getItem("isAdminLoggedIn") === "true"; + setIsAdminLoggedIn(isAdmin); + + // Beobachten von Änderungen in localStorage + const interval = setInterval(() => { + const updatedIsAdmin = localStorage.getItem("isAdminLoggedIn") === "true"; + if (updatedIsAdmin !== isAdminLoggedIn) { + setIsAdminLoggedIn(updatedIsAdmin); } - } - }, []); + }, 500); // Überprüfung alle 500ms + + return () => { + clearInterval(interval); // Intervall stoppen, wenn die Komponente entladen wird + }; + }, [isAdminLoggedIn]); return (
@@ -70,12 +78,21 @@ function Header() {
- + {!isAdminLoggedIn ? ( + + ) : ( + + )}
diff --git a/components/modales/settingsModal/SettingsModal.jsx b/components/modales/settingsModal/SettingsModal.jsx index 89d91b6..ece7f37 100644 --- a/components/modales/settingsModal/SettingsModal.jsx +++ b/components/modales/settingsModal/SettingsModal.jsx @@ -48,6 +48,7 @@ function SettingModal({ showModal, onClose }) { if (isMatch) { const token = generateToken(user); sessionStorage.setItem("token", token); // Speichere Token in SessionStorage + localStorage.setItem("isAdminLoggedIn", "true"); setShowLoginForm(false); onClose(); @@ -97,7 +98,8 @@ function SettingModal({ showModal, onClose }) { active, }; const handleAdminLogout = () => { - localStorage.removeItem("token"); // Remove token on logout + sessionStorage.removeItem("token"); // Token aus sessionStorage entfernen + localStorage.setItem("isAdminLoggedIn", "false"); // Admin-Status im localStorage setzen }; useEffect(() => { From dc4a6d6fad7594fe7b3bac5b3ec979dd67a5945d Mon Sep 17 00:00:00 2001 From: ISA Date: Tue, 19 Nov 2024 18:55:17 +0100 Subject: [PATCH 6/7] Anmelden ein Header entfernt --- components/Header.jsx | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/components/Header.jsx b/components/Header.jsx index 61cc3d9..3eb2b98 100644 --- a/components/Header.jsx +++ b/components/Header.jsx @@ -78,21 +78,12 @@ function Header() {
- {!isAdminLoggedIn ? ( - - ) : ( - - )} +
From f0d8ad4bdf109d879fd79b54609f81eac9341ae8 Mon Sep 17 00:00:00 2001 From: ISA Date: Mon, 20 Jan 2025 12:12:19 +0100 Subject: [PATCH 7/7] Webserverversion: 1.0.5.0 --- pages/dashboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/dashboard.js b/pages/dashboard.js index 5869042..4b1cfc8 100644 --- a/pages/dashboard.js +++ b/pages/dashboard.js @@ -177,7 +177,7 @@ function Dashboard() {

- Webserverversion: 1.0.4 + Webserverversion: 1.0.5.0