nakama/backend/routes/moderation.js

167 lines
5.0 KiB
JavaScript

const express = require('express');
const router = express.Router();
const { authenticate, requireModerator } = require('../middleware/auth');
const Report = require('../models/Report');
const Post = require('../models/Post');
const User = require('../models/User');
// Создать репорт
router.post('/report', authenticate, async (req, res) => {
try {
const { postId, reason } = req.body;
if (!postId || !reason) {
return res.status(400).json({ error: 'postId и reason обязательны' });
}
const post = await Post.findById(postId);
if (!post) {
return res.status(404).json({ error: 'Пост не найден' });
}
const report = new Report({
reporter: req.user._id,
post: postId,
reason
});
await report.save();
res.status(201).json({
message: 'Жалоба отправлена',
report
});
} catch (error) {
console.error('Ошибка создания репорта:', error);
res.status(500).json({ error: 'Ошибка сервера' });
}
});
// Получить все репорты (только модераторы)
router.get('/reports', authenticate, requireModerator, async (req, res) => {
try {
const { status = 'pending', page = 1, limit = 20 } = req.query;
const query = status === 'all' ? {} : { status };
const reports = await Report.find(query)
.populate('reporter', 'username firstName lastName')
.populate('post')
.populate('reviewedBy', 'username firstName lastName')
.sort({ createdAt: -1 })
.limit(limit * 1)
.skip((page - 1) * limit)
.exec();
const count = await Report.countDocuments(query);
res.json({
reports,
totalPages: Math.ceil(count / limit),
currentPage: page
});
} catch (error) {
console.error('Ошибка получения репортов:', error);
res.status(500).json({ error: 'Ошибка сервера' });
}
});
// Обработать репорт (только модераторы)
router.put('/reports/:id', authenticate, requireModerator, async (req, res) => {
try {
const { status, action } = req.body; // action: 'delete_post', 'ban_user', 'dismiss'
const report = await Report.findById(req.params.id).populate('post');
if (!report) {
return res.status(404).json({ error: 'Репорт не найден' });
}
report.status = status || 'reviewed';
report.reviewedBy = req.user._id;
// Выполнить действие
if (action === 'delete_post' && report.post) {
await Post.findByIdAndDelete(report.post._id);
report.status = 'resolved';
} else if (action === 'ban_user' && report.post) {
const author = await User.findById(report.post.author);
if (author) {
author.banned = true;
author.bannedUntil = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000); // 7 дней
await author.save();
}
report.status = 'resolved';
} else if (action === 'dismiss') {
report.status = 'dismissed';
}
await report.save();
res.json({
message: 'Репорт обработан',
report
});
} catch (error) {
console.error('Ошибка обработки репорта:', error);
res.status(500).json({ error: 'Ошибка сервера' });
}
});
// Установить NSFW флаг (модераторы)
router.put('/posts/:id/nsfw', authenticate, requireModerator, async (req, res) => {
try {
const { isNSFW } = req.body;
const post = await Post.findById(req.params.id);
if (!post) {
return res.status(404).json({ error: 'Пост не найден' });
}
post.isNSFW = isNSFW;
await post.save();
res.json({
message: 'NSFW статус обновлен',
post
});
} catch (error) {
console.error('Ошибка обновления NSFW:', error);
res.status(500).json({ error: 'Ошибка сервера' });
}
});
// Заблокировать/разблокировать пользователя (модераторы)
router.put('/users/:id/ban', authenticate, requireModerator, async (req, res) => {
try {
const { banned, days } = req.body;
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({ error: 'Пользователь не найден' });
}
user.banned = banned;
if (banned && days) {
user.bannedUntil = new Date(Date.now() + days * 24 * 60 * 60 * 1000);
} else {
user.bannedUntil = null;
}
await user.save();
res.json({
message: banned ? 'Пользователь заблокирован' : 'Пользователь разблокирован',
user
});
} catch (error) {
console.error('Ошибка блокировки пользователя:', error);
res.status(500).json({ error: 'Ошибка сервера' });
}
});
module.exports = router;