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:
@@ -1,205 +1,29 @@
|
||||
const bcrypt = require('bcryptjs');
|
||||
const { User, PasswordResetToken } = require('../models');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const { addTokenToBlacklist } = require('../utils/blacklist');
|
||||
const { transporter, getPasswordResetEmailTemplate } = require('../config/email');
|
||||
const crypto = require('crypto');
|
||||
const AuthService = require('../services/AuthService');
|
||||
const ErrorHandler = require('../utils/ErrorHandler');
|
||||
|
||||
function delay(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
exports.register = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const result = await AuthService.register(req.body);
|
||||
ErrorHandler.successResponse(res, result, 'Benutzer erfolgreich registriert', 201);
|
||||
});
|
||||
|
||||
exports.register = async (req, res) => {
|
||||
const { name, email, password } = req.body;
|
||||
if (!name || !email || !password) {
|
||||
return res.status(400).json({ message: 'Alle Felder sind erforderlich' });
|
||||
}
|
||||
try {
|
||||
const hashedPassword = await bcrypt.hash(password, 10);
|
||||
console.log('Register: creating user', { email });
|
||||
exports.login = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const result = await AuthService.login(req.body);
|
||||
ErrorHandler.successResponse(res, result, result.message);
|
||||
});
|
||||
|
||||
const maxAttempts = 3;
|
||||
let attempt = 0;
|
||||
let createdUser = null;
|
||||
let lastError = null;
|
||||
exports.forgotPassword = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const result = await AuthService.forgotPassword(req.body.email);
|
||||
ErrorHandler.successResponse(res, result, result.message);
|
||||
});
|
||||
|
||||
while (attempt < maxAttempts && !createdUser) {
|
||||
try {
|
||||
createdUser = await User.create({ name, email, password: hashedPassword, active: true });
|
||||
} catch (err) {
|
||||
lastError = err;
|
||||
// Spezifisch auf Lock-Timeout reagieren und erneut versuchen
|
||||
if ((err.code === 'ER_LOCK_WAIT_TIMEOUT' || err?.parent?.code === 'ER_LOCK_WAIT_TIMEOUT') && attempt < maxAttempts - 1) {
|
||||
const backoffMs = 300 * (attempt + 1);
|
||||
console.warn(`Register: ER_LOCK_WAIT_TIMEOUT, retry in ${backoffMs}ms (attempt ${attempt + 1}/${maxAttempts})`);
|
||||
await delay(backoffMs);
|
||||
attempt++;
|
||||
continue;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
exports.resetPassword = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const result = await AuthService.resetPassword(req.body.token, req.body.password);
|
||||
ErrorHandler.successResponse(res, result, result.message);
|
||||
});
|
||||
|
||||
if (!createdUser && lastError) {
|
||||
console.error('Register error (after retries):', lastError);
|
||||
return res.status(503).json({ message: 'Zeitüberschreitung beim Zugriff auf die Datenbank. Bitte erneut versuchen.' });
|
||||
}
|
||||
|
||||
console.log('Register: user created', { id: createdUser.id });
|
||||
|
||||
const safeUser = {
|
||||
id: createdUser.id,
|
||||
name: createdUser.name,
|
||||
email: createdUser.email,
|
||||
active: createdUser.active,
|
||||
created_at: createdUser.created_at
|
||||
};
|
||||
|
||||
return res.status(201).json({ message: 'Benutzer erfolgreich registriert', user: safeUser });
|
||||
} catch (error) {
|
||||
if (error.name === 'SequelizeUniqueConstraintError') {
|
||||
return res.status(400).json({ message: 'Email-Adresse bereits in Verwendung' });
|
||||
}
|
||||
console.error('Register error:', error);
|
||||
return res.status(500).json({ message: 'Ein Fehler ist aufgetreten', error: error.message });
|
||||
}
|
||||
};
|
||||
|
||||
exports.login = async (req, res) => {
|
||||
const { email, password } = req.body;
|
||||
if (!email || !password) {
|
||||
return res.status(400).json({ message: 'Email und Passwort sind erforderlich' });
|
||||
}
|
||||
try {
|
||||
const user = await User.findOne({ where: { email } });
|
||||
if (!user) {
|
||||
return res.status(401).json({ message: 'Ungültige Anmeldedaten' });
|
||||
}
|
||||
const validPassword = await bcrypt.compare(password, user.password);
|
||||
if (!validPassword) {
|
||||
return res.status(401).json({ message: 'Ungültige Anmeldedaten' });
|
||||
}
|
||||
if (!user.active) {
|
||||
return res.status(403).json({ message: 'Benutzerkonto ist nicht aktiv' });
|
||||
}
|
||||
const token = jwt.sign({ id: user.id, name: user.name, email: user.email }, 'zTxVgptmPl9!_dr%xxx9999(dd)', { expiresIn: '1h' });
|
||||
return res.status(200).json({ message: 'Login erfolgreich', token, 'user': user });
|
||||
} catch (error) {
|
||||
return res.status(500).json({ message: 'Ein Fehler ist aufgetreten' });
|
||||
}
|
||||
};
|
||||
|
||||
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) => {
|
||||
exports.logout = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const authHeader = req.header('Authorization');
|
||||
if (!authHeader) {
|
||||
return res.status(400).json({ message: 'Kein Token bereitgestellt' });
|
||||
}
|
||||
const token = authHeader.replace('Bearer ', '');
|
||||
try {
|
||||
addTokenToBlacklist(token);
|
||||
return res.status(200).json({ message: 'Logout erfolgreich' });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return res.status(500).json({ message: 'Ein Fehler ist beim Logout aufgetreten' });
|
||||
}
|
||||
};
|
||||
const token = authHeader ? authHeader.replace('Bearer ', '') : null;
|
||||
const result = await AuthService.logout(token);
|
||||
ErrorHandler.successResponse(res, result, result.message);
|
||||
});
|
||||
@@ -1,188 +1,32 @@
|
||||
const { Event, Institution, EventPlace, ContactPerson, EventType } = require('../models');
|
||||
const { Op } = require('sequelize');
|
||||
const moment = require('moment'); // Import von Moment.js
|
||||
const EventService = require('../services/EventService');
|
||||
const ErrorHandler = require('../utils/ErrorHandler');
|
||||
|
||||
const getAllEvents = async (req, res) => {
|
||||
try {
|
||||
const events = await Event.findAll({
|
||||
include: [
|
||||
{ model: Institution, as: 'institution' },
|
||||
{ model: EventPlace, as: 'eventPlace' },
|
||||
{ model: EventType, as: 'eventType' },
|
||||
{ model: ContactPerson, as: 'contactPersons', through: { attributes: [] } }
|
||||
],
|
||||
order: ['name', 'date', 'time']
|
||||
});
|
||||
res.json(events);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: 'Failed to fetch events' });
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
exports.getAllEvents = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const events = await EventService.getAllEvents();
|
||||
ErrorHandler.successResponse(res, events, 'Events erfolgreich abgerufen');
|
||||
});
|
||||
|
||||
const filterEvents = async (req, res) => {
|
||||
try {
|
||||
const request = req.body;
|
||||
const where = {
|
||||
[Op.or]: [
|
||||
{
|
||||
date: {
|
||||
[Op.or]: [
|
||||
{ [Op.gte]: moment().startOf('day').toDate() },
|
||||
{ [Op.eq]: null }
|
||||
]
|
||||
}
|
||||
},
|
||||
{ dayOfWeek: { [Op.gte]: 0 } }
|
||||
]
|
||||
};
|
||||
const order = [
|
||||
['date', 'ASC'],
|
||||
['time', 'ASC']
|
||||
];
|
||||
exports.getEventById = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const event = await EventService.getEventById(req.params.id);
|
||||
ErrorHandler.successResponse(res, event, 'Event erfolgreich abgerufen');
|
||||
});
|
||||
|
||||
if (request.id === 'all') {
|
||||
const events = await Event.findAll({
|
||||
where,
|
||||
include: [
|
||||
{ model: Institution, as: 'institution' },
|
||||
{ model: EventPlace, as: 'eventPlace' },
|
||||
{ model: EventType, as: 'eventType' },
|
||||
{ model: ContactPerson, as: 'contactPersons', through: { attributes: [] } }
|
||||
],
|
||||
order: order,
|
||||
logging: console.log // Log the generated SQL query
|
||||
});
|
||||
return res.json({ events });
|
||||
}
|
||||
exports.filterEvents = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const result = await EventService.filterEvents(req.body);
|
||||
ErrorHandler.successResponse(res, result, 'Events erfolgreich gefiltert');
|
||||
});
|
||||
|
||||
if (request.id === 'home') {
|
||||
const events = await Event.findAll({
|
||||
where: {
|
||||
alsoOnHomepage: 1,
|
||||
date: { [Op.gte]: moment().startOf('day').toDate() }
|
||||
},
|
||||
include: [
|
||||
{ model: Institution, as: 'institution' },
|
||||
{ model: EventPlace, as: 'eventPlace' },
|
||||
{ model: EventType, as: 'eventType' },
|
||||
{ model: ContactPerson, as: 'contactPersons', through: { attributes: [] } },
|
||||
],
|
||||
order: order,
|
||||
});
|
||||
return res.json({ events });
|
||||
}
|
||||
exports.createEvent = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const event = await EventService.createEvent(req.body);
|
||||
ErrorHandler.successResponse(res, event, 'Event erfolgreich erstellt', 201);
|
||||
});
|
||||
|
||||
if (!request.id && !request.places && !request.types) {
|
||||
return res.json({ events: [], places: [], types: [], contactPersons: [] });
|
||||
}
|
||||
exports.updateEvent = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const event = await EventService.updateEvent(req.params.id, req.body);
|
||||
ErrorHandler.successResponse(res, event, 'Event erfolgreich aktualisiert');
|
||||
});
|
||||
|
||||
if (request.id) {
|
||||
where.id = request.id;
|
||||
}
|
||||
|
||||
if (request.places && request.places.length > 0) {
|
||||
where.event_place_id = {
|
||||
[Op.in]: request.places.map(id => parseInt(id))
|
||||
};
|
||||
}
|
||||
|
||||
if (request.types && request.types.length > 0) {
|
||||
where.eventTypeId = {
|
||||
[Op.in]: request.types.map(id => parseInt(id))
|
||||
};
|
||||
}
|
||||
|
||||
const events = await Event.findAll({
|
||||
where,
|
||||
include: [
|
||||
{ model: Institution, as: 'institution' },
|
||||
{ model: EventPlace, as: 'eventPlace' },
|
||||
{ model: EventType, as: 'eventType' },
|
||||
{ model: ContactPerson, as: 'contactPersons', through: { attributes: [] } }
|
||||
],
|
||||
order: order,
|
||||
});
|
||||
const displayFields = request.display ? request.display : [];
|
||||
|
||||
const filteredEvents = events.map(event => {
|
||||
const filteredEvent = { ...event.toJSON() };
|
||||
|
||||
if (!displayFields.includes('name')) delete filteredEvent.name;
|
||||
if (!displayFields.includes('type')) delete filteredEvent.eventType;
|
||||
if (!displayFields.includes('place')) delete filteredEvent.eventPlace;
|
||||
if (!displayFields.includes('description')) delete filteredEvent.description;
|
||||
if (!displayFields.includes('time')) delete filteredEvent.time;
|
||||
if (!displayFields.includes('time')) delete filteredEvent.endTime;
|
||||
if (!displayFields.includes('contactPerson')) delete filteredEvent.contactPersons;
|
||||
if (!displayFields.includes('day')) delete filteredEvent.dayOfWeek;
|
||||
if (!displayFields.includes('institution')) delete filteredEvent.institution;
|
||||
|
||||
return filteredEvent;
|
||||
});
|
||||
|
||||
res.json({ events: filteredEvents });
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: 'Failed to filter events' });
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const createEvent = async (req, res) => {
|
||||
try {
|
||||
const { contactPersonIds, ...eventData } = req.body;
|
||||
eventData.alsoOnHomepage = eventData.alsoOnHomepage ?? 0;
|
||||
const event = await Event.create(eventData);
|
||||
if (contactPersonIds) {
|
||||
await event.setContactPersons(contactPersonIds);
|
||||
}
|
||||
res.status(201).json(event);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: 'Failed to create event' });
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const updateEvent = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { contactPersonIds, ...eventData } = req.body;
|
||||
const event = await Event.findByPk(id);
|
||||
if (!event) {
|
||||
return res.status(404).json({ error: 'Event not found' });
|
||||
}
|
||||
await event.update(eventData);
|
||||
if (contactPersonIds) {
|
||||
await event.setContactPersons(contactPersonIds);
|
||||
}
|
||||
res.status(200).json(event);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: 'Failed to update event' });
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteEvent = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const deleted = await Event.destroy({
|
||||
where: { id: id }
|
||||
});
|
||||
if (deleted) {
|
||||
res.status(204).json();
|
||||
} else {
|
||||
res.status(404).json({ error: 'Event not found' });
|
||||
}
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: 'Failed to delete event' });
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getAllEvents,
|
||||
createEvent,
|
||||
updateEvent,
|
||||
deleteEvent,
|
||||
filterEvents
|
||||
};
|
||||
exports.deleteEvent = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const result = await EventService.deleteEvent(req.params.id);
|
||||
ErrorHandler.successResponse(res, result, result.message);
|
||||
});
|
||||
@@ -1,30 +1,12 @@
|
||||
const { MenuItem } = require('../models');
|
||||
const fetchMenuData = require('../utils/fetchMenuData');
|
||||
const MenuDataService = require('../services/MenuDataService');
|
||||
const ErrorHandler = require('../utils/ErrorHandler');
|
||||
|
||||
exports.getMenuData = async (req, res) => {
|
||||
try {
|
||||
const menuData = await fetchMenuData();
|
||||
res.json(menuData);
|
||||
} catch (error) {
|
||||
res.status(500).send('Error fetching menu data');
|
||||
}
|
||||
};
|
||||
exports.getMenuData = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const menuData = await MenuDataService.getMenuData();
|
||||
ErrorHandler.successResponse(res, menuData, 'Menü-Daten erfolgreich abgerufen');
|
||||
});
|
||||
|
||||
exports.saveMenuData = async (req, res) => {
|
||||
try {
|
||||
const menuData = req.body;
|
||||
const adjustedMenuData = menuData.map(item => {
|
||||
item.parent_id = item.parent_id < 0 ? null : item.parent_id;
|
||||
return item;
|
||||
})
|
||||
.sort((a, b) => (a.parent_id === null ? -1 : 1) - (b.parent_id === null ? -1 : 1));
|
||||
await MenuItem.destroy({ where: {} });
|
||||
for (const item of adjustedMenuData) {
|
||||
await MenuItem.create(item);
|
||||
}
|
||||
res.status(200).send('Menü-Daten erfolgreich gespeichert');
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Speichern der Menü-Daten:', error);
|
||||
res.status(500).send('Fehler beim Speichern der Menü-Daten');
|
||||
}
|
||||
};
|
||||
exports.saveMenuData = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const result = await MenuDataService.saveMenuData(req.body);
|
||||
ErrorHandler.successResponse(res, result, result.message);
|
||||
});
|
||||
@@ -1,48 +1,27 @@
|
||||
// controllers/pageController.js
|
||||
const { Page } = require('../models');
|
||||
const PageService = require('../services/PageService');
|
||||
const ErrorHandler = require('../utils/ErrorHandler');
|
||||
|
||||
exports.getMenuData = async (req, res) => {
|
||||
try {
|
||||
const pages = await Page.findAll({
|
||||
attributes: ['link', 'name']
|
||||
});
|
||||
res.json(pages);
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Abrufen der Seiten:', error);
|
||||
res.status(500).json({ message: 'Fehler beim Abrufen der Seiten' });
|
||||
}
|
||||
};
|
||||
exports.getMenuData = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const pages = await PageService.getAllPages();
|
||||
ErrorHandler.successResponse(res, pages, 'Seiten erfolgreich abgerufen');
|
||||
});
|
||||
|
||||
exports.getPageContent = async (req, res) => {
|
||||
try {
|
||||
const page = await Page.findOne({
|
||||
where: { link: req.query.link }
|
||||
});
|
||||
if (page) {
|
||||
res.json({ content: page.content });
|
||||
} else {
|
||||
res.json({ content: "" });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Laden des Seiteninhalts:', error);
|
||||
res.status(500).json({ message: 'Fehler beim Laden des Seiteninhalts' });
|
||||
}
|
||||
};
|
||||
exports.getPageContent = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const result = await PageService.getPageContent(req.query.link);
|
||||
ErrorHandler.successResponse(res, result, 'Seiteninhalt erfolgreich abgerufen');
|
||||
});
|
||||
|
||||
exports.savePageContent = async (req, res) => {
|
||||
try {
|
||||
const { link, name, content } = req.body;
|
||||
let page = await Page.findOne({ where: { link } });
|
||||
if (page) {
|
||||
page.content = content;
|
||||
page.name = name;
|
||||
} else {
|
||||
page = await Page.create({ link, name, content });
|
||||
}
|
||||
await page.save();
|
||||
res.json({ message: 'Seiteninhalt gespeichert', page });
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Speichern des Seiteninhalts:', error);
|
||||
res.status(500).json({ message: 'Fehler beim Speichern des Seiteninhalts' });
|
||||
}
|
||||
};
|
||||
exports.savePageContent = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const result = await PageService.savePageContent(req.body);
|
||||
ErrorHandler.successResponse(res, result, result.message);
|
||||
});
|
||||
|
||||
exports.getPageById = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const page = await PageService.getPageById(req.params.id);
|
||||
ErrorHandler.successResponse(res, page, 'Seite erfolgreich abgerufen');
|
||||
});
|
||||
|
||||
exports.deletePage = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const result = await PageService.deletePage(req.params.id);
|
||||
ErrorHandler.successResponse(res, result, result.message);
|
||||
});
|
||||
@@ -1,104 +1,42 @@
|
||||
const { User } = require('../models');
|
||||
const UserService = require('../services/UserService');
|
||||
const UserValidator = require('../validators/UserValidator');
|
||||
const ErrorHandler = require('../utils/ErrorHandler');
|
||||
|
||||
exports.getAllUsers = async (req, res) => {
|
||||
try {
|
||||
const users = await User.findAll({
|
||||
order: [['name', 'ASC']],
|
||||
attributes: ['id', 'name', 'email', 'active', 'created_at'] // Passwort ausschließen
|
||||
});
|
||||
res.status(200).json(users);
|
||||
} catch (error) {
|
||||
console.error('Error fetching users:', error);
|
||||
res.status(500).json({ message: 'Error fetching users' });
|
||||
}
|
||||
};
|
||||
exports.getAllUsers = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const users = await UserService.getAllUsers();
|
||||
ErrorHandler.successResponse(res, users, 'Benutzer erfolgreich abgerufen');
|
||||
});
|
||||
|
||||
exports.getUserById = async (req, res) => {
|
||||
try {
|
||||
const user = await User.findByPk(req.params.id, {
|
||||
attributes: ['id', 'name', 'email', 'active', 'created_at'] // Passwort ausschließen
|
||||
});
|
||||
if (user) {
|
||||
res.status(200).json(user);
|
||||
} else {
|
||||
res.status(404).json({ message: 'User not found' });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching user:', error);
|
||||
res.status(500).json({ message: 'Error fetching user' });
|
||||
}
|
||||
};
|
||||
exports.getUserById = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
UserValidator.validateId(req.params.id);
|
||||
const user = await UserService.getUserById(req.params.id);
|
||||
ErrorHandler.successResponse(res, user, 'Benutzer erfolgreich abgerufen');
|
||||
});
|
||||
|
||||
exports.createUser = async (req, res) => {
|
||||
try {
|
||||
const user = await User.create(req.body);
|
||||
|
||||
// Sichere User-Daten zurückgeben (ohne Passwort)
|
||||
const safeUser = {
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
email: user.email,
|
||||
active: user.active,
|
||||
created_at: user.created_at
|
||||
};
|
||||
|
||||
res.status(201).json(safeUser);
|
||||
} catch (error) {
|
||||
console.error('Error creating user:', error);
|
||||
res.status(500).json({ message: 'Error creating user' });
|
||||
}
|
||||
};
|
||||
exports.createUser = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
UserValidator.validateCreateUser(req.body);
|
||||
const user = await UserService.createUser(req.body);
|
||||
ErrorHandler.successResponse(res, user, 'Benutzer erfolgreich erstellt', 201);
|
||||
});
|
||||
|
||||
exports.updateUser = async (req, res) => {
|
||||
try {
|
||||
const user = await User.findByPk(req.params.id);
|
||||
if (user) {
|
||||
// Erstelle eine Kopie der Request-Daten ohne sensible Felder
|
||||
const updateData = { ...req.body };
|
||||
|
||||
// Entferne sensible Felder, die niemals über diese Route geändert werden dürfen
|
||||
delete updateData.password;
|
||||
delete updateData.id;
|
||||
delete updateData.created_at;
|
||||
|
||||
// Setze updated_at auf aktuelle Zeit
|
||||
updateData.updated_at = new Date();
|
||||
|
||||
// Logging für Debugging
|
||||
console.log('Updating user:', req.params.id, 'with data:', updateData);
|
||||
|
||||
await user.update(updateData);
|
||||
|
||||
// Sichere User-Daten zurückgeben (ohne Passwort)
|
||||
const safeUser = {
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
email: user.email,
|
||||
active: user.active,
|
||||
created_at: user.created_at
|
||||
};
|
||||
|
||||
res.status(200).json(safeUser);
|
||||
} else {
|
||||
res.status(404).json({ message: 'User not found' });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error updating user:', error);
|
||||
res.status(500).json({ message: 'Error updating user' });
|
||||
}
|
||||
};
|
||||
exports.updateUser = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
UserValidator.validateId(req.params.id);
|
||||
UserValidator.validateUpdateUser(req.body);
|
||||
const user = await UserService.updateUser(req.params.id, req.body);
|
||||
ErrorHandler.successResponse(res, user, 'Benutzer erfolgreich aktualisiert');
|
||||
});
|
||||
|
||||
exports.deleteUser = async (req, res) => {
|
||||
try {
|
||||
const user = await User.findByPk(req.params.id);
|
||||
if (user) {
|
||||
await user.destroy();
|
||||
res.status(200).json({ message: 'User deleted successfully' });
|
||||
} else {
|
||||
res.status(404).json({ message: 'User not found' });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error deleting user:', error);
|
||||
res.status(500).json({ message: 'Error deleting user' });
|
||||
}
|
||||
};
|
||||
exports.deleteUser = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
UserValidator.validateId(req.params.id);
|
||||
await UserService.deleteUser(req.params.id);
|
||||
ErrorHandler.successResponse(res, null, 'Benutzer erfolgreich gelöscht');
|
||||
});
|
||||
|
||||
// Neue Route für Passwort-Änderung
|
||||
exports.changePassword = ErrorHandler.asyncHandler(async (req, res) => {
|
||||
const { currentPassword, newPassword } = req.body;
|
||||
UserValidator.validateId(req.params.id);
|
||||
UserValidator.validatePasswordChange(currentPassword, newPassword);
|
||||
await UserService.changePassword(req.params.id, currentPassword, newPassword);
|
||||
ErrorHandler.successResponse(res, null, 'Passwort erfolgreich geändert');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user