Implementiere Passwort-Zurücksetzen-Funktionalität im authController, einschließlich E-Mail-Versand und Token-Generierung. Aktualisiere die Benutzer- und Router-Modelle, um neue Routen für Passwort-Wiederherstellung hinzuzufügen. Passe die Frontend-Komponenten für die Passwort-Zurücksetzen-Logik an und verbessere die Benutzeroberfläche für die Eingabe der E-Mail-Adresse.
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
const bcrypt = require('bcryptjs');
|
||||
const { User } = require('../models');
|
||||
const { User, PasswordResetToken } = require('../models');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const { addTokenToBlacklist } = require('../utils/blacklist');
|
||||
const { transporter, getPasswordResetEmailTemplate } = require('../config/email');
|
||||
const crypto = require('crypto');
|
||||
|
||||
function delay(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
@@ -87,6 +89,106 @@ exports.login = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
exports.forgotPassword = async (req, res) => {
|
||||
const { email } = req.body;
|
||||
if (!email) {
|
||||
return res.status(400).json({ message: 'E-Mail-Adresse ist erforderlich' });
|
||||
}
|
||||
try {
|
||||
const user = await User.findOne({ where: { email } });
|
||||
if (!user) {
|
||||
// Aus Sicherheitsgründen immer Erfolg melden, auch wenn E-Mail nicht existiert
|
||||
return res.status(200).json({ message: 'Falls die E-Mail-Adresse in unserem System registriert ist, erhalten Sie einen Link zum Zurücksetzen des Passworts.' });
|
||||
}
|
||||
|
||||
// Alte Reset-Tokens für diesen User löschen
|
||||
await PasswordResetToken.destroy({ where: { userId: user.id } });
|
||||
|
||||
// Neuen Reset-Token generieren
|
||||
const token = crypto.randomBytes(32).toString('hex');
|
||||
const expiresAt = new Date(Date.now() + 60 * 60 * 1000); // 1 Stunde
|
||||
|
||||
await PasswordResetToken.create({
|
||||
userId: user.id,
|
||||
token,
|
||||
expiresAt
|
||||
});
|
||||
|
||||
// Reset-URL generieren
|
||||
const resetUrl = `${process.env.FRONTEND_URL || 'http://localhost:8080'}/reset-password?token=${token}`;
|
||||
|
||||
// E-Mail versenden
|
||||
const emailTemplate = getPasswordResetEmailTemplate(resetUrl, user.name);
|
||||
|
||||
const mailOptions = {
|
||||
from: process.env.SMTP_FROM || 'noreply@miriamgemeinde.de',
|
||||
to: email,
|
||||
subject: emailTemplate.subject,
|
||||
html: emailTemplate.html,
|
||||
text: emailTemplate.text
|
||||
};
|
||||
|
||||
console.log('=== EMAIL SENDING DEBUG ===');
|
||||
console.log('From:', mailOptions.from);
|
||||
console.log('To:', mailOptions.to);
|
||||
console.log('Subject:', mailOptions.subject);
|
||||
console.log('Reset URL:', resetUrl);
|
||||
console.log('===========================');
|
||||
|
||||
await transporter.sendMail(mailOptions);
|
||||
|
||||
console.log('Password reset email sent to:', email);
|
||||
return res.status(200).json({ message: 'Falls die E-Mail-Adresse in unserem System registriert ist, erhalten Sie einen Link zum Zurücksetzen des Passworts.' });
|
||||
} catch (error) {
|
||||
console.error('Forgot password error:', error);
|
||||
return res.status(500).json({ message: 'Ein Fehler ist aufgetreten' });
|
||||
}
|
||||
};
|
||||
|
||||
exports.resetPassword = async (req, res) => {
|
||||
const { token, password } = req.body;
|
||||
if (!token || !password) {
|
||||
return res.status(400).json({ message: 'Token und neues Passwort sind erforderlich' });
|
||||
}
|
||||
if (password.length < 6) {
|
||||
return res.status(400).json({ message: 'Passwort muss mindestens 6 Zeichen lang sein' });
|
||||
}
|
||||
|
||||
try {
|
||||
// Token validieren
|
||||
const resetToken = await PasswordResetToken.findOne({
|
||||
where: {
|
||||
token,
|
||||
used: false,
|
||||
expiresAt: {
|
||||
[require('sequelize').Op.gt]: new Date()
|
||||
}
|
||||
},
|
||||
include: [{ model: User, as: 'user' }]
|
||||
});
|
||||
|
||||
if (!resetToken) {
|
||||
return res.status(400).json({ message: 'Ungültiger oder abgelaufener Token' });
|
||||
}
|
||||
|
||||
// Passwort hashen und aktualisieren
|
||||
const hashedPassword = await bcrypt.hash(password, 10);
|
||||
await User.update(
|
||||
{ password: hashedPassword },
|
||||
{ where: { id: resetToken.userId } }
|
||||
);
|
||||
|
||||
// Token als verwendet markieren
|
||||
await resetToken.update({ used: true });
|
||||
|
||||
console.log('Password reset successful for user:', resetToken.userId);
|
||||
return res.status(200).json({ message: 'Passwort erfolgreich zurückgesetzt' });
|
||||
} catch (error) {
|
||||
console.error('Reset password error:', error);
|
||||
return res.status(500).json({ message: 'Ein Fehler ist aufgetreten' });
|
||||
}
|
||||
};
|
||||
|
||||
exports.logout = async (req, res) => {
|
||||
const authHeader = req.header('Authorization');
|
||||
if (!authHeader) {
|
||||
|
||||
Reference in New Issue
Block a user