diff --git a/backend/src/routes/auth.ts b/backend/src/routes/auth.ts index c42d06b..d69c46b 100644 --- a/backend/src/routes/auth.ts +++ b/backend/src/routes/auth.ts @@ -32,6 +32,32 @@ authRouter.post('/auth/login', async (req: Request, res: Response) => { res.status(200).json({ token, user: publicUser(user) }); }); +// POST /v1/auth/change-password { currentPassword, newPassword } -> { ok: true } +// Für alle Rollen (Vermieter/Admin/Mieter/Handwerker) gleichermaßen nutzbar — +// ändert ausschließlich das eigene Passwort, verlangt zur Bestätigung das +// aktuelle Passwort. +authRouter.post('/auth/change-password', requireAuth, async (req: AuthedRequest, res: Response) => { + const { currentPassword, newPassword } = req.body || {}; + if (!currentPassword || !newPassword) { + return res.status(400).json({ error: 'Aktuelles und neues Passwort erforderlich' }); + } + if (String(newPassword).length < 8) { + return res.status(400).json({ error: 'Das neue Passwort muss mindestens 8 Zeichen lang sein' }); + } + + const user = await prisma.user.findUnique({ where: { id: req.user!.id } }); + if (!user) return res.status(404).json({ error: 'Nutzer nicht gefunden' }); + + const currentOk = await bcrypt.compare(String(currentPassword), user.passwordHash); + if (!currentOk) { + return res.status(401).json({ error: 'Aktuelles Passwort ist falsch' }); + } + + const passwordHash = await bcrypt.hash(String(newPassword), 12); + await prisma.user.update({ where: { id: user.id }, data: { passwordHash } }); + res.status(200).json({ ok: true }); +}); + // GET /v1/auth/me -> aktuell eingeloggter Nutzer (zur Session-Wiederherstellung) authRouter.get('/auth/me', requireAuth, async (req: AuthedRequest, res: Response) => { const user = await prisma.user.findUnique({ where: { id: req.user!.id } }); diff --git a/web-dashboard/index.html b/web-dashboard/index.html index 988ba08..dbccb44 100644 --- a/web-dashboard/index.html +++ b/web-dashboard/index.html @@ -590,6 +590,7 @@
@@ -1081,6 +1082,35 @@ + + +