Files
yourpart3/backend/services/forumService.js
Torsten Schulz (local) 3e70bbee9b Änderung: Anpassung der Berechtigungsverwaltung in ForumService und ForumAdminView
Änderungen:
- Im ForumService wurde die Berechtigungsabfrage aktualisiert, um direkt den Wert der Berechtigung zu verwenden.
- In ForumAdminView wurde die Verarbeitung der Berechtigungen beim Erstellen eines neuen Forums angepasst, um die Werte der Berechtigungen korrekt zu übermitteln.

Diese Anpassungen verbessern die Konsistenz und Funktionalität der Berechtigungsverwaltung im Forum.
2025-09-15 08:53:23 +02:00

383 lines
13 KiB
JavaScript

import BaseService from './BaseService.js';
import Forum from '../models/forum/forum.js';
import ForumPermission from '../models/forum/forum_permission.js';
import ForumUserPermission from '../models/forum/forum_user_permission.js';
import UserRight from '../models/community/user_right.js';
import UserRightType from '../models/type/user_right.js';
import { Op } from 'sequelize';
import { sequelize } from '../utils/sequelize.js';
import User from '../models/community/user.js';
import ForumForumPermission from '../models/forum/forum_forum_permission.js';
import Title from '../models/forum/title.js';
import Message from '../models/forum/message.js';
import { notifyAllUsers } from '../utils/socket.js';
class ForumService extends BaseService {
async createForum(hashedUserId, name, permissions) {
const user = await this.getUserByHashedId(hashedUserId);
const isAdmin = await this.hasUserRight(user.id, ['mainadmin', 'forum']);
if (!isAdmin) {
throw new Error('Access denied: Only admins can create forums.');
}
const newForum = await Forum.create({ name });
if (permissions && permissions.length > 0) {
for (const permission of permissions) {
const forumPermission = await ForumPermission.findOne({
where: { name: permission }
});
if (forumPermission) {
await newForum.addAssociatedPermissions(forumPermission);
}
}
}
await notifyAllUsers('forumschanged', {});
return newForum;
}
async deleteForum(hashedUserId, forumId) {
const user = await this.getUserByHashedId(hashedUserId);
const isAdmin = await this.hasUserRight(user.id, ['mainadmin', 'forum']);
if (!isAdmin) {
throw new Error('Access denied: Only admins can delete forums.');
}
const forum = await Forum.findByPk(forumId);
if (!forum) {
throw new Error('Forum not found.');
}
const transaction = await sequelize.transaction();
try {
const forumFormRights = await ForumForumPermission.findAll({
where: { forumId: forumId }
});
for (const forumFormRight of forumFormRights) {
await forumFormRight.destroy({ transaction });
}
const forumUserRights = await ForumUserPermission.findAll({
where: { forumId: forumId }
});
for (const forumUserRight of forumUserRights) {
await forumUserRight.destroy({ transaction });
}
await forum.destroy({ transaction });
await transaction.commit();
await notifyAllUsers('forumschanged', {});
return forum;
} catch (error) {
await transaction.rollback();
throw new Error(`Error deleting forum: ${error.message}`);
}
}
async getAllForums(hashedUserId) {
const user = await this.getUserByHashedId(hashedUserId);
if (!user) throw new Error('User not found.');
const forums = await Forum.findAll({
include: [
{
model: ForumPermission,
as: 'associatedPermissions',
},
{
model: ForumUserPermission,
as: 'userPermissions',
}
]
});
const accessibleForums = [];
for (const forum of forums) {
const hasAccess = await this.checkForumAccess(forum, user);
if (hasAccess) {
accessibleForums.push(forum);
}
}
return accessibleForums;
}
async getForum(hashedUserId, forumId, page) {
const user = await this.getUserByHashedId(hashedUserId);
if (!user) throw new Error('User not found.');
const forum = await Forum.findByPk(forumId, {
include: [
{
model: ForumPermission,
as: 'associatedPermissions',
},
{
model: ForumUserPermission,
as: 'userPermissions',
}
]
});
const hasAccess = await this.checkForumAccess(forum, user);
if (!hasAccess) {
throw new Error('Access denied.');
}
const titlesRaw = await Title.findAll({
where: {
forumId
},
attributes: [
'id',
'title',
'createdBy',
'forumId',
'createdAt',
'updatedAt',
[sequelize.literal(`(SELECT COUNT(*) FROM forum.message WHERE message.title_id = title.id)`), 'messageCount'],
[sequelize.literal(`(SELECT MAX("created_at") FROM forum.message WHERE message.title_id = title.id)`), 'lastMessageDate']
],
include: [
{
model: User,
as: 'createdByUser',
attributes: ['id', 'username', 'hashedId']
},
{
model: Message,
as: 'messages',
attributes: [],
include: [
{
model: User,
as: 'lastMessageUser',
attributes: ['id', 'username']
}
]
}
],
offset: (page - 1) * 25,
limit: 25,
order: [
['createdAt', 'DESC']
],
group: [
'title.id',
'title.created_at',
]
});
const totalTopics = await Title.count({ where: { forumId } });
const titles = titlesRaw.map(title => ({
id: title.dataValues.id,
title: title.dataValues.title,
createdBy: title.createdByUser.username,
createdByHash: title.createdByUser.hashedId,
createdAt: title.dataValues.createdAt,
numberOfItems: title.dataValues.messageCount,
lastMessageDate: title.dataValues.lastMessageDate
}));
return {
name: forum.name,
titles,
page,
totalTopics,
};
}
async createTopic(hashedUserId, forumId, title, content) {
const user = await this.getUserByHashedId(hashedUserId);
if (!user) throw new Error('User not found.');
const forum = await Forum.findByPk(forumId, {
include: [
{
model: ForumPermission,
as: 'associatedPermissions',
},
{
model: ForumUserPermission,
as: 'userPermissions',
}
]
});
const hasAccess = await this.checkForumAccess(forum, user);
if (!hasAccess) {
throw new Error('Access denied.');
}
const newTopic = await Title.create({ title, forumId, createdBy: user.id });
await Message.create({ titleId: newTopic.id, text: content, createdBy: user.id})
await notifyAllUsers('topicschanged', { forumId, topic: newTopic });
return this.getForum(hashedUserId, forumId, 1);
}
async getTopic(hashedUserId, topicId) {
console.log('[ForumService.getTopic] - start');
const user = await User.findOne({
where: {
hashedId: hashedUserId
}
});
if (!user) {
throw new Error('User not found.');
}
const topic = await Title.findByPk(topicId, {
include: [
{
model: Message,
as:'messages',
include: [
{
model: User,
as: 'lastMessageUser',
attributes: ['hashedId', 'username'],
order: [['createdAt', 'ASC']]
}
]
},
{
model: User,
as: 'createdByUser',
attributes: ['username', 'hashedId']
},
{
model: Forum,
as: 'forum',
attributes: ['id', 'name']
}
]
});
if (!topic) {
throw new Error('Topic not found.');
}
console.log('[ForumService.getTopic] - check user permissions');
const hasAccess = await this.checkForumAccess(topic.forum, user);
if (!hasAccess) {
throw new Error('Access denied.');
}
console.log('[ForumService.getTopic] - return topic');
return topic;
}
async addMessage(hashedUserId, topicId, content) {
console.log('[ForumService.addMessage] - start');
const user = await User.findOne({
where: {
hashedId: hashedUserId
}
});
if (!user) {
throw new Error('User not found.');
}
const topic = await Title.findByPk(topicId, {
include: [
{
model: Message,
as:'messages',
include: [
{
model: User,
as: 'lastMessageUser',
attributes: ['hashedId', 'username'],
order: [['createdAt', 'ASC']]
}
]
},
{
model: User,
as: 'createdByUser',
attributes: ['username', 'hashedId']
},
{
model: Forum,
as: 'forum',
attributes: ['id', 'name']
}
]
});
if (!topic) {
throw new Error('Topic not found.');
}
const hasAccess = await this.checkForumAccess(topic.forum, user);
if (!hasAccess) {
throw new Error('Access denied.');
}
console.log('[ForumService.addMessage] - create new message');
await Message.create({ titleId: topicId, text: content, createdBy: user.id });
await notifyAllUsers('messageschanged', { topicId, message });
console.log('[ForumService.addMessage] - return topic');
return this.getTopic(hashedUserId, topicId);
}
async checkForumAccess(forum, user) {
console.log('[ForumService.checkForumAccess] - start');
const { age } = user;
console.log('[ForumService.checkForumAccess] - read user permissions');
const userPermission = await ForumUserPermission.findOne({
where: {
userId: user.id,
forumId: forum.id
}
});
if (userPermission) {
return true;
}
console.log('[ForumService.checkForumAccess] - read forum permissions');
const forumPermissions = await ForumForumPermission.findAll({
where: {
forumId: forum.id
}
});
console.log('[ForumService.checkForumAccess] - filter persmissions');
for (const permission of forumPermissions) {
if (permission.permission === 'age' && age >= parseInt(permission.value, 10)) {
return true;
}
if (permission.permission === 'all' || permission.permission === 'user') {
return true;
}
const userRight = await UserRight.findOne({
where: {
userId: user.id,
},
include: {
model: UserRightType,
as: 'rightType',
where: {
[Op.or]: [
{ title: 'mainadmin' },
{ title: 'forum' }
]
}
}
});
if (userRight) {
return true;
}
}
console.log('[ForumService.checkForumAccess] - not successful');
return false;
}
async setPermissions(forumId, permissions) {
if (permissions && Array.isArray(permissions)) {
for (const permission of permissions) {
await ForumPermission.create({
forumId,
permission: permission.type,
value: permission.value
});
}
}
}
async checkAdminRights(userId) {
const userRight = await UserRight.findOne({
where: { userId },
include: {
model: UserRightType,
as: 'rightType',
where: { title: ['mainadmin', 'forum'] }
}
});
if (!userRight) {
throw new Error('Unauthorized: Only admins can perform this action.');
}
}
}
export default new ForumService();