Refaktoriere Controller-Methoden zur Benutzer-, Event- und Menü-Datenverwaltung, indem die Logik in separate Service-Klassen ausgelagert wird. Implementiere eine verbesserte Fehlerbehandlung und sichere Rückgaben. Füge eine neue Route zur Passwortänderung im Benutzer-Router hinzu.
This commit is contained in:
140
services/UserService.js
Normal file
140
services/UserService.js
Normal file
@@ -0,0 +1,140 @@
|
||||
const { User } = require('../models');
|
||||
const bcrypt = require('bcryptjs');
|
||||
|
||||
class UserService {
|
||||
/**
|
||||
* Alle User abrufen (ohne sensible Daten)
|
||||
*/
|
||||
async getAllUsers() {
|
||||
const users = await User.findAll({
|
||||
order: [['name', 'ASC']],
|
||||
attributes: ['id', 'name', 'email', 'active', 'created_at', 'updated_at']
|
||||
});
|
||||
return users;
|
||||
}
|
||||
|
||||
/**
|
||||
* User anhand ID abrufen (ohne sensible Daten)
|
||||
*/
|
||||
async getUserById(id) {
|
||||
const user = await User.findByPk(id, {
|
||||
attributes: ['id', 'name', 'email', 'active', 'created_at', 'updated_at']
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
throw new Error('USER_NOT_FOUND');
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Neuen User erstellen
|
||||
*/
|
||||
async createUser(userData) {
|
||||
// Passwort hashen falls vorhanden
|
||||
if (userData.password) {
|
||||
userData.password = await bcrypt.hash(userData.password, 10);
|
||||
}
|
||||
|
||||
const user = await User.create(userData);
|
||||
|
||||
// Sichere User-Daten zurückgeben
|
||||
return this.getSafeUserData(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* User aktualisieren (ohne sensible Felder)
|
||||
*/
|
||||
async updateUser(id, updateData) {
|
||||
const user = await User.findByPk(id);
|
||||
|
||||
if (!user) {
|
||||
throw new Error('USER_NOT_FOUND');
|
||||
}
|
||||
|
||||
// Erstelle sichere Update-Daten
|
||||
const safeUpdateData = this.getSafeUpdateData(updateData);
|
||||
|
||||
await user.update(safeUpdateData);
|
||||
|
||||
return this.getSafeUserData(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* User löschen
|
||||
*/
|
||||
async deleteUser(id) {
|
||||
const user = await User.findByPk(id);
|
||||
|
||||
if (!user) {
|
||||
throw new Error('USER_NOT_FOUND');
|
||||
}
|
||||
|
||||
await user.destroy();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* User anhand E-Mail abrufen (für interne Verwendung)
|
||||
*/
|
||||
async getUserByEmail(email) {
|
||||
return await User.findOne({ where: { email } });
|
||||
}
|
||||
|
||||
/**
|
||||
* Passwort ändern (separate Methode für sichere Passwort-Änderung)
|
||||
*/
|
||||
async changePassword(id, currentPassword, newPassword) {
|
||||
const user = await User.findByPk(id);
|
||||
|
||||
if (!user) {
|
||||
throw new Error('USER_NOT_FOUND');
|
||||
}
|
||||
|
||||
// Aktuelles Passwort prüfen
|
||||
const isValidPassword = await bcrypt.compare(currentPassword, user.password);
|
||||
if (!isValidPassword) {
|
||||
throw new Error('INVALID_CURRENT_PASSWORD');
|
||||
}
|
||||
|
||||
// Neues Passwort hashen und speichern
|
||||
const hashedPassword = await bcrypt.hash(newPassword, 10);
|
||||
await user.update({ password: hashedPassword });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sichere User-Daten extrahieren (ohne Passwort)
|
||||
*/
|
||||
getSafeUserData(user) {
|
||||
return {
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
email: user.email,
|
||||
active: user.active,
|
||||
created_at: user.created_at,
|
||||
updated_at: user.updated_at
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sichere Update-Daten erstellen (ohne sensible Felder)
|
||||
*/
|
||||
getSafeUpdateData(updateData) {
|
||||
const safeData = { ...updateData };
|
||||
|
||||
// Entferne sensible Felder
|
||||
delete safeData.password;
|
||||
delete safeData.id;
|
||||
delete safeData.created_at;
|
||||
|
||||
// Setze updated_at
|
||||
safeData.updated_at = new Date();
|
||||
|
||||
return safeData;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new UserService();
|
||||
Reference in New Issue
Block a user