Erster Aufbau Forum
This commit is contained in:
@@ -9,6 +9,7 @@ import adminRouter from './routers/adminRouter.js';
|
||||
import contactRouter from './routers/contactRouter.js';
|
||||
import cors from 'cors';
|
||||
import socialnetworkRouter from './routers/socialnetworkRouter.js';
|
||||
import forumRouter from './routers/forumRouter.js';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
@@ -33,6 +34,7 @@ app.use('/api/admin', adminRouter);
|
||||
app.use('/images', express.static(path.join(__dirname, '../frontend/public/images')));
|
||||
app.use('/api/contact', contactRouter);
|
||||
app.use('/api/socialnetwork', socialnetworkRouter);
|
||||
app.use('/api/forum', forumRouter);
|
||||
|
||||
app.use((req, res) => {
|
||||
res.status(404).send('404 Not Found');
|
||||
|
||||
64
backend/controllers/forumController.js
Normal file
64
backend/controllers/forumController.js
Normal file
@@ -0,0 +1,64 @@
|
||||
import forumService from '../services/forumService.js';
|
||||
|
||||
const forumController = {
|
||||
async createForum(req, res) {
|
||||
try {
|
||||
const { userid: userId } = req.headers;
|
||||
const { name, permissions } = req.body;
|
||||
const forum = await forumService.createForum(userId, name, permissions);
|
||||
res.status(201).json(forum);
|
||||
} catch (error) {
|
||||
console.error('Error in createForum:', error);
|
||||
res.status(400).json({ error: error.message });
|
||||
}
|
||||
},
|
||||
|
||||
async deleteForum(req, res) {
|
||||
try {
|
||||
const { userid: userId } = req.headers;
|
||||
const { forumId } = req.params;
|
||||
await forumService.deleteForum(userId, forumId);
|
||||
res.status(200).json({ message: 'Forum deleted successfully' });
|
||||
} catch (error) {
|
||||
console.error('Error in deleteForum:', error);
|
||||
res.status(400).json({ error: error.message });
|
||||
}
|
||||
},
|
||||
|
||||
async getAllForums(req, res) {
|
||||
try {
|
||||
const { userid: userId } = req.headers;
|
||||
const forums = await forumService.getAllForums(userId);
|
||||
res.status(200).json(forums);
|
||||
} catch (error) {
|
||||
console.error('Error in getAllForums:', error);
|
||||
res.status(400).json({ error: error.message });
|
||||
}
|
||||
},
|
||||
|
||||
async getForum(req, res) {
|
||||
try {
|
||||
const { userid: userId } = req.headers;
|
||||
const { forumId, page } = req.params;
|
||||
const forum = await forumService.getForum(userId, forumId, page);
|
||||
res.status(200).json(forum);
|
||||
} catch (error) {
|
||||
console.error('Error in getForum:', error);
|
||||
res.status(400).json({ error: error.message });
|
||||
}
|
||||
},
|
||||
|
||||
async createTopic(req, res) {
|
||||
try {
|
||||
const { userid: userId } = req.headers;
|
||||
const { forumId, title, content } = req.body;
|
||||
const result = await forumService.createTopic(userId, forumId, title, content);
|
||||
res.status(201).json(result);
|
||||
} catch (error) {
|
||||
console.error('Error in createTopic:', error);
|
||||
res.status(400).json({ error: error.message });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default forumController;
|
||||
@@ -254,9 +254,9 @@ class SocialNetworkController {
|
||||
|
||||
async updateDiaryEntry(req, res) {
|
||||
try {
|
||||
const { diaryId } = req.params;
|
||||
const { diaryEntryId } = req.params;
|
||||
const { userId, text } = req.body;
|
||||
const updatedEntry = await this.socialNetworkService.updateDiaryEntry(diaryId, userId, text);
|
||||
const updatedEntry = await this.socialNetworkService.updateDiaryEntry(diaryEntryId, userId, text);
|
||||
res.status(200).json(updatedEntry);
|
||||
} catch (error) {
|
||||
console.error('Error in updateDiaryEntry:', error);
|
||||
@@ -266,9 +266,9 @@ class SocialNetworkController {
|
||||
|
||||
async deleteDiaryEntry(req, res) {
|
||||
try {
|
||||
const { diaryId } = req.params;
|
||||
const { entryId } = req.params;
|
||||
const { userId } = req.body;
|
||||
const result = await this.socialNetworkService.deleteDiaryEntry(diaryId, userId);
|
||||
const result = await this.socialNetworkService.deleteDiaryEntry(entryId, userId);
|
||||
res.status(200).json({ message: 'Entry deleted successfully', result });
|
||||
} catch (error) {
|
||||
console.error('Error in deleteDiaryEntry:', error);
|
||||
@@ -278,8 +278,9 @@ class SocialNetworkController {
|
||||
|
||||
async getDiaryEntries(req, res) {
|
||||
try {
|
||||
const { userId } = req.params;
|
||||
const entries = await this.socialNetworkService.getDiaryEntries(userId);
|
||||
const { userid: userId} = req.headers;
|
||||
const { page } = req.params;
|
||||
const entries = await this.socialNetworkService.getDiaryEntries(userId, page);
|
||||
res.status(200).json(entries);
|
||||
} catch (error) {
|
||||
console.error('Error in getDiaryEntries:', error);
|
||||
|
||||
@@ -18,8 +18,18 @@ import FolderImageVisibility from './community/folder_image_visibility.js';
|
||||
import ImageImageVisibility from './community/image_image_visibility.js';
|
||||
import FolderVisibilityUser from './community/folder_visibility_user.js';
|
||||
import GuestbookEntry from './community/guestbook.js';
|
||||
import Forum from './forum/forum.js';
|
||||
import Title from './forum/title.js';
|
||||
import Message from './forum/message.js';
|
||||
import MessageImage from './forum/message_image.js';
|
||||
import MessageHistory from './forum/message_history.js';
|
||||
import TitleHistory from './forum/title_history.js';
|
||||
import ForumPermission from './forum/forum_permission.js';
|
||||
import ForumUserPermission from './forum/forum_user_permission.js';
|
||||
import ForumForumPermission from './forum/forum_forum_permission.js';
|
||||
|
||||
export default function setupAssociations() {
|
||||
// UserParam related associations
|
||||
SettingsType.hasMany(UserParamType, { foreignKey: 'settingsId', as: 'user_param_types' });
|
||||
UserParamType.belongsTo(SettingsType, { foreignKey: 'settingsId', as: 'settings_type' });
|
||||
|
||||
@@ -29,13 +39,19 @@ export default function setupAssociations() {
|
||||
User.hasMany(UserParam, { foreignKey: 'userId', as: 'user_params' });
|
||||
UserParam.belongsTo(User, { foreignKey: 'userId', as: 'user' });
|
||||
|
||||
// UserRight related associations
|
||||
UserRight.belongsTo(User, { foreignKey: 'userId', as: 'user_with_rights' });
|
||||
UserRight.belongsTo(UserRightType, { foreignKey: 'rightTypeId', as: 'rightType' });
|
||||
UserRightType.hasMany(UserRight, { foreignKey: 'rightTypeId', as: 'user_rights' });
|
||||
|
||||
UserParamType.hasMany(UserParamValue, { foreignKey: 'userParamTypeId', as: 'user_param_values' });
|
||||
UserParamValue.belongsTo(UserParamType, { foreignKey: 'userParamTypeId', as: 'user_param_type' });
|
||||
// UserParamVisibility related associations
|
||||
UserParam.hasMany(UserParamVisibility, { foreignKey: 'param_id', as: 'param_visibilities' });
|
||||
UserParamVisibility.belongsTo(UserParam, { foreignKey: 'param_id', as: 'param' });
|
||||
|
||||
UserParamVisibility.belongsTo(UserParamVisibilityType, { foreignKey: 'visibility', as: 'visibility_type' });
|
||||
UserParamVisibilityType.hasMany(UserParamVisibility, { foreignKey: 'visibility', as: 'user_param_visibilities' });
|
||||
|
||||
// Interest related associations
|
||||
InterestType.hasMany(InterestTranslationType, { foreignKey: 'interestsId', as: 'interest_translations' });
|
||||
InterestTranslationType.belongsTo(InterestType, { foreignKey: 'interestsId', as: 'interest_translations' });
|
||||
|
||||
@@ -44,14 +60,7 @@ export default function setupAssociations() {
|
||||
Interest.belongsTo(InterestType, { foreignKey: 'userinterestId', as: 'interest_type' });
|
||||
Interest.belongsTo(User, { foreignKey: 'userId', as: 'interest_owner' });
|
||||
|
||||
InterestTranslationType.belongsTo(UserParamValue, { foreignKey: 'language', targetKey: 'id', as: 'user_param_value' });
|
||||
|
||||
UserParam.hasMany(UserParamVisibility, { foreignKey: 'param_id', as: 'param_visibilities' });
|
||||
UserParamVisibility.belongsTo(UserParam, { foreignKey: 'param_id', as: 'param' });
|
||||
|
||||
UserParamVisibility.belongsTo(UserParamVisibilityType, { foreignKey: 'visibility', as: 'visibility_type' });
|
||||
UserParamVisibilityType.hasMany(UserParamVisibility, { foreignKey: 'visibility', as: 'user_param_visibilities' });
|
||||
|
||||
// Folder and Image related associations
|
||||
Folder.belongsTo(User, { foreignKey: 'userId' });
|
||||
User.hasMany(Folder, { foreignKey: 'userId' });
|
||||
|
||||
@@ -62,8 +71,9 @@ export default function setupAssociations() {
|
||||
Folder.hasMany(Image, { foreignKey: 'folderId' });
|
||||
|
||||
Image.belongsTo(User, { foreignKey: 'userId' });
|
||||
User.hasMany(Image, { foreignKey: 'userId' });
|
||||
User.hasMany(Image, { foreignKey: 'userId' });
|
||||
|
||||
// Image visibility associations
|
||||
Folder.belongsToMany(ImageVisibilityType, {
|
||||
through: FolderImageVisibility,
|
||||
foreignKey: 'folderId',
|
||||
@@ -97,24 +107,53 @@ export default function setupAssociations() {
|
||||
otherKey: 'folderId'
|
||||
});
|
||||
|
||||
User.hasMany(GuestbookEntry, {
|
||||
foreignKey: 'recipientId',
|
||||
as: 'receivedEntries'
|
||||
// Guestbook related associations
|
||||
User.hasMany(GuestbookEntry, { foreignKey: 'recipientId', as: 'receivedEntries' });
|
||||
User.hasMany(GuestbookEntry, { foreignKey: 'senderId', as: 'sentEntries' });
|
||||
GuestbookEntry.belongsTo(User, { foreignKey: 'recipientId', as: 'recipient' });
|
||||
GuestbookEntry.belongsTo(User, { foreignKey: 'senderId', as: 'sender' });
|
||||
|
||||
// Forum related associations
|
||||
Forum.hasMany(Title, { foreignKey: 'forumId' });
|
||||
Title.belongsTo(Forum, { foreignKey: 'forumId' });
|
||||
|
||||
Title.belongsTo(User, { foreignKey: 'createdBy', as: 'createdByUser' });
|
||||
User.hasMany(Title, { foreignKey: 'createdBy', as: 'titles' });
|
||||
|
||||
Title.hasMany(Message, { foreignKey: 'titleId', as: 'messages' });
|
||||
Message.belongsTo(Title, { foreignKey: 'titleId', as: 'title' });
|
||||
|
||||
Message.belongsTo(User, { foreignKey: 'createdBy', as: 'lastMessageUser' });
|
||||
User.hasMany(Message, { foreignKey: 'createdBy', as: 'userMessages' });
|
||||
|
||||
Message.hasMany(MessageImage, { foreignKey: 'messageId' });
|
||||
MessageImage.belongsTo(Message, { foreignKey: 'messageId' });
|
||||
|
||||
Message.hasMany(MessageHistory, { foreignKey: 'messageId' });
|
||||
MessageHistory.belongsTo(Message, { foreignKey: 'messageId' });
|
||||
|
||||
Title.hasMany(TitleHistory, { foreignKey: 'titleId' });
|
||||
TitleHistory.belongsTo(Title, { foreignKey: 'titleId' });
|
||||
|
||||
// Forum permissions associations
|
||||
Forum.hasMany(ForumUserPermission, { foreignKey: 'forumId', as: 'userPermissions' });
|
||||
ForumUserPermission.belongsTo(Forum, { foreignKey: 'forumId' });
|
||||
|
||||
User.hasMany(ForumUserPermission, { foreignKey: 'userId', as: 'userPermissions' });
|
||||
ForumUserPermission.belongsTo(User, { foreignKey: 'userId' });
|
||||
|
||||
Forum.belongsToMany(ForumPermission, {
|
||||
through: ForumForumPermission,
|
||||
foreignKey: 'forumId',
|
||||
as: 'associatedPermissions'
|
||||
});
|
||||
|
||||
User.hasMany(GuestbookEntry, {
|
||||
foreignKey: 'senderId',
|
||||
as: 'sentEntries'
|
||||
});
|
||||
|
||||
GuestbookEntry.belongsTo(User, {
|
||||
foreignKey: 'recipientId',
|
||||
as: 'recipient'
|
||||
});
|
||||
|
||||
GuestbookEntry.belongsTo(User, {
|
||||
foreignKey: 'senderId',
|
||||
as: 'sender'
|
||||
ForumPermission.belongsToMany(Forum, {
|
||||
through: ForumForumPermission,
|
||||
foreignKey: 'permissionId',
|
||||
as: 'forums'
|
||||
});
|
||||
|
||||
ForumPermission.hasMany(ForumUserPermission, { foreignKey: 'permissionId' });
|
||||
ForumUserPermission.belongsTo(ForumPermission, { foreignKey: 'permissionId' });
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ Diary.init({
|
||||
tableName: 'diary',
|
||||
schema: 'community',
|
||||
timestamps: true,
|
||||
underscored: true,
|
||||
});
|
||||
|
||||
export default Diary;
|
||||
|
||||
@@ -15,7 +15,7 @@ DiaryHistory.init({
|
||||
oldText: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: false,
|
||||
},
|
||||
},
|
||||
oldCreatedAt: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false,
|
||||
@@ -30,6 +30,7 @@ DiaryHistory.init({
|
||||
tableName: 'diary_history',
|
||||
schema: 'community',
|
||||
timestamps: false,
|
||||
underscored: true,
|
||||
});
|
||||
|
||||
export default DiaryHistory;
|
||||
|
||||
15
backend/models/forum/forum.js
Normal file
15
backend/models/forum/forum.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import { sequelize } from '../../utils/sequelize.js';
|
||||
import { DataTypes } from 'sequelize';
|
||||
|
||||
const Forum = sequelize.define('forum', {
|
||||
name: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
}
|
||||
}, {
|
||||
tableName: 'forum',
|
||||
schema: 'forum',
|
||||
underscored: true
|
||||
});
|
||||
|
||||
export default Forum;
|
||||
27
backend/models/forum/forum_forum_permission.js
Normal file
27
backend/models/forum/forum_forum_permission.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import { sequelize } from '../../utils/sequelize.js';
|
||||
import { DataTypes } from 'sequelize';
|
||||
|
||||
const ForumForumPermission = sequelize.define('forum_forum_permission', {
|
||||
forumId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
references: {
|
||||
model: 'forum',
|
||||
key: 'id'
|
||||
}
|
||||
},
|
||||
permissionId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
references: {
|
||||
model: 'forum_permission',
|
||||
key: 'id'
|
||||
}
|
||||
}
|
||||
}, {
|
||||
tableName: 'forum_forum_permission',
|
||||
schema: 'forum',
|
||||
underscored: true
|
||||
});
|
||||
|
||||
export default ForumForumPermission;
|
||||
22
backend/models/forum/forum_permission.js
Normal file
22
backend/models/forum/forum_permission.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import { sequelize } from '../../utils/sequelize.js';
|
||||
import { DataTypes } from 'sequelize';
|
||||
|
||||
const ForumPermission = sequelize.define('forum_permission', {
|
||||
name: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
value: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
},
|
||||
}, {
|
||||
sequelize,
|
||||
modelName: 'ForumPermission',
|
||||
tableName: 'forum_permission',
|
||||
schema: 'forum',
|
||||
timestamps: false,
|
||||
underscored: true
|
||||
});
|
||||
|
||||
export default ForumPermission;
|
||||
23
backend/models/forum/forum_user_permission.js
Normal file
23
backend/models/forum/forum_user_permission.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import { sequelize } from '../../utils/sequelize.js';
|
||||
import { DataTypes } from 'sequelize';
|
||||
|
||||
const ForumUserPermission = sequelize.define('forum_user_permission', {
|
||||
userId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true
|
||||
},
|
||||
permissionId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false
|
||||
},
|
||||
forumId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false
|
||||
},
|
||||
}, {
|
||||
tableName: 'forum_user_permission',
|
||||
schema: 'forum',
|
||||
underscored: true
|
||||
});
|
||||
|
||||
export default ForumUserPermission;
|
||||
24
backend/models/forum/message.js
Normal file
24
backend/models/forum/message.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import { sequelize } from '../../utils/sequelize.js';
|
||||
import { DataTypes } from 'sequelize';
|
||||
|
||||
const Message = sequelize.define('message', {
|
||||
text: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: false
|
||||
},
|
||||
createdBy: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false
|
||||
},
|
||||
titleId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false
|
||||
}
|
||||
}, {
|
||||
tableName: 'message',
|
||||
schema: 'forum',
|
||||
underscored: true,
|
||||
timestamps: true
|
||||
});
|
||||
|
||||
export default Message;
|
||||
28
backend/models/forum/message_history.js
Normal file
28
backend/models/forum/message_history.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import { sequelize } from '../../utils/sequelize.js';
|
||||
import { DataTypes } from 'sequelize';
|
||||
|
||||
const MessageHistory = sequelize.define('message_history', {
|
||||
messageId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false
|
||||
},
|
||||
oldText: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: false
|
||||
},
|
||||
changedBy: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false
|
||||
},
|
||||
oldUpdatedAt: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false
|
||||
}
|
||||
}, {
|
||||
tableName: 'message_history',
|
||||
schema: 'forum',
|
||||
underscored: true,
|
||||
timestamps: false
|
||||
});
|
||||
|
||||
export default MessageHistory;
|
||||
20
backend/models/forum/message_image.js
Normal file
20
backend/models/forum/message_image.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import { sequelize } from '../../utils/sequelize.js';
|
||||
import { DataTypes } from 'sequelize';
|
||||
|
||||
const MessageImage = sequelize.define('message_image', {
|
||||
messageId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false
|
||||
},
|
||||
fileName: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
}
|
||||
}, {
|
||||
tableName: 'message_image',
|
||||
schema: 'forum',
|
||||
underscored: true,
|
||||
timestamps: false
|
||||
});
|
||||
|
||||
export default MessageImage;
|
||||
24
backend/models/forum/title.js
Normal file
24
backend/models/forum/title.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import { sequelize } from '../../utils/sequelize.js';
|
||||
import { DataTypes } from 'sequelize';
|
||||
|
||||
const Title = sequelize.define('title', {
|
||||
title: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
createdBy: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false
|
||||
},
|
||||
forumId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false
|
||||
}
|
||||
}, {
|
||||
tableName: 'title',
|
||||
schema: 'forum',
|
||||
underscored: true,
|
||||
timestamps: true,
|
||||
});
|
||||
|
||||
export default Title;
|
||||
28
backend/models/forum/title_history.js
Normal file
28
backend/models/forum/title_history.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import { sequelize } from '../../utils/sequelize.js';
|
||||
import { DataTypes } from 'sequelize';
|
||||
|
||||
const TitleHistory = sequelize.define('title_history', {
|
||||
titleId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false
|
||||
},
|
||||
oldTitle: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
changedBy: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false
|
||||
},
|
||||
oldUpdatedAt: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false
|
||||
}
|
||||
}, {
|
||||
tableName: 'title_history',
|
||||
schema: 'forum',
|
||||
underscored: true,
|
||||
timestamps: false
|
||||
});
|
||||
|
||||
export default TitleHistory;
|
||||
@@ -22,6 +22,15 @@ import FolderVisibilityUser from './community/folder_visibility_user.js';
|
||||
import GuestbookEntry from './community/guestbook.js';
|
||||
import DiaryHistory from './community/diary_history.js';
|
||||
import Diary from './community/diary.js';
|
||||
import Forum from './forum/forum.js';
|
||||
import ForumPermission from './forum/forum_permission.js';
|
||||
import ForumUserPermission from './forum/forum_user_permission.js';
|
||||
import Title from './forum/title.js';
|
||||
import TitleHistory from './forum/title_history.js';
|
||||
import Message from './forum/message.js';
|
||||
import MessageHistory from './forum/message_history.js';
|
||||
import MessageImage from './forum/message_image.js';
|
||||
import ForumForumPermission from './forum/forum_forum_permission.js';
|
||||
|
||||
const models = {
|
||||
SettingsType,
|
||||
@@ -48,6 +57,15 @@ const models = {
|
||||
GuestbookEntry,
|
||||
DiaryHistory,
|
||||
Diary,
|
||||
Forum,
|
||||
ForumPermission,
|
||||
ForumForumPermission,
|
||||
ForumUserPermission,
|
||||
Title,
|
||||
TitleHistory,
|
||||
Message,
|
||||
MessageHistory,
|
||||
MessageImage,
|
||||
};
|
||||
|
||||
export default models;
|
||||
|
||||
@@ -16,6 +16,12 @@ export async function createTriggers() {
|
||||
SELECT id FROM type.user_param_visibility WHERE description = 'Invisible'
|
||||
));
|
||||
END IF;
|
||||
|
||||
-- If NEW is null, then we have nothing to do
|
||||
IF NEW IS NULL THEN
|
||||
RETURN NULL;
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
@@ -25,6 +31,7 @@ export async function createTriggers() {
|
||||
CREATE OR REPLACE TRIGGER trigger_create_user_param_visibility
|
||||
AFTER INSERT ON community.user_param
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.id IS NOT NULL)
|
||||
EXECUTE FUNCTION create_user_param_visibility_trigger();
|
||||
`;
|
||||
|
||||
@@ -32,6 +39,7 @@ export async function createTriggers() {
|
||||
CREATE OR REPLACE TRIGGER trigger_update_user_param_visibility
|
||||
AFTER UPDATE ON community.user_param
|
||||
FOR EACH ROW
|
||||
WHEN (NEW.id IS NOT NULL)
|
||||
EXECUTE FUNCTION create_user_param_visibility_trigger();
|
||||
`;
|
||||
|
||||
@@ -39,8 +47,14 @@ export async function createTriggers() {
|
||||
CREATE OR REPLACE FUNCTION insert_diary_history()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
INSERT INTO community.diary_history (diaryId, userId, oldText, oldCreatedAt, oldUpdatedAt)
|
||||
VALUES (OLD.id, OLD.userId, OLD.text, OLD.createdAt, OLD.updatedAt);
|
||||
INSERT INTO community.diary_history (diary_id, user_id, old_text, old_created_at, old_updated_at)
|
||||
VALUES (OLD.id, OLD.user_id, OLD.text, OLD.created_at, OLD.updated_at);
|
||||
|
||||
-- If NEW is null, then we have nothing to do
|
||||
IF NEW IS NULL THEN
|
||||
RETURN NULL;
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
@@ -50,18 +64,41 @@ export async function createTriggers() {
|
||||
CREATE OR REPLACE TRIGGER diary_update_trigger
|
||||
BEFORE UPDATE ON community.diary
|
||||
FOR EACH ROW
|
||||
WHEN (OLD.id IS NOT NULL)
|
||||
EXECUTE FUNCTION insert_diary_history();
|
||||
`;
|
||||
|
||||
const createTitleHistoryTriggerFunction = `
|
||||
CREATE OR REPLACE FUNCTION insert_title_history()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
INSERT INTO forum.title_history (title_id, old_title, changed_by, old_updated_at)
|
||||
VALUES (OLD.id, OLD.title, OLD.created_by, OLD.updated_at);
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
`;
|
||||
|
||||
const createTitleHistoryTrigger = `
|
||||
CREATE OR REPLACE TRIGGER title_update_trigger
|
||||
BEFORE UPDATE ON forum.title
|
||||
FOR EACH ROW
|
||||
WHEN (OLD.id IS NOT NULL)
|
||||
EXECUTE FUNCTION insert_title_history();
|
||||
`;
|
||||
|
||||
try {
|
||||
await sequelize.query(createTriggerFunction);
|
||||
await sequelize.query(createInsertTrigger);
|
||||
await sequelize.query(createUpdateTrigger);
|
||||
await sequelize.query(createDiaryHistoryTriggerFunction);
|
||||
await sequelize.query(createDiaryHistoryTrigger);
|
||||
await sequelize.query(createTitleHistoryTriggerFunction);
|
||||
await sequelize.query(createTitleHistoryTrigger);
|
||||
|
||||
console.log('Triggers created successfully');
|
||||
} catch (error) {
|
||||
console.error('Error creating triggers:', error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
15
backend/routers/forumRouter.js
Normal file
15
backend/routers/forumRouter.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Router } from 'express';
|
||||
import forumController from '../controllers/forumController.js';
|
||||
import { authenticate } from '../middleware/authMiddleware.js';
|
||||
|
||||
const forumRouter = Router();
|
||||
|
||||
forumRouter.use(authenticate);
|
||||
|
||||
forumRouter.post('/topic', forumController.createTopic);
|
||||
forumRouter.post('/', forumController.createForum);
|
||||
forumRouter.delete('/:forumId', forumController.deleteForum);
|
||||
forumRouter.get('/:forumId/:page', forumController.getForum);
|
||||
forumRouter.get('/', forumController.getAllForums);
|
||||
|
||||
export default forumRouter;
|
||||
@@ -24,8 +24,8 @@ router.get('/guestbook/entries/:username/:page', authenticate, socialNetworkCont
|
||||
router.delete('/guestbook/entries/:entryId', authenticate, socialNetworkController.deleteGuestbookEntry);
|
||||
router.get('/guestbook/image/:guestbookUserName/:entryId', authenticate, socialNetworkController.getGuestbookImage);
|
||||
router.post('/diary', authenticate, socialNetworkController.createDiaryEntry);
|
||||
router.put('/diary/:diaryId', authenticate, socialNetworkController.updateDiaryEntry);
|
||||
router.delete('/diary/:diaryId', authenticate, socialNetworkController.deleteDiaryEntry);
|
||||
router.get('/diary/:userId', authenticate, socialNetworkController.getDiaryEntries);
|
||||
router.put('/diary/:diaryEntryId', authenticate, socialNetworkController.updateDiaryEntry);
|
||||
router.delete('/diary/:entryId', authenticate, socialNetworkController.deleteDiaryEntry);
|
||||
router.get('/diary/:page', authenticate, socialNetworkController.getDiaryEntries);
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -4,6 +4,8 @@ import UserParamType from '../models/type/user_param.js';
|
||||
import UserParamVisibility from '../models/community/user_param_visibility.js';
|
||||
import UserParamVisibilityType from '../models/type/user_param_visibility.js';
|
||||
import { Op } from 'sequelize';
|
||||
import UserRight from '../models/community/user_right.js';
|
||||
import UserRightType from '../models/type/user_right.js';
|
||||
|
||||
class BaseService {
|
||||
async getUserByHashedId(hashedId) {
|
||||
@@ -63,6 +65,33 @@ class BaseService {
|
||||
return age >= 18;
|
||||
}
|
||||
|
||||
async checkUserAccess(hashedId) {
|
||||
const user = await this.getUserByHashedId(hashedId);
|
||||
if (!user || !user.active) throw new Error('Access denied: User not found or inactive');
|
||||
return user.id;
|
||||
}
|
||||
|
||||
async getUserRights(userId) {
|
||||
const userRights = await UserRight.findAll({
|
||||
where: { userId },
|
||||
include: [
|
||||
{
|
||||
model: UserRightType,
|
||||
as: 'rightType',
|
||||
attributes: ['title']
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
return userRights.map((right) => right.rightType.title);
|
||||
}
|
||||
|
||||
async hasUserRight(userId, requiredRights) {
|
||||
console.log(requiredRights);
|
||||
const userRights = await this.getUserRights(userId);
|
||||
return userRights.some((right) => requiredRights.includes(right));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default BaseService;
|
||||
|
||||
280
backend/services/forumService.js
Normal file
280
backend/services/forumService.js
Normal file
@@ -0,0 +1,280 @@
|
||||
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';
|
||||
|
||||
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.value }
|
||||
});
|
||||
if (forumPermission) {
|
||||
await newForum.addAssociatedPermissions(forumPermission);
|
||||
}
|
||||
}
|
||||
}
|
||||
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();
|
||||
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})
|
||||
return this.getForum(hashedUserId, forumId, 1);
|
||||
}
|
||||
|
||||
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();
|
||||
@@ -22,6 +22,7 @@ import GuestbookEntry from '../models/community/guestbook.js';
|
||||
import { JSDOM } from 'jsdom';
|
||||
import DOMPurify from 'dompurify';
|
||||
import sharp from 'sharp';
|
||||
import Diary from '../models/community/diary.js';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
@@ -42,9 +43,7 @@ class SocialNetworkService extends BaseService {
|
||||
|
||||
async createFolder(hashedUserId, data, folderId) {
|
||||
await this.checkUserAccess(hashedUserId);
|
||||
const user = await User.findOne({
|
||||
where: { hashedId: hashedUserId }
|
||||
});
|
||||
const user = await this.loadUserByHash(hashedUserId);
|
||||
if (!user) {
|
||||
throw new Error('User not found');
|
||||
}
|
||||
@@ -266,10 +265,12 @@ class SocialNetworkService extends BaseService {
|
||||
return image;
|
||||
}
|
||||
|
||||
async checkUserAccess(hashedId) {
|
||||
const user = await User.findOne({ hashedId: hashedId });
|
||||
if (!user || !user.active) throw new Error('Access denied: User not found or inactive');
|
||||
return user.id;
|
||||
async loadUserByHash(hashedId) {
|
||||
return await User.findOne({ hashedId });
|
||||
}
|
||||
|
||||
async loadUserByName(userName) {
|
||||
return await User.findOne({ username: userName});
|
||||
}
|
||||
|
||||
validateFolderData(data) {
|
||||
@@ -354,9 +355,7 @@ class SocialNetworkService extends BaseService {
|
||||
|
||||
async constructUserProfile(user, hashedUserId) {
|
||||
const userParams = {};
|
||||
const requestingUser = await User.findOne({
|
||||
where: { hashedId: hashedUserId },
|
||||
});
|
||||
const requestingUser = await this.loadUserByHash(hashedUserId);
|
||||
if (!requestingUser) {
|
||||
throw new Error('User not found');
|
||||
}
|
||||
@@ -461,7 +460,7 @@ class SocialNetworkService extends BaseService {
|
||||
}
|
||||
|
||||
async getFoldersByUsername(username, hashedUserId) {
|
||||
const user = await User.findOne({ where: { username } });
|
||||
const user = await this.loadUserByName(username);
|
||||
if (!user) {
|
||||
throw new Error('User not found');
|
||||
}
|
||||
@@ -528,11 +527,11 @@ class SocialNetworkService extends BaseService {
|
||||
}
|
||||
|
||||
async createGuestbookEntry(hashedSenderId, recipientName, htmlContent, image) {
|
||||
const sender = await User.findOne({ where: { hashedId: hashedSenderId } });
|
||||
const sender = await this.loadUserByHash(hashedSenderId);
|
||||
if (!sender) {
|
||||
throw new Error('Sender not found');
|
||||
}
|
||||
const recipient = await User.findOne({ where: { username: recipientName } });
|
||||
const recipient = await this.loadUserByName(recipientName);
|
||||
if (!recipient) {
|
||||
throw new Error('Recipient not found');
|
||||
}
|
||||
@@ -594,7 +593,7 @@ class SocialNetworkService extends BaseService {
|
||||
const pageSize = 20;
|
||||
const offset = (page - 1) * pageSize;
|
||||
this.checkUserAccess(hashedUserId);
|
||||
const user = await User.findOne({ where: { username: username } });
|
||||
const user = await this.loadUserByName(username);
|
||||
if (!user) {
|
||||
throw new Error('User not found');
|
||||
}
|
||||
@@ -624,9 +623,7 @@ class SocialNetworkService extends BaseService {
|
||||
async getGuestbookImageFilePath(hashedUserId, guestbookOwnerName, entryId) {
|
||||
await this.checkUserAccess(hashedUserId);
|
||||
|
||||
const guestbookOwner = await User.findOne({
|
||||
where: { username: guestbookOwnerName },
|
||||
});
|
||||
const guestbookOwner = await this.loadUserByName(guestbookOwnerName);
|
||||
if (!guestbookOwner) {
|
||||
throw new Error('usernotfound');
|
||||
}
|
||||
@@ -649,7 +646,7 @@ class SocialNetworkService extends BaseService {
|
||||
}
|
||||
|
||||
async deleteGuestbookEntry(hashedUserId, entryId) {
|
||||
const user = await User.findOne({ where: { hashedId: hashedUserId } });
|
||||
const user = await this.loadUserByHash(hashedUserId);
|
||||
if (!user) {
|
||||
throw new Error('User not found');
|
||||
}
|
||||
@@ -663,7 +660,8 @@ class SocialNetworkService extends BaseService {
|
||||
await entry.destroy();
|
||||
}
|
||||
|
||||
async createDiaryEntry(userId, text) {
|
||||
async createDiaryEntry(hashedUserId, text) {
|
||||
const userId = await this.checkUserAccess(hashedUserId);
|
||||
const newEntry = await Diary.create({
|
||||
userId: userId,
|
||||
text: text,
|
||||
@@ -673,29 +671,24 @@ class SocialNetworkService extends BaseService {
|
||||
return newEntry;
|
||||
}
|
||||
|
||||
async updateDiaryEntry(diaryId, userId, newText) {
|
||||
async updateDiaryEntry(diaryEntryId, hashedUserId, newText) {
|
||||
const userId = await this.checkUserAccess(hashedUserId);
|
||||
const existingEntry = await Diary.findOne({
|
||||
where: { id: diaryId, userId: userId }
|
||||
where: { id: diaryEntryId, userId: userId }
|
||||
});
|
||||
if (!existingEntry) {
|
||||
throw new Error('Diary entry not found or unauthorized access');
|
||||
}
|
||||
await DiaryHistory.create({
|
||||
diaryId: existingEntry.id,
|
||||
userId: existingEntry.userId,
|
||||
oldText: existingEntry.text,
|
||||
oldCreatedAt: existingEntry.createdAt,
|
||||
oldUpdatedAt: existingEntry.updatedAt,
|
||||
});
|
||||
existingEntry.text = newText;
|
||||
existingEntry.updatedAt = new Date();
|
||||
await existingEntry.save();
|
||||
return existingEntry;
|
||||
}
|
||||
|
||||
async deleteDiaryEntry(diaryId, userId) {
|
||||
async deleteDiaryEntry(diaryEntryId, hashedUserId) {
|
||||
const userId = await this.checkUserAccess(hashedUserId);
|
||||
const entryToDelete = await Diary.findOne({
|
||||
where: { id: diaryId, userId: userId }
|
||||
where: { id: diaryEntryId, userId: userId }
|
||||
});
|
||||
if (!entryToDelete) {
|
||||
throw new Error('Diary entry not found or unauthorized access');
|
||||
@@ -704,13 +697,15 @@ class SocialNetworkService extends BaseService {
|
||||
return true;
|
||||
}
|
||||
|
||||
async getDiaryEntries(userId) {
|
||||
const entries = await Diary.findAll({
|
||||
async getDiaryEntries(hashedUserId, page) {
|
||||
const userId = await this.checkUserAccess(hashedUserId);
|
||||
const entries = await Diary.findAndCountAll({
|
||||
where: { userId: userId },
|
||||
order: [['createdAt', 'DESC']]
|
||||
order: [['createdAt', 'DESC']],
|
||||
offset: (page - 1) * 20,
|
||||
limit: 20,
|
||||
});
|
||||
return entries;
|
||||
return { entries: entries.rows, totalPages: Math.ceil(entries.count / 20) };
|
||||
}
|
||||
}
|
||||
|
||||
export default SocialNetworkService;
|
||||
export default SocialNetworkService;
|
||||
|
||||
48
backend/utils/initializeForum.js
Normal file
48
backend/utils/initializeForum.js
Normal file
@@ -0,0 +1,48 @@
|
||||
import Forum from '../models/forum/forum.js';
|
||||
import ForumPermission from '../models/forum/forum_permission.js';
|
||||
import ForumForumPermission from '../models/forum/forum_forum_permission.js';
|
||||
|
||||
const initializeForum = async () => {
|
||||
const permissions = [
|
||||
{ name: 'all', value: null },
|
||||
{ name: 'user', value: null },
|
||||
{ name: 'admin', value: null },
|
||||
{ name: 'age', value: '14' },
|
||||
{ name: 'teammember', value: null }
|
||||
];
|
||||
const forums = [
|
||||
{ name: 'Intern', permissions: ['admin', 'teammember'] },
|
||||
{ name: 'Flirt', permissions: ['age'] },
|
||||
{ name: 'Falukant', permissions: ['all'] },
|
||||
{ name: 'Politik', permissions: ['all'] },
|
||||
{ name: 'Schule', permissions: ['all'] }
|
||||
];
|
||||
const permissionMap = {};
|
||||
for (const perm of permissions) {
|
||||
const [permission] = await ForumPermission.findOrCreate({
|
||||
where: { name: perm.name },
|
||||
defaults: { name: perm.name, value: perm.value }
|
||||
});
|
||||
permissionMap[perm.name] = permission.id;
|
||||
}
|
||||
for (const forum of forums) {
|
||||
try {
|
||||
const [createdForum] = await Forum.findOrCreate({
|
||||
where: { name: forum.name },
|
||||
defaults: { name: forum.name }
|
||||
});
|
||||
for (const permissionName of forum.permissions) {
|
||||
const permissionId = permissionMap[permissionName];
|
||||
await ForumForumPermission.findOrCreate({
|
||||
where: { forumId: createdForum.id, permissionId: permissionId },
|
||||
defaults: { forumId: createdForum.id, permissionId: permissionId },
|
||||
});
|
||||
}
|
||||
console.log(`Forum '${forum.name}' erfolgreich erstellt oder aktualisiert.`);
|
||||
} catch (error) {
|
||||
console.error(`Fehler beim Erstellen des Forums '${forum.name}': ${error.message}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default initializeForum;
|
||||
@@ -16,6 +16,7 @@ const createSchemas = async () => {
|
||||
await sequelize.query('CREATE SCHEMA IF NOT EXISTS logs');
|
||||
await sequelize.query('CREATE SCHEMA IF NOT EXISTS type');
|
||||
await sequelize.query('CREATE SCHEMA IF NOT EXISTS service');
|
||||
await sequelize.query('CREATE SCHEMA IF NOT EXISTS forum');
|
||||
};
|
||||
|
||||
const initializeDatabase = async () => {
|
||||
@@ -25,8 +26,8 @@ const initializeDatabase = async () => {
|
||||
};
|
||||
|
||||
const syncModels = async (models) => {
|
||||
for (const model of Object.values(models)) {
|
||||
await model.sync({ alter: true });
|
||||
for (const model of Object.values(models)) {
|
||||
await model.sync({ alter: true, force: false });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// syncDatabase.js
|
||||
|
||||
import { initializeDatabase, syncModels } from './sequelize.js';
|
||||
import initializeTypes from './initializeTypes.js';
|
||||
import initializeSettings from './initializeSettings.js';
|
||||
@@ -6,18 +8,38 @@ import initializeImageTypes from './initializeImageTypes.js';
|
||||
import setupAssociations from '../models/associations.js';
|
||||
import models from '../models/index.js';
|
||||
import { createTriggers } from '../models/trigger.js';
|
||||
import initializeForum from './initializeForum.js';
|
||||
|
||||
const syncDatabase = async () => {
|
||||
try {
|
||||
await initializeDatabase();
|
||||
await syncModels(models);
|
||||
setupAssociations();
|
||||
createTriggers();
|
||||
console.log("Initializing database schemas...");
|
||||
await initializeDatabase(); // Stellt sicher, dass alle Schemas erstellt sind
|
||||
|
||||
await initializeSettings();
|
||||
await initializeTypes();
|
||||
await initializeUserRights();
|
||||
await initializeImageTypes();
|
||||
console.log("Synchronizing models...");
|
||||
await syncModels(models); // Modelle synchronisieren
|
||||
|
||||
console.log("Setting up associations...");
|
||||
setupAssociations(); // Assoziationen definieren
|
||||
|
||||
console.log("Creating triggers...");
|
||||
await createTriggers(); // Trigger erstellen
|
||||
|
||||
console.log("Initializing settings...");
|
||||
await initializeSettings(); // Einstellungsdaten initialisieren
|
||||
|
||||
console.log("Initializing types...");
|
||||
await initializeTypes(); // Typen initialisieren
|
||||
|
||||
console.log("Initializing user rights...");
|
||||
await initializeUserRights(); // Benutzerrechte initialisieren
|
||||
|
||||
console.log("Initializing image types...");
|
||||
await initializeImageTypes(); // Bildtypen initialisieren
|
||||
|
||||
console.log("Initializing forums...");
|
||||
await initializeForum(); // Foren initialisieren
|
||||
|
||||
console.log('Database synchronization complete.');
|
||||
} catch (error) {
|
||||
console.error('Unable to synchronize the database:', error);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user