add password change functionality with frontend integration

This commit is contained in:
2025-09-03 14:50:35 +02:00
parent a24b2697b0
commit 68f13f369c
4 changed files with 72 additions and 0 deletions

View File

@@ -19,6 +19,7 @@ import {
deleteItemID, deleteItemID,
createItem, createItem,
changeUserPassword, changeUserPassword,
changeUserPasswordFRONTEND,
} from "../services/database.js"; } from "../services/database.js";
import { authenticate, generateToken } from "../services/tokenService.js"; import { authenticate, generateToken } from "../services/tokenService.js";
const router = express.Router(); const router = express.Router();
@@ -176,6 +177,21 @@ router.post("/createLoan", authenticate, async (req, res) => {
} }
}); });
router.post("/changePassword", authenticate, async (req, res) => {
const { oldPassword, newPassword } = req.body || {};
const username = req.user.username;
const result = await changeUserPasswordFRONTEND(
username,
oldPassword,
newPassword
);
if (result.success) {
res.status(200).json({ message: "Password changed successfully" });
} else {
res.status(500).json({ message: "Failed to change password" });
}
});
// Admin panel functions // Admin panel functions
router.post("/loginAdmin", async (req, res) => { router.post("/loginAdmin", async (req, res) => {

View File

@@ -413,3 +413,16 @@ export const changeUserPassword = async (username, newPassword) => {
if (result.affectedRows > 0) return { success: true }; if (result.affectedRows > 0) return { success: true };
return { success: false }; return { success: false };
}; };
export const changeUserPasswordFRONTEND = async (
username,
oldPassword,
newPassword
) => {
const [result] = await pool.query(
"UPDATE users SET password = ? WHERE username = ? AND password = ?",
[newPassword, username, oldPassword]
);
if (result.affectedRows > 0) return { success: true };
return { success: false };
};

View File

@@ -1,10 +1,27 @@
import React from "react"; import React from "react";
import { changePW } from "../utils/userHandler";
import { myToast } from "../utils/toastify";
type HeaderProps = { type HeaderProps = {
onLogout: () => void; onLogout: () => void;
}; };
const Header: React.FC<HeaderProps> = ({ onLogout }) => { const Header: React.FC<HeaderProps> = ({ onLogout }) => {
const passwordForm = () => {
const oldPW = window.prompt("Altes Passwort");
const newPW = window.prompt("Neues Passwort");
const repeatNewPW = window.prompt("Neues Passwort wiederholen");
if (oldPW && newPW && repeatNewPW) {
if (newPW === repeatNewPW) {
changePW(oldPW, newPW);
} else {
myToast("Die neuen Passwörter stimmen nicht überein.", "error");
}
} else {
myToast("Bitte alle Felder ausfüllen.", "error");
}
};
return ( return (
<header className="mb-4 sm:mb-6"> <header className="mb-4 sm:mb-6">
<div className="flex items-start justify-between gap-3"> <div className="flex items-start justify-between gap-3">
@@ -33,6 +50,13 @@ const Header: React.FC<HeaderProps> = ({ onLogout }) => {
Source Code Source Code
</button> </button>
</a> </a>
<button
type="button"
onClick={passwordForm}
className="h-9 px-3 rounded-md border border-slate-300 text-slate-700 hover:bg-slate-100 transition"
>
Passwort ändern
</button>
</div> </div>
</header> </header>
); );

View File

@@ -137,3 +137,22 @@ export const onTake = async (loanID: number) => {
myToast("Ausleihe erfolgreich ausgeliehen!", "success"); myToast("Ausleihe erfolgreich ausgeliehen!", "success");
return true; return true;
}; };
export const changePW = async (oldPassword: string, newPassword: string) => {
const response = await fetch("http://localhost:8002/api/changePassword", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${Cookies.get("token") || ""}`,
},
body: JSON.stringify({ oldPassword, newPassword }),
});
if (!response.ok) {
myToast("Fehler beim Ändern des Passworts", "error");
return false;
}
myToast("Passwort erfolgreich geändert!", "success");
return true;
};