const User = require('../models/User'); const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); // Registrierungs-Controller const register = async (req, res) => { const { username, email, password } = req.body; try { // Überprüfen, ob Benutzername oder E-Mail bereits existieren let user = await User.findOne({ $or: [{ username }, { email }] }); if (user) { return res.status(400).json({ message: 'Benutzername oder E-Mail bereits vergeben' }); } // Überprüfen, ob es sich um den ersten Benutzer handelt const userCount = await User.countDocuments(); const isAdmin = userCount === 0; // Erster Benutzer wird Admin // Passwort hashen const hashedPassword = await bcrypt.hash(password, 10); // Neuen Benutzer erstellen user = new User({ username, email, password: hashedPassword, isAdmin, }); await user.save(); res.status(201).json({ message: 'Registrierung erfolgreich' }); } catch (error) { res.status(500).json({ message: 'Serverfehler' }); } }; // Login-Controller const login = async (req, res) => { const { email, password } = req.body; try { // Benutzer anhand der E-Mail suchen const user = await User.findOne({ email }); if (!user) { return res.status(400).json({ message: 'Ungültige Anmeldedaten' }); } // Check for too many failed login attempts (e.g., more than 5 in 15 minutes) const maxAttempts = 5; const lockTime = Math.pow(2, user.failedLoginAttempts) * 15 * 1000; // Exponentially increasing delay const now = new Date(); if (user.failedLoginAttempts >= maxAttempts && user.lastFailedLogin) { const timeDifference = now - new Date(user.lastFailedLogin); if (timeDifference < lockTime) { return res.status(429).json({ message: 'Zu viele fehlgeschlagene Versuche. Bitte versuchen Sie es später erneut.', }); } else { // Reset failed attempts if the lock time has passed user.failedLoginAttempts = 0; user.lastFailedLogin = null; await user.save(); } } // Passwort überprüfen const isMatch = await bcrypt.compare(password, user.password); if (!isMatch) { // Increment failed login attempts user.failedLoginAttempts += 1; user.lastFailedLogin = now; // Update the timestamp of the last failed attempt await user.save(); // Calculate delay (using the exponential backoff strategy) const delay = Math.pow(2, user.failedLoginAttempts) * 15 * 1000; // Delay in milliseconds const delayInSeconds = delay / 1000; // Return the delay time to the client return res.status(400).json({ message: `Invalid credentials. Please wait for ${delayInSeconds} seconds before trying again.`, }); } // Reset failed login attempts on successful login user.failedLoginAttempts = 0; user.lastFailedLogin = null; await user.save(); // JWT-Token erstellen mit benutzerdefinierten Daten const token = jwt.sign({ id: user._id, username: user.username, isAdmin: user.isAdmin }, process.env.JWT_SECRET, { expiresIn: '1h' }); res.status(200).json({ token, message: 'Login erfolgreich' }); } catch (error) { res.status(500).json({ message: 'Serverfehler' }); } }; module.exports = { register, login };