improvements to removebans and deleteboards controllers, and adjustments to combine global and board manage routes

merge-requests/208/head
fatchan 5 years ago
parent 4e2a6aea2e
commit e17d7e2305
  1. 88
      controllers/forms.js
  2. 11
      helpers/paramconverter.js
  3. 27
      models/forms/deleteboard.js
  4. 8
      models/forms/removebans.js
  5. 17
      views/pages/globalmanage.pug

@ -5,9 +5,6 @@ const express = require('express')
, { enableUserBoards } = require(__dirname+'/../configs/main.json')
, Boards = require(__dirname+'/../db/boards.js')
, Posts = require(__dirname+'/../db/posts.js')
, Bans = require(__dirname+'/../db/bans.js')
, Mongo = require(__dirname+'/../db/db.js')
, { remove } = require('fs-extra')
, upload = require('express-fileupload')
, path = require('path')
, alphaNumericRegex = /^[a-zA-Z0-9]+$/
@ -37,10 +34,10 @@ const express = require('express')
})
, removeBans = require(__dirname+'/../models/forms/removebans.js')
, makePost = require(__dirname+'/../models/forms/makepost.js')
, deletePosts = require(__dirname+'/../models/forms/deletepost.js')
, deleteTempFiles = require(__dirname+'/../helpers/files/deletetempfiles.js')
, uploadBanners = require(__dirname+'/../models/forms/uploadbanners.js')
, deleteBanners = require(__dirname+'/../models/forms/deletebanners.js')
, deleteBoard = require(__dirname+'/../models/forms/deleteboard.js')
, loginAccount = require(__dirname+'/../models/forms/login.js')
, changePassword = require(__dirname+'/../models/forms/changepassword.js')
, changeBoardSettings = require(__dirname+'/../models/forms/changeboardsettings.js')
@ -610,7 +607,9 @@ async function globalActionController(req, res, next) {
}
//unban
router.post('/board/:board/unban', csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(3), paramConverter, async (req, res, next) => {
router.post('/global/unban', csrf, calcPerms, isLoggedIn, hasPerms(1), paramConverter, removeBansController);
router.post('/board/:board/unban', csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(3), paramConverter, removeBansController);
async function removeBansController(req, res, next) {
//keep this for later in case i add other options to unbans
const errors = [];
@ -619,101 +618,78 @@ router.post('/board/:board/unban', csrf, Boards.exists, calcPerms, banCheck, isL
errors.push('Must select 1-10 bans')
}
const redirect = req.params.board ? `/${req.params.board}/manage.html` : '/globalmanage.html';
if (errors.length > 0) {
return res.status(400).render('message', {
'title': 'Bad request',
'errors': errors,
'redirect': `/${req.params.board}/manage.html`
redirect
});
}
const messages = [];
let amount = 0;
try {
messages.push((await removeBans(req, res, next)));
amount = await removeBans(req, res, next);
} catch (err) {
return next(err);
}
return res.render('message', {
'title': 'Success',
'messages': messages,
'redirect': `/${req.params.board}/manage.html`
'message': `Removed ${amount} bans`,
redirect
});
});
}
//delete board
router.post('/board/:board/deleteboard', csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(2), async (req, res, next) => {
router.post('/board/:board/deleteboard', csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(2), deleteBoardController);
router.post('/global/deleteboard', csrf, calcPerms, isLoggedIn, hasPerms(1), deleteBoardController);
async function deleteBoardController(req, res, next) {
const errors = [];
if (!req.body.confirm) {
errors.push('Missing confirmation');
}
if (!req.body.uri || req.body.uri !== req.params.board) {
errors.push('URI does not match')
}
if (errors.length > 0) {
return res.status(400).render('message', {
'title': 'Bad request',
'errors': errors,
'redirect': `/${req.params.board}/manage.html`
});
if (!req.body.uri) {
errors.push('Missing URI');
}
try {
//todo: move this to separate model file
// could be slow, might also wanna use projection to just get the files and other info necessary for deleteposts model
await Boards.deleteOne(res.locals.board._id);
const allPosts = await Posts.allBoardPosts(res.locals.board._id);
if (allPosts.length > 0) {
await deletePosts(allPosts, res.locals.board._id, true);
if (alphaNumericRegex.test(req.body.uri) !== true) {
errors.push('URI must contain a-z 0-9 only');
} else {
//no need to check these if the board name is completely invalid
if (req.params.board != null && req.params.board !== req.body.uri) {
//board manage page to not be able to delete other boards;
errors.push('URI does not match current board');
} else if (!(await Boards.findOne(req.body.uri))) {
//global must chech exist because it skips Boards.exists middleware
errors.push(`Board /${req.body.uri}/ does not exist`);
}
await Bans.deleteBoard(res.locals.board._id);
await remove(`${uploadDirectory}html/${req.params.board}/`)
} catch (err) {
return next(err);
}
return res.render('message', {
'title': 'Success',
'message': 'Board deleted',
'redirect': '/'
});
});
router.post('/global/unban', csrf, calcPerms, isLoggedIn, hasPerms(1), paramConverter, async(req, res, next) => {
const errors = [];
if (!req.body.checkedbans || req.body.checkedbans.length === 0 || req.body.checkedbans.length > 10) {
errors.push('Must select 1-10 bans')
}
if (errors.length > 0) {
return res.status(400).render('message', {
'title': 'Bad request',
'errors': errors,
'redirect': `/globalmanage.html`
'redirect': req.params.board ? `/${req.params.board}/manage.html` : '/globalmanage.html'
});
}
const messages = [];
try {
messages.push((await removeBans(req, res, next)));
await deleteBoard(req.body.uri);
} catch (err) {
return next(err);
}
return res.render('message', {
'title': 'Success',
'messages': messages,
'redirect': `/globalmanage.html`
'message': 'Board deleted',
'redirect': req.params.board ? '/' : '/globalmanage.html'
});
});
}
router.post('/newcaptcha', async(req, res, next) => {

@ -1,6 +1,6 @@
'use strict';
const Mongo = require(__dirname+'/../db/db.js')
const { ObjectId } = require(__dirname+'/../db/db.js')
, allowedArrays = new Set(['checkedposts', 'globalcheckedposts', 'checkedbans', 'checkedbanners']) //only these can be arrays, since express bodyparser will output arrays
, trimFields = ['uri', 'moderators', 'filters', 'announcement', 'description', 'message',
'name', 'subject', 'email', 'password', 'default_name', 'report_reason', 'ban_reason'] //trim if we dont want filed with whitespace
@ -47,12 +47,17 @@ module.exports = (req, res, next) => {
}
}
//convert checked post ids to mongoid/number
//convert checked reports to number
if (req.body.checkedposts) {
req.body.checkedposts = req.body.checkedposts.map(Number);
}
//convert checked global reports to mongoid
if (req.body.globalcheckedposts) {
req.body.globalcheckedposts = req.body.globalcheckedposts.map(Mongo.ObjectId)
req.body.globalcheckedposts = req.body.globalcheckedposts.map(ObjectId)
}
//convert checked bans to mongoid
if (req.body.checkedbans) {
req.body.checkedbans = req.body.checkedbans.map(ObjectId)
}
//ban duration convert to ban time in ms

@ -0,0 +1,27 @@
'use strict';
const Boards = require(__dirname+'/../../db/boards.js')
, Posts = require(__dirname+'/../../db/posts.js')
, Bans = require(__dirname+'/../../db/bans.js')
, deletePosts = require(__dirname+'/deletepost.js')
, uploadDirectory = require(__dirname+'/../../helpers/files/uploadDirectory.js')
, { remove } = require('fs-extra');
module.exports = async (uri) => {
//delete board
await Boards.deleteOne(uri);
//get all posts (should probably project to get files for deletin and anything else necessary)
const allPosts = await Posts.allBoardPosts(uri);
if (allPosts.length > 0) {
//delete posts and decrement images
await deletePosts(allPosts, uri, true);
}
//bans for the board are pointless now
await Bans.deleteBoard(uri);
//remove all pages for the board
await remove(`${uploadDirectory}html/${uri}/`)
//todo: maybe put some of this in parallel
}

@ -1,13 +1,9 @@
'use strict';
const Bans = require(__dirname+'/../../db/bans.js')
, { ObjectId } = require('mongodb');
const Bans = require(__dirname+'/../../db/bans.js');
module.exports = async (req, res, next) => {
const banIds = req.body.checkedbans.map(ObjectId);
const removedBans = await Bans.removeMany(req.params.board, banIds).then(result => result.deletedCount);
return `Removed ${removedBans} bans`;
return Bans.removeMany(req.params.board, banIds).then(result => result.deletedCount);
}

@ -7,7 +7,20 @@ block head
block content
h1.board-title Global Management
h4.no-m-p Reports:
hr(size=1)
h4.no-m-p Delete board:
section.form-wrapper.flexleft.mv-10
form.form-post(action=`/forms/global/deleteboard`, enctype='application/x-www-form-urlencoded', method='POST')
input(type='hidden' name='_csrf' value=csrf)
section.row
.label I'm sure
label.postform-style.ph-5
input(type='checkbox', name='confirm', value='true' required)
section.row
.label Board URI
input(type='text' name='uri' required)
input(type='submit', value='submit')
h4.no-m-p Global Reports:
.mv-10
form(action=`/forms/global/actions` method='POST' enctype='application/x-www-form-urlencoded')
input(type='hidden' name='_csrf' value=csrf)
@ -21,7 +34,7 @@ block content
hr(size=1)
include ../includes/actionfooter_globalmanage.pug
hr(size=1)
h4.no-m-p Bans:
h4.no-m-p Global Bans:
form(action=`/forms/global/unban` method='POST' enctype='application/x-www-form-urlencoded')
input(type='hidden' name='_csrf' value=csrf)
if bans.length === 0

Loading…
Cancel
Save