From 5c6cfa41ab296bc3db01ca7730d341ea3e37917c Mon Sep 17 00:00:00 2001 From: Torsten Schulz Date: Fri, 6 Sep 2024 16:34:17 +0200 Subject: [PATCH] Improvement of logout. Added Sacrital Service. Added website link for event places and direct link to other websites in worship overview --- config/database.js | 2 +- controllers/authController.js | 26 +++++++++------ controllers/worshipController.js | 35 ++++++++++++++++++--- middleware/authMiddleware.js | 5 ++- models/EventPlace.js | 6 +++- models/Worship.js | 7 ++++- routes/auth.js | 2 ++ src/axios.js | 2 +- src/common/components/FooterComponent.vue | 8 +++-- src/components/WorshipRender.vue | 25 ++++++++++++--- src/content/admin/EventPlacesManagement.vue | 8 +++-- src/content/admin/WorshipManagement.vue | 7 ++++- src/store/index.js | 12 +++++-- utils/blacklist.js | 26 +++++++++++++++ 14 files changed, 139 insertions(+), 32 deletions(-) create mode 100644 utils/blacklist.js diff --git a/config/database.js b/config/database.js index 3636a78..6cce022 100644 --- a/config/database.js +++ b/config/database.js @@ -13,7 +13,7 @@ const sequelize = new Sequelize('miriamgemeinde', 'miriam_user', 'qTCTTWwpEwy3vP /SequelizeInvalidConnectionError/, /SequelizeConnectionTimedOutError/ ], - max: 5 // Maximal 5 Versuche + max: 5 }, pool: { max: 5, diff --git a/controllers/authController.js b/controllers/authController.js index fd7de88..bfa226f 100644 --- a/controllers/authController.js +++ b/controllers/authController.js @@ -1,18 +1,16 @@ const bcrypt = require('bcryptjs'); const { User } = require('../models'); const jwt = require('jsonwebtoken'); +const { addTokenToBlacklist } = require('../utils/blacklist'); 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); const user = await User.create({ name, email, password: hashedPassword, active: true }); - res.status(201).json({ message: 'Benutzer erfolgreich registriert', user }); } catch (error) { if (error.name === 'SequelizeUniqueConstraintError') { @@ -27,28 +25,36 @@ exports.login = async (req, res) => { 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' }); - res.status(200).json({ message: 'Login erfolgreich', token, 'user': user }); } catch (error) { res.status(500).json({ message: 'Ein Fehler ist aufgetreten' }); } }; + +exports.logout = 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); + res.status(200).json({ message: 'Logout erfolgreich' }); + } catch (error) { + console.log(error); + res.status(500).json({ message: 'Ein Fehler ist beim Logout aufgetreten' }); + } +}; diff --git a/controllers/worshipController.js b/controllers/worshipController.js index 0557c8f..13b65bd 100644 --- a/controllers/worshipController.js +++ b/controllers/worshipController.js @@ -1,14 +1,40 @@ -const { Worship, EventPlace, Sequelize } = require('../models'); -const { Op, fn, literal } = require('sequelize'); // Importieren Sie die Operatoren von Sequelize +const { Worship, EventPlace, Sequelize, sequelize } = require('../models'); +const { Op, fn, literal } = require('sequelize'); +const jwt = require('jsonwebtoken'); +const { isTokenBlacklisted, addTokenToBlacklist } = require('../utils/blacklist'); + +function isAuthorized(req) { + const authHeader = req.header('Authorization'); + if (!authHeader) { + return false; + } + const token = authHeader.replace('Bearer ', ''); + if (isTokenBlacklisted(token)) { + console.log('Token is blacklisted'); + return false; + } + try { + const decoded = jwt.verify(token, 'zTxVgptmPl9!_dr%xxx9999(dd)'); + req.user = decoded; + return true; + } catch (err) { + console.log('Token verification failed, adding to blacklist:', err.message); + addTokenToBlacklist(token); + return false; + } +} + exports.getAllWorships = async (req, res) => { try { + const authorized = isAuthorized(req); const worships = await Worship.findAll({ where: { date: { [Op.gt]: literal("DATE_SUB(NOW(), INTERVAL 4 WEEK)") }, }, + attributes: authorized ? undefined : { exclude: ['sacristanService'] }, order: [ ['date', 'DESC'] ], @@ -69,14 +95,15 @@ exports.getFilteredWorships = async (req, res) => { [Sequelize.Op.in]: locations } } - where.date = { [Op.gte]: fn('CURDATE'), }; - try { + const authorized = isAuthorized(req); + console.log(authorized); const worships = await Worship.findAll({ where, + attributes: authorized ? undefined : { exclude: ['sacristanService'] }, include: { model: EventPlace, as: 'eventPlace', diff --git a/middleware/authMiddleware.js b/middleware/authMiddleware.js index e366ec9..821b5eb 100644 --- a/middleware/authMiddleware.js +++ b/middleware/authMiddleware.js @@ -1,12 +1,15 @@ const jwt = require('jsonwebtoken'); +const { isTokenBlacklisted } = require('../utils/blacklist'); const authMiddleware = (req, res, next) => { const authHeader = req.header('Authorization'); if (!authHeader) { return res.status(401).json({ message: 'Zugriff verweigert. Kein Token vorhanden.' }); } - const token = authHeader.replace('Bearer ', ''); + if (isTokenBlacklisted(token)) { + return res.status(401).json({ message: 'Token wurde gesperrt.' }); + } try { const decoded = jwt.verify(token, 'zTxVgptmPl9!_dr%xxx9999(dd)'); req.user = decoded; diff --git a/models/EventPlace.js b/models/EventPlace.js index 864c141..74bc22e 100644 --- a/models/EventPlace.js +++ b/models/EventPlace.js @@ -21,7 +21,11 @@ module.exports = (sequelize) => { backgroundColor: { type: DataTypes.STRING, allowNull: true - } + }, + website: { + type: DataTypes.STRING, + allowNull: true + }, }, { tableName: 'event_places' }); diff --git a/models/Worship.js b/models/Worship.js index c5cd682..b7f1177 100644 --- a/models/Worship.js +++ b/models/Worship.js @@ -55,7 +55,12 @@ module.exports = (sequelize) => { type: DataTypes.STRING, defaultValue: '', allowNull: false - } + }, + sacristanService: { + type: DataTypes.STRING(100), + allowNull: true, + field: 'sacristan_service' + }, }, { tableName: 'worships', timestamps: true diff --git a/routes/auth.js b/routes/auth.js index caea18a..fc21f30 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -1,8 +1,10 @@ const express = require('express'); const router = express.Router(); const authController = require('../controllers/authController'); +const authMiddleware = require('../middleware/authMiddleware'); router.post('/register', authController.register); router.post('/login', authController.login); +router.post('/logout', authMiddleware, authController.logout); module.exports = router; diff --git a/src/axios.js b/src/axios.js index e835a3a..d573ad2 100644 --- a/src/axios.js +++ b/src/axios.js @@ -24,7 +24,7 @@ axios.interceptors.response.use( }, error => { if (error.response && error.response.status === 401) { - store.commit('logout'); + store.dispatch('logout'); router.push('/'); } return Promise.reject(error); diff --git a/src/common/components/FooterComponent.vue b/src/common/components/FooterComponent.vue index 53d4109..eb24d34 100644 --- a/src/common/components/FooterComponent.vue +++ b/src/common/components/FooterComponent.vue @@ -21,8 +21,12 @@ export default { }, methods: { ...mapActions(['logout']), - navigateToLogin() { - this.$router.push('/login'); + async handleLogout() { + try { + await this.logout(); + } catch (error) { + console.error('Fehler beim Logout:', error); + } } } }; diff --git a/src/components/WorshipRender.vue b/src/components/WorshipRender.vue index 0849b62..27da5cf 100644 --- a/src/components/WorshipRender.vue +++ b/src/components/WorshipRender.vue @@ -1,24 +1,32 @@