global and board IP bans, improved error handling, improved permissions checks

merge-requests/208/head
fatchan 5 years ago
parent e823cad14e
commit db963d4607
  1. 41
      controllers/forms.js
  2. 43
      controllers/pages.js
  3. 2
      db-models/bans.js
  4. 16
      db-models/posts.js
  5. 10
      helpers/bancheck.js
  6. 9
      helpers/has-perms.js
  7. 16
      helpers/hasperms.js
  8. 16
      helpers/haspermsmiddleware.js
  9. 0
      helpers/isloggedin.js
  10. 35
      models/forms/ban-poster.js
  11. 41
      models/forms/delete-post.js
  12. 12
      models/forms/dismiss-report.js
  13. 13
      models/forms/edit-post.js
  14. 8
      models/forms/login.js
  15. 13
      models/forms/make-post.js
  16. 8
      models/forms/register.js
  17. 8
      models/forms/report-post.js
  18. 13
      models/forms/spoiler-post.js
  19. 3
      models/pages/board.js
  20. 3
      models/pages/catalog.js
  21. 20
      models/pages/globalmanage.js
  22. 3
      models/pages/home.js
  23. 2
      models/pages/login.js
  24. 5
      models/pages/manage.js
  25. 11
      models/pages/register.js
  26. 3
      models/pages/thread.js
  27. 5
      server.js
  28. 4
      views/mixins/post.pug
  29. 25
      views/pages/ban.pug
  30. 11
      views/pages/globalmanage.pug
  31. 6
      views/pages/manage.pug
  32. 2
      wipe.js

@ -46,7 +46,7 @@ router.post('/login', (req, res, next) => {
}) })
} }
loginAccount(req, res); loginAccount(req, res, next);
}); });
@ -88,7 +88,7 @@ router.post('/register', (req, res, next) => {
}) })
} }
registerAccount(req, res); registerAccount(req, res, next);
}); });
@ -137,11 +137,11 @@ router.post('/board/:board', Boards.exists, banCheck, numberConverter, async (re
}) })
} }
makePost(req, res, numFiles); makePost(req, res, next, numFiles);
}); });
//report, delete, sticky, etc //report/delete/spoiler/ban
router.post('/board/:board/posts', Boards.exists, banCheck, numberConverter, async (req, res, next) => { router.post('/board/:board/posts', Boards.exists, banCheck, numberConverter, async (req, res, next) => {
const errors = []; const errors = [];
@ -178,38 +178,45 @@ router.post('/board/:board/posts', Boards.exists, banCheck, numberConverter, asy
}) })
} }
const posts = await Posts.getPosts(req.params.board, req.body.checked, true);
if (!posts || posts.length === 0) {
return res.status(404).render('message', {
'title': 'Not found',
'errors': 'Selected posts not found',
'redirect': `/${req.params.board}`
})
}
const messages = []; const messages = [];
try { try {
//TODO: maybe fetch the posts first instead of checking multiple times with multiple actions
//global or board ban
if (req.body.global_ban) { if (req.body.global_ban) {
messages.push((await banPoster(req, res, null))); messages.push((await banPoster(req, res, next, null, posts)));
} else if (req.body.ban) { } else if (req.body.ban) {
messages.push((await banPoster(req, res, req.params.board))); messages.push((await banPoster(req, res, next, req.params.board, posts)));
} }
// then if not deleting, we can spoiler and report or dismiss reports
if (req.body.delete) { if (req.body.delete) {
messages.push((await deletePosts(req, res))); messages.push((await deletePosts(req, res, next, posts)));
} else { } else {
if (req.body.spoiler) { if (req.body.spoiler) {
messages.push((await spoilerPosts(req, res))); messages.push((await spoilerPosts(req, res, next, posts)));
} }
if (req.body.report) { if (req.body.report) {
messages.push((await reportPosts(req, res))); messages.push((await reportPosts(req, res, next)));
} else if (req.body.dismiss) { } else if (req.body.dismiss) {
messages.push((await dismissReports(req, res))); messages.push((await dismissReports(req, res, next)));
} }
} }
} catch (err) { } catch (err) {
//something not right
if (err.status) { if (err.status) {
// return out special error
return res.status(err.status).render('message', err.message); return res.status(err.status).render('message', err.message);
} }
console.error(err); //some other error, use regular error handler
return res.status(500).render('error'); return next(err);
} }
return res.render('message', { return res.render('message', {
@ -220,6 +227,4 @@ router.post('/board/:board/posts', Boards.exists, banCheck, numberConverter, asy
}); });
module.exports = router; module.exports = router;

@ -3,13 +3,15 @@
const express = require('express') const express = require('express')
, router = express.Router() , router = express.Router()
, Boards = require(__dirname+'/../db-models/boards.js') , Boards = require(__dirname+'/../db-models/boards.js')
, checkAuth = require(__dirname+'/../helpers/check-auth.js') , hasPerms = require(__dirname+'/../helpers/haspermsmiddleware.js')
, isLoggedIn = require(__dirname+'/../helpers/isloggedin.js')
, numberConverter = require(__dirname+'/../helpers/number-converter.js') , numberConverter = require(__dirname+'/../helpers/number-converter.js')
//page models //page models
, home = require(__dirname+'/../models/pages/home.js') , home = require(__dirname+'/../models/pages/home.js')
, register = require(__dirname+'/../models/pages/register.js') , register = require(__dirname+'/../models/pages/register.js')
, manage = require(__dirname+'/../models/pages/manage.js') , manage = require(__dirname+'/../models/pages/manage.js')
, login = require(__dirname+'/../models/pages/login.js') , globalmanage = require(__dirname+'/../models/pages/globalmanage.js')
, login = require(__dirname+'/../models/pages/login.js')
, board = require(__dirname+'/../models/pages/board.js') , board = require(__dirname+'/../models/pages/board.js')
, catalog = require(__dirname+'/../models/pages/catalog.js') , catalog = require(__dirname+'/../models/pages/catalog.js')
, thread = require(__dirname+'/../models/pages/thread.js'); , thread = require(__dirname+'/../models/pages/thread.js');
@ -24,27 +26,24 @@ router.get('/login', login);
router.get('/register', register); router.get('/register', register);
//logout //logout
router.get('/logout', (req, res, next) => { router.get('/logout', isLoggedIn, (req, res, next) => {
if (req.session.authenticated === true) { //remove session
req.session.destroy(); req.session.destroy();
return res.render('message', {
'title': 'Success', return res.render('message', {
'message': 'You have been logged out successfully', 'title': 'Success',
'redirect': '/' 'message': 'You have been logged out successfully',
}); 'redirect': '/'
} });
return res.status(400).render('message', {
'title': 'Bad request',
'message': 'You are not logged in',
'redirect': '/login'
})
}); });
//board manage page //board manage page
router.get('/:board/manage', Boards.exists, checkAuth, Boards.canManage, manage); router.get('/:board/manage', Boards.exists, isLoggedIn, hasPerms, manage);
//board manage page
router.get('/globalmanage', isLoggedIn, hasPerms, globalmanage);
// board page/recents // board page/recents
router.get('/:board/:page(\\d+)?', Boards.exists, numberConverter, board); router.get('/:board/:page(\\d+)?', Boards.exists, numberConverter, board);

@ -5,6 +5,8 @@ const Mongo = require(__dirname+'/../helpers/db.js')
module.exports = { module.exports = {
db,
find: (ip, board) => { find: (ip, board) => {
return db.find({ return db.find({
'ip': ip, 'ip': ip,

@ -240,6 +240,22 @@ module.exports = {
}).toArray(); }).toArray();
}, },
getAllReports: () => {
return db.find({
'reports.0': {
'$exists': true
}
}, {
'projection': {
'salt': 0,
'password': 0,
'ip': 0,
}
}).sort({
'board': 1
}).toArray();
},
deleteOne: (board, options) => { deleteOne: (board, options) => {
return db.deleteOne(options); return db.deleteOne(options);
}, },

@ -1,19 +1,17 @@
'use strict'; 'use strict';
const Bans = require(__dirname+'/../db-models/bans.js') const Bans = require(__dirname+'/../db-models/bans.js')
, hasPerms = require(__dirname+'/has-perms.js'); , hasPerms = require(__dirname+'/hasperms.js');
module.exports = async (req, res, next) => { module.exports = async (req, res, next) => {
if (!hasPerms(req, res)) { if (!hasPerms(req, res)) {
const ip = req.headers['x-real-ip'] || req.connection.remoteAddress; const ip = req.headers['x-real-ip'] || req.connection.remoteAddress;
const bans = await Bans.find(ip, res.locals.board._id); const bans = await Bans.find(ip, res.locals.board ? res.locals.board._id : null);
if (bans && bans.length > 0) { if (bans && bans.length > 0) {
//TODO: show posts banned for, expiry, etc //TODO: show posts banned for, expiry, etc
return res.status(403).render('message', { return res.status(403).render('ban', {
'title': 'Forbidden', bans: bans
'message': 'You are banned',
'redirect': '/'
}); });
} }
} }

@ -1,9 +0,0 @@
'use strict';
module.exports = (req, res) => {
return req.session.authenticated //if the user is authed
&& req.session.user //if the user is logged in
&& (req.session.user.authLevel > 1 //and is not a regular user
|| res.locals.board.owner == req.session.user.username //or us board owner
|| res.locals.board.moderators.includes(req.session.user.username)); //or is board moderator
}

@ -0,0 +1,16 @@
'use strict';
module.exports = (req, res) => {
return req.session.authenticated //if the user is authed
&& req.session.user //if the user is logged in
&& (
req.session.user.authLevel > 1 //and is not a regular user
|| (
res.locals.board
&& (
res.locals.board.owner == req.session.user.username //and board owner
|| res.locals.board.moderators.includes(req.session.user.username) //or board mod
)
)
)
}

@ -0,0 +1,16 @@
'use strict';
const hasPerms = require(__dirname+'/hasperms.js');
module.exports = async (req, res, next) => {
if (!hasPerms(req, res)) {
return res.status(403).render('message', {
'title': 'Forbidden',
'message': 'You do not have permission to access this page',
'redirect': '/'
});
}
next();
}

@ -1,11 +1,13 @@
'use strict'; 'use strict';
const uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js') const uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js')
, hasPerms = require(__dirname+'/../../helpers/has-perms.js') , hasPerms = require(__dirname+'/../../helpers/hasperms.js')
, Bans = require(__dirname+'/../../db-models/bans.js') , Bans = require(__dirname+'/../../db-models/bans.js')
, Posts = require(__dirname+'/../../db-models/posts.js'); , Posts = require(__dirname+'/../../db-models/posts.js');
module.exports = async (req, res, board) => { module.exports = async (req, res, next, board, checkedPosts) => {
const posts = checkedPosts;
//if user is not logged in or if logged in but not authed, they cannot ban //if user is not logged in or if logged in but not authed, they cannot ban
if (!hasPerms(req, res)) { if (!hasPerms(req, res)) {
@ -19,33 +21,24 @@ module.exports = async (req, res, board) => {
}; };
} }
//get all posts that were checked
let posts = await Posts.getPosts(req.params.board, req.body.checked, true); //admin arument true, fetches passwords and salts
if (!posts || posts.length === 0) {
throw {
'status': 400,
'message': {
'title': 'Bad requests',
'message': 'No posts found',
'redirect': `/${req.params.board}`
}
};
}
const bans = posts.map(post => { const bans = posts.map(post => {
return { return {
'ip': post.ip, 'ip': post.ip,
'reason': req.body.reason || 'No reason specified',
'board': board, 'board': board,
'post': post, 'post': req.body.delete ? null : post,
'issuer': req.session.user.username 'issuer': req.session.user.username,
'date': new Date(),
'expireAt': new Date((new Date).getTime() + (72*1000*60*60)) // 72h ban
} }
}); });
let bannedIps = 0; let bannedIps = 0;
const result = await Bans.insertMany(bans, board); try {
console.log(result) bannedIps = await Bans.insertMany(bans).then(result => result.insertedCount);
bannedIps = result.insertedCount; } catch (err) {
return next(err);
}
return `Banned ${bannedIps} ips`; return `Banned ${bannedIps} ips`;

@ -5,24 +5,12 @@ const path = require('path')
, fs = require('fs') , fs = require('fs')
, unlink = util.promisify(fs.unlink) , unlink = util.promisify(fs.unlink)
, uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js') , uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js')
, hasPerms = require(__dirname+'/../../helpers/has-perms.js') , hasPerms = require(__dirname+'/../../helpers/hasperms.js')
, Posts = require(__dirname+'/../../db-models/posts.js'); , Posts = require(__dirname+'/../../db-models/posts.js');
module.exports = async (req, res) => { module.exports = async (req, res, next, checkedPosts) => {
//get all posts that were checked let posts = checkedPosts;
let posts = await Posts.getPosts(req.params.board, req.body.checked, true); //admin arument true, fetches passwords and salts
if (!posts || posts.length === 0) {
throw {
'status': 400,
'message': {
'title': 'Bad request',
'message': 'No posts found',
'redirect': `/${req.params.board}`
}
};
}
//if user is not logged in OR if lgoged in but not authed, filter the posts by passwords that are not null //if user is not logged in OR if lgoged in but not authed, filter the posts by passwords that are not null
if (!hasPerms(req, res)) { if (!hasPerms(req, res)) {
@ -34,14 +22,14 @@ module.exports = async (req, res) => {
&& post.password == req.body.password && post.password == req.body.password
}); });
if (posts.length === 0) { if (posts.length === 0) {
throw { throw {
'status': 403, 'status': 403,
'message': { 'message': {
'title': 'Forbidden', 'title': 'Forbidden',
'message': 'Password did not match any selected posts', 'message': 'Password did not match any selected posts',
'redirect': `/${req.params.board}` 'redirect': `/${req.params.board}`
} }
}; };
} }
} }
@ -60,8 +48,11 @@ module.exports = async (req, res) => {
//delete posts from DB //delete posts from DB
let deletedPosts = 0; let deletedPosts = 0;
const result = await Posts.deleteMany(req.params.board, allPosts.map(x => x.postId)); try {
deletedPosts = result.deletedCount; deletedPosts = await Posts.deleteMany(req.params.board, allPosts.map(x => x.postId)).then(result => result.deletedCount);
} catch (err) {
return next(err);
}
//get filenames from all the posts //get filenames from all the posts
let fileNames = []; let fileNames = [];

@ -1,9 +1,9 @@
'use strict'; 'use strict';
const Posts = require(__dirname+'/../../db-models/posts.js') const Posts = require(__dirname+'/../../db-models/posts.js')
, hasPerms = require(__dirname+'/../../helpers/has-perms.js'); , hasPerms = require(__dirname+'/../../helpers/hasperms.js');
module.exports = async (req, res) => { module.exports = async (req, res, next) => {
if (!hasPerms(req, res)) { if (!hasPerms(req, res)) {
throw { throw {
@ -16,8 +16,12 @@ module.exports = async (req, res) => {
}; };
} }
await Posts.dismissReports(req.params.board, req.body.checked); try {
await Posts.dismissReports(req.params.board, req.body.checked);
} catch (err) {
return next(err);
}
return `Dismissed report(s) successfully` return `Dismissed report(s) successfully`;
} }

@ -1,13 +1,18 @@
'use strict'; 'use strict';
const uuidv4 = require('uuid/v4') const uuidv4 = require('uuid/v4')
, path = require('path') , path = require('path')
, Posts = require(__dirname+'/../../db-models/posts.js') , Posts = require(__dirname+'/../../db-models/posts.js')
module.exports = async (req, res, numFiles) => { module.exports = async (req, res, next, numFiles) => {
// get the post that we are trying to edit // get the post that we are trying to edit
let post = await Posts.getPost(req.params.board, req.body.id, true); let post;
try {
post = await Posts.getPost(req.params.board, req.body.id, true);
} catch (err) {
return next(err);
}
if (!thread || thread.thread != null) { if (!thread || thread.thread != null) {
throw { throw {

@ -3,7 +3,7 @@
const bcrypt = require('bcrypt') const bcrypt = require('bcrypt')
, Accounts = require(__dirname+'/../../db-models/accounts.js'); , Accounts = require(__dirname+'/../../db-models/accounts.js');
module.exports = async (req, res) => { module.exports = async (req, res, next) => {
const username = req.body.username.toLowerCase(); const username = req.body.username.toLowerCase();
const password = req.body.password; const password = req.body.password;
@ -13,8 +13,7 @@ module.exports = async (req, res) => {
try { try {
account = await Accounts.findOne(username); account = await Accounts.findOne(username);
} catch (err) { } catch (err) {
console.error(err); return next(err);
return res.status(500).render('error');
} }
//if the account doesnt exist, reject //if the account doesnt exist, reject
@ -31,8 +30,7 @@ module.exports = async (req, res) => {
try { try {
passwordMatch = await bcrypt.compare(password, account.passwordHash); passwordMatch = await bcrypt.compare(password, account.passwordHash);
} catch (err) { } catch (err) {
console.error(err); return next(err);
return res.status(500).render('error');
} }
//if hashes matched //if hashes matched

@ -25,7 +25,7 @@ const uuidv4 = require('uuid/v4')
, videoIdentify = require(__dirname+'/../../helpers/files/video-identify.js') , videoIdentify = require(__dirname+'/../../helpers/files/video-identify.js')
, formatSize = require(__dirname+'/../../helpers/files/format-size.js') , formatSize = require(__dirname+'/../../helpers/files/format-size.js')
module.exports = async (req, res, numFiles) => { module.exports = async (req, res, next, numFiles) => {
// check if this is responding to an existing thread // check if this is responding to an existing thread
let redirect = `/${req.params.board}` let redirect = `/${req.params.board}`
@ -35,8 +35,7 @@ module.exports = async (req, res, numFiles) => {
try { try {
thread = await Posts.getPost(req.params.board, req.body.thread, true); thread = await Posts.getPost(req.params.board, req.body.thread, true);
} catch (err) { } catch (err) {
console.error(err); return next(err);
return res.status(500).render('error');
} }
if (!thread || thread.thread != null) { if (!thread || thread.thread != null) {
return res.status(400).render('message', { return res.status(400).render('message', {
@ -100,7 +99,7 @@ module.exports = async (req, res, numFiles) => {
await videoThumbnail(filename); await videoThumbnail(filename);
break; break;
default: default:
return res.status(500).render('error'); //how did we get here? return next(err);
} }
//make thumbnail //make thumbnail
@ -119,9 +118,8 @@ module.exports = async (req, res, numFiles) => {
files.push(processedFile); files.push(processedFile);
} catch (err) { } catch (err) {
console.error(err);
//TODO: DELETE FAILED FILES //TODO: DELETE FAILED FILES
return res.status(500).render('error'); return next(err);
} }
} }
} }
@ -174,8 +172,7 @@ module.exports = async (req, res, numFiles) => {
try { try {
postId = await Posts.insertOne(req.params.board, data); postId = await Posts.insertOne(req.params.board, data);
} catch (err) { } catch (err) {
console.error(err); return next(err);
return res.status(500).render('error');
} }
const successRedirect = `/${req.params.board}/thread/${req.body.thread || postId}#${postId}`; const successRedirect = `/${req.params.board}/thread/${req.body.thread || postId}#${postId}`;

@ -3,7 +3,7 @@
const bcrypt = require('bcrypt') const bcrypt = require('bcrypt')
, Accounts = require(__dirname+'/../../db-models/accounts.js'); , Accounts = require(__dirname+'/../../db-models/accounts.js');
module.exports = async (req, res) => { module.exports = async (req, res, next) => {
const username = req.body.username.toLowerCase(); const username = req.body.username.toLowerCase();
const password = req.body.password; const password = req.body.password;
@ -12,8 +12,7 @@ module.exports = async (req, res) => {
try { try {
account = await Accounts.findOne(username); account = await Accounts.findOne(username);
} catch (err) { } catch (err) {
console.error(err); return next(err);
return res.status(500).render('error');
} }
// if the account exists reject // if the account exists reject
@ -29,8 +28,7 @@ module.exports = async (req, res) => {
try { try {
await Accounts.insertOne(username, password, 1); await Accounts.insertOne(username, password, 1);
} catch (err) { } catch (err) {
console.error(err); return next(err);
return res.status(500).render('error');
} }
return res.render('message', { return res.render('message', {

@ -2,7 +2,7 @@
const Posts = require(__dirname+'/../../db-models/posts.js'); const Posts = require(__dirname+'/../../db-models/posts.js');
module.exports = async (req, res) => { module.exports = async (req, res, next) => {
const ip = req.headers['x-real-ip'] || req.connection.remoteAddress; const ip = req.headers['x-real-ip'] || req.connection.remoteAddress;
const report = { const report = {
@ -12,7 +12,11 @@ module.exports = async (req, res) => {
} }
//push the report to all checked posts //push the report to all checked posts
await Posts.reportMany(req.params.board, req.body.checked, report); try {
await Posts.reportMany(req.params.board, req.body.checked, report);
} catch (err) {
return next(err);
}
//hooray! //hooray!
return `Reported post(s) successfully` return `Reported post(s) successfully`

@ -5,13 +5,13 @@ const path = require('path')
, fs = require('fs') , fs = require('fs')
, unlink = util.promisify(fs.unlink) , unlink = util.promisify(fs.unlink)
, uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js') , uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js')
, hasPerms = require(__dirname+'/../../helpers/has-perms.js') , hasPerms = require(__dirname+'/../../helpers/hasperms.js')
, Posts = require(__dirname+'/../../db-models/posts.js'); , Posts = require(__dirname+'/../../db-models/posts.js');
module.exports = async (req, res) => { module.exports = async (req, res, next, checkedPosts) => {
//get all posts that were checked //get all posts that were checked
let posts = await Posts.getPosts(req.params.board, req.body.checked, true); //admin arument true, fetches passwords and salts let posts = checkedPosts;
if (!posts || posts.length === 0) { if (!posts || posts.length === 0) {
throw { throw {
@ -63,8 +63,11 @@ module.exports = async (req, res) => {
// spoiler posts // spoiler posts
let spoileredPosts = 0; let spoileredPosts = 0;
const result = await Posts.spoilerMany(req.params.board, posts.map(x => x.postId)); try {
spoileredPosts = result.modifiedCount; spoileredPosts = await Posts.spoilerMany(req.params.board, posts.map(x => x.postId)).then(result => result.modifiedCount);
} catch (err) {
return next(err);
}
//hooray! //hooray!
return `Spoilered ${spoileredPosts} posts` return `Spoilered ${spoileredPosts} posts`

@ -10,8 +10,7 @@ module.exports = async (req, res, next) => {
threads = await Posts.getRecent(req.params.board, req.params.page || 1); threads = await Posts.getRecent(req.params.board, req.params.page || 1);
pages = Math.ceil((await Posts.getPages(req.params.board)) / 10); pages = Math.ceil((await Posts.getPages(req.params.board)) / 10);
} catch (err) { } catch (err) {
console.error(err) return next(err);
return next();
} }
//render the page //render the page

@ -9,8 +9,7 @@ module.exports = async (req, res, next) => {
try { try {
threads = await Posts.getCatalog(req.params.board); threads = await Posts.getCatalog(req.params.board);
} catch (err) { } catch (err) {
console.error(err); return next(err);
return next();
} }
//render the page //render the page

@ -0,0 +1,20 @@
'use strict';
const Posts = require(__dirname+'/../../db-models/posts.js');
module.exports = async (req, res, next) => {
let posts;
try {
posts = await Posts.getAllReports();
} catch (err) {
return next(err);
}
//render the page
res.render('globalmanage', {
csrf: req.csrfToken(),
posts: posts
});
}

@ -9,8 +9,7 @@ module.exports = async (req, res, next) => {
try { try {
boards = await Boards.find(); boards = await Boards.find();
} catch (err) { } catch (err) {
console.error(err) return next(err);
return next();
} }
//render the page //render the page

@ -1,6 +1,6 @@
'use strict'; 'use strict';
module.exports = (req, res) => { module.exports = (req, res, next) => {
//render the page //render the page
res.render('login', { res.render('login', {

@ -2,14 +2,13 @@
const Posts = require(__dirname+'/../../db-models/posts.js'); const Posts = require(__dirname+'/../../db-models/posts.js');
module.exports = async (req, res) => { module.exports = async (req, res, next) => {
let posts; let posts;
try { try {
posts = await Posts.getReports(req.params.board); posts = await Posts.getReports(req.params.board);
} catch (err) { } catch (err) {
console.error(err); return next(err)
return res.status(500).render('error');
} }
//render the page //render the page

@ -1,15 +1,6 @@
'use strict'; 'use strict';
module.exports = (req, res) => { module.exports = (req, res, next) => {
//send home if already logged in
if (req.session.authenticated === true) {
return res.status(400).render('message', {
'title': 'Notice',
'message': 'You are already logged in. Redirecting you to back home.',
'redirect': '/'
});
}
//render the page //render the page
res.render('register', { res.render('register', {

@ -9,8 +9,7 @@ module.exports = async (req, res, next) => {
try { try {
thread = await Posts.getThread(req.params.board, req.params.id); thread = await Posts.getThread(req.params.board, req.params.id);
} catch (err) { } catch (err) {
console.error(err); return next(err);
return next();
} }
if (!thread) { if (!thread) {

@ -74,7 +74,10 @@ const express = require('express')
return res.status(403).send('Invalid CSRF token') return res.status(403).send('Invalid CSRF token')
} }
console.error(err.stack) console.error(err.stack)
return res.status(500).render('error') return res.status(500).render('message', {
'title': 'Internal Server Error',
'redirect': req.header('Referer') || '/'
})
}) })
// listen // listen

@ -1,4 +1,4 @@
mixin post(board, post, truncate) mixin post(board, post, truncate, showreports)
article(id=post.postId class='post-container '+(post.thread ? '' : 'op')) article(id=post.postId class='post-container '+(post.thread ? '' : 'op'))
header.post-info header.post-info
input.post-check(type='checkbox', name='checked[]' value=post.postId) input.post-check(type='checkbox', name='checked[]' value=post.postId)
@ -44,7 +44,7 @@ mixin post(board, post, truncate)
blockquote.post-message !{post.message} blockquote.post-message !{post.message}
else else
blockquote.post-message !{post.message} blockquote.post-message !{post.message}
if post.reports if showreports && post.reports
each report in post.reports each report in post.reports
.reports.post-container .reports.post-container
span Date: #{report.date.toLocaleString()} span Date: #{report.date.toLocaleString()}

@ -0,0 +1,25 @@
extends ../layout.pug
include ../mixins/post.pug
block head
title Banned!
block content
h1.board-title Banned!
hr(size=1)
Bans currently in place against your IP:
hr(size=1)
for ban in bans
if ban.board
div Board: #[a(href=`/${ban.board}`) /#{ban.board}/]
else
div Global ban.
div Reason: #{ban.reason}
div Issuer: #{ban.issuer}
div Date: #{ban.date}
div Expiry: #{ban.expireAt}
if ban.post
span Post:
section.thread
+post(ban.post.board, ban.post, false)
hr(size=1)

@ -0,0 +1,11 @@
extends ../layout.pug
include ../mixins/post.pug
block head
title Manage
block content
h1.board-title Global Management
hr(size=1)
p under construction

@ -15,7 +15,7 @@ block content
hr(size=1) hr(size=1)
for post in posts for post in posts
section.thread section.thread
+post(board, post) +post(board, post, false, true)
hr(size=1) hr(size=1)
section.action-wrapper section.action-wrapper
span span
@ -26,6 +26,10 @@ block content
label label
input.post-check(type='checkbox', name='spoiler' value=1) input.post-check(type='checkbox', name='spoiler' value=1)
| Spoiler | Spoiler
span
label
input.post-check(type='checkbox', name='dismiss' value=1)
| Dismiss
span span
label label
input.post-check(type='checkbox', name='ban' value=1) input.post-check(type='checkbox', name='ban' value=1)

@ -43,6 +43,8 @@ const Mongo = require(__dirname+'/helpers/db.js')
moderators: [], moderators: [],
}) })
console.log('creating indexes') console.log('creating indexes')
await Bans.db.dropIndexes();
await Bans.db.createIndex({ "expireAt": 1 }, { expireAfterSeconds: 0 });
await Posts.db.dropIndexes(); await Posts.db.dropIndexes();
//these are fucked //these are fucked
await Posts.db.createIndex({ await Posts.db.createIndex({

Loading…
Cancel
Save