Merge branch 'master' into dev

merge-requests/208/head
Thomas Lynch 4 years ago
commit 41a22809fc
  1. 53
      controllers/forms.js
  2. 2
      controllers/forms/editpost.js
  3. 40
      controllers/pages.js
  4. 47
      db/accounts.js
  5. 1
      gulpfile.js
  6. 4
      helpers/checks/hasperms.js
  7. 4
      helpers/checks/isloggedin.js
  8. 22
      helpers/processip.js
  9. 11
      helpers/sessionrefresh.js
  10. 24
      helpers/usesession.js
  11. 2
      models/forms/actionhandler.js
  12. 6
      models/forms/addban.js
  13. 4
      models/forms/banposter.js
  14. 2
      models/forms/create.js
  15. 4
      models/forms/editpost.js
  16. 16
      models/forms/login.js
  17. 2
      models/pages/account.js
  18. 20
      package-lock.json
  19. 1
      package.json
  20. 26
      server.js

@ -14,6 +14,7 @@ const express = require('express')
, isLoggedIn = require(__dirname+'/../helpers/checks/isloggedin.js')
, verifyCaptcha = require(__dirname+'/../helpers/captcha/captchaverify.js')
, csrf = require(__dirname+'/../helpers/checks/csrfmiddleware.js')
, useSession = require(__dirname+'/../helpers/usesession.js')
, sessionRefresh = require(__dirname+'/../helpers/sessionrefresh.js')
, dnsblCheck = require(__dirname+'/../helpers/checks/dnsbl.js')
, blockBypassCheck = require(__dirname+'/../helpers/checks/blockbypass.js')
@ -82,45 +83,45 @@ const express = require('express')
, logout = require(__dirname+'/../models/forms/logout.js');
//make new post
router.post('/board/:board/post', processIp, sessionRefresh, Boards.exists, calcPerms, banCheck, postFiles,
router.post('/board/:board/post', processIp, useSession, sessionRefresh, Boards.exists, calcPerms, banCheck, postFiles,
paramConverter, verifyCaptcha, numFiles, blockBypassCheck, dnsblCheck, makePostController);
router.post('/board/:board/modpost', processIp, sessionRefresh, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(3), postFiles,
router.post('/board/:board/modpost', processIp, useSession, sessionRefresh, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(3), postFiles,
paramConverter, csrf, numFiles, blockBypassCheck, dnsblCheck, makePostController); //mod post has token instead of captcha
//post actions
router.post('/board/:board/actions', processIp, sessionRefresh, Boards.exists, calcPerms, banCheck, paramConverter, verifyCaptcha, actionController); //public, with captcha
router.post('/board/:board/modactions', processIp, sessionRefresh, csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(3), paramConverter, actionController); //board manage page
router.post('/global/actions', processIp, sessionRefresh, csrf, calcPerms, isLoggedIn, hasPerms(1), paramConverter, globalActionController); //global manage page
router.post('/board/:board/actions', processIp, useSession, sessionRefresh, Boards.exists, calcPerms, banCheck, paramConverter, verifyCaptcha, actionController); //public, with captcha
router.post('/board/:board/modactions', processIp, useSession, sessionRefresh, csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(3), paramConverter, actionController); //board manage page
router.post('/global/actions', processIp, useSession, sessionRefresh, csrf, calcPerms, isLoggedIn, hasPerms(1), paramConverter, globalActionController); //global manage page
//appeal ban
router.post('/appeal', processIp, sessionRefresh, paramConverter, verifyCaptcha, appealController);
router.post('/appeal', processIp, useSession, sessionRefresh, paramConverter, verifyCaptcha, appealController);
//edit post
router.post('/editpost', processIp, sessionRefresh, csrf, paramConverter, Boards.bodyExists, calcPerms, hasPerms(3), editPostController);
router.post('/editpost', processIp, useSession, sessionRefresh, csrf, paramConverter, Boards.bodyExists, calcPerms, hasPerms(3), editPostController);
//board management forms
router.post('/board/:board/transfer', processIp, sessionRefresh, csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(2), paramConverter, transferController);
router.post('/board/:board/settings', processIp, sessionRefresh, csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(2), paramConverter, boardSettingsController);
router.post('/board/:board/addbanners', processIp, sessionRefresh, bannerFiles, csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(2), paramConverter, numFiles, uploadBannersController); //add banners
router.post('/board/:board/deletebanners', processIp, sessionRefresh, csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(2), paramConverter, deleteBannersController); //delete banners
router.post('/board/:board/addban', processIp, sessionRefresh, csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(3), paramConverter, addBanController); //add ban manually without post
router.post('/board/:board/editbans', processIp, sessionRefresh, csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(3), paramConverter, editBansController); //edit bans
router.post('/board/:board/deleteboard', processIp, sessionRefresh, csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(2), deleteBoardController); //delete board
router.post('/board/:board/transfer', processIp, useSession, sessionRefresh, csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(2), paramConverter, transferController);
router.post('/board/:board/settings', processIp, useSession, sessionRefresh, csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(2), paramConverter, boardSettingsController);
router.post('/board/:board/addbanners', processIp, useSession, sessionRefresh, bannerFiles, csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(2), paramConverter, numFiles, uploadBannersController); //add banners
router.post('/board/:board/deletebanners', processIp, useSession, sessionRefresh, csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(2), paramConverter, deleteBannersController); //delete banners
router.post('/board/:board/addban', processIp, useSession, sessionRefresh, csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(3), paramConverter, addBanController); //add ban manually without post
router.post('/board/:board/editbans', processIp, useSession, sessionRefresh, csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(3), paramConverter, editBansController); //edit bans
router.post('/board/:board/deleteboard', processIp, useSession, sessionRefresh, csrf, Boards.exists, calcPerms, banCheck, isLoggedIn, hasPerms(2), deleteBoardController); //delete board
//global management forms
router.post('/global/editbans', sessionRefresh, csrf, calcPerms, isLoggedIn, hasPerms(1), paramConverter, editBansController); //remove bans
router.post('/global/addban', processIp, sessionRefresh, csrf, calcPerms, isLoggedIn, hasPerms(1), paramConverter, addBanController); //add ban manually without post
router.post('/global/deleteboard', sessionRefresh, csrf, paramConverter, calcPerms, isLoggedIn, hasPerms(1), deleteBoardController); //delete board
router.post('/global/addnews', sessionRefresh, csrf, calcPerms, isLoggedIn, hasPerms(0), addNewsController); //add new newspost
router.post('/global/deletenews', sessionRefresh, csrf, calcPerms, isLoggedIn, hasPerms(0), paramConverter, deleteNewsController); //delete news
router.post('/global/editaccounts', sessionRefresh, csrf, calcPerms, isLoggedIn, hasPerms(0), paramConverter, editAccountsController); //account editing
router.post('/global/settings', sessionRefresh, csrf, calcPerms, isLoggedIn, hasPerms(0), paramConverter, globalSettingsController); //global settings
router.post('/global/editbans', useSession, sessionRefresh, csrf, calcPerms, isLoggedIn, hasPerms(1), paramConverter, editBansController); //remove bans
router.post('/global/addban', processIp, useSession, sessionRefresh, csrf, calcPerms, isLoggedIn, hasPerms(1), paramConverter, addBanController); //add ban manually without post
router.post('/global/deleteboard', useSession, sessionRefresh, csrf, paramConverter, calcPerms, isLoggedIn, hasPerms(1), deleteBoardController); //delete board
router.post('/global/addnews', useSession, sessionRefresh, csrf, calcPerms, isLoggedIn, hasPerms(0), addNewsController); //add new newspost
router.post('/global/deletenews', useSession, sessionRefresh, csrf, calcPerms, isLoggedIn, hasPerms(0), paramConverter, deleteNewsController); //delete news
router.post('/global/editaccounts', useSession, sessionRefresh, csrf, calcPerms, isLoggedIn, hasPerms(0), paramConverter, editAccountsController); //account editing
router.post('/global/settings', useSession, sessionRefresh, csrf, calcPerms, isLoggedIn, hasPerms(0), paramConverter, globalSettingsController); //global settings
//create board
router.post('/create', processIp, sessionRefresh, isLoggedIn, verifyCaptcha, calcPerms, hasPerms(4), createBoardController);
router.post('/create', processIp, useSession, sessionRefresh, isLoggedIn, verifyCaptcha, calcPerms, hasPerms(4), createBoardController);
//accounts
router.post('/login', loginController);
router.post('/logout', logout);
router.post('/register', processIp, verifyCaptcha, calcPerms, registerController);
router.post('/changepassword', processIp, verifyCaptcha, changePasswordController);
router.post('/login', useSession, loginController);
router.post('/logout', useSession, logout);
router.post('/register', processIp, useSession, sessionRefresh, verifyCaptcha, calcPerms, registerController);
router.post('/changepassword', processIp, useSession, sessionRefresh, verifyCaptcha, changePasswordController);
//removes captcha cookie, for refreshing for noscript users
router.post('/newcaptcha', newCaptcha);

@ -48,7 +48,7 @@ module.exports = async (req, res, next) => {
}
if (res.locals.permLevel > 1) { //if not global staff or above
const ratelimitUser = await Ratelimits.incrmentQuota(req.session.user.username, 'edit', rateLimitCost.editPost);
const ratelimitUser = await Ratelimits.incrmentQuota(req.session.user, 'edit', rateLimitCost.editPost);
const ratelimitIp = await Ratelimits.incrmentQuota(res.locals.ip.single, 'edit', rateLimitCost.editPost);
if (ratelimitUser > 100 || ratelimitIp > 100) {
return dynamicResponse(req, res, 429, 'message', {

@ -10,6 +10,7 @@ const express = require('express')
, hasPerms = require(__dirname+'/../helpers/checks/haspermsmiddleware.js')
, isLoggedIn = require(__dirname+'/../helpers/checks/isloggedin.js')
, paramConverter = require(__dirname+'/../helpers/paramconverter.js')
, useSession = require(__dirname+'/../helpers/usesession.js')
, sessionRefresh = require(__dirname+'/../helpers/sessionrefresh.js')
, csrf = require(__dirname+'/../helpers/checks/csrfmiddleware.js')
, setMinimal = require(__dirname+'/../helpers/setminimal.js')
@ -29,7 +30,7 @@ router.get('/index.html', home);
router.get('/news.html', news);
//board list
router.get('/boards.html', sessionRefresh, calcPerms, boardlist);
router.get('/boards.html', useSession, sessionRefresh, calcPerms, boardlist);
//board pages
router.get('/:board/:page(1[0-9]{1,}|[2-9][0-9]{0,}|index).html', Boards.exists, paramConverter, board); //index
@ -39,29 +40,29 @@ router.get('/:board/logs.html', Boards.exists, modloglist);//modlog list
router.get('/:board/logs/:date(\\d{2}-\\d{2}-\\d{4}).html', Boards.exists, paramConverter, modlog); //daily log
router.get('/:board/banners.html', Boards.exists, banners); //banners
router.get('/all.html', overboard); //overboard
router.get('/create.html', sessionRefresh, isLoggedIn, create); //create new board
router.get('/create.html', useSession, sessionRefresh, isLoggedIn, create); //create new board
router.get('/randombanner', randombanner); //random banner
//board manage pages
router.get('/:board/manage/reports.html', sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(3), csrf, manageReports);
router.get('/:board/manage/recent.html', sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(3), csrf, manageRecent);
router.get('/:board/manage/bans.html', sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(3), csrf, manageBans);
router.get('/:board/manage/logs.html', sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(3), csrf, manageLogs);
router.get('/:board/manage/settings.html', sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(2), csrf, manageSettings);
router.get('/:board/manage/banners.html', sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(2), csrf, manageBanners);
router.get('/:board/manage/reports.html', useSession, sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(3), csrf, manageReports);
router.get('/:board/manage/recent.html', useSession, sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(3), csrf, manageRecent);
router.get('/:board/manage/bans.html', useSession, sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(3), csrf, manageBans);
router.get('/:board/manage/logs.html', useSession, sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(3), csrf, manageLogs);
router.get('/:board/manage/settings.html', useSession, sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(2), csrf, manageSettings);
router.get('/:board/manage/banners.html', useSession, sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(2), csrf, manageBanners);
// if (mod view enabled) {
router.get('/:board/manage/catalog.html', sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(3), csrf, manageCatalog);
router.get('/:board/manage/:page(1[0-9]{1,}|[2-9][0-9]{0,}|index).html', sessionRefresh, isLoggedIn, Boards.exists, paramConverter, calcPerms, hasPerms(3), csrf, manageBoard);
router.get('/:board/manage/thread/:id([1-9][0-9]{0,}).html', sessionRefresh, isLoggedIn, Boards.exists, paramConverter, calcPerms, hasPerms(3), csrf, Posts.exists, manageThread);
router.get('/:board/manage/catalog.html', useSession, sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(3), csrf, manageCatalog);
router.get('/:board/manage/:page(1[0-9]{1,}|[2-9][0-9]{0,}|index).html', useSession, sessionRefresh, isLoggedIn, Boards.exists, paramConverter, calcPerms, hasPerms(3), csrf, manageBoard);
router.get('/:board/manage/thread/:id([1-9][0-9]{0,}).html', useSession, sessionRefresh, isLoggedIn, Boards.exists, paramConverter, calcPerms, hasPerms(3), csrf, Posts.exists, manageThread);
//global manage pages
router.get('/globalmanage/reports.html', sessionRefresh, isLoggedIn, calcPerms, hasPerms(1), csrf, globalManageReports);
router.get('/globalmanage/bans.html', sessionRefresh, isLoggedIn, calcPerms, hasPerms(1), csrf, globalManageBans);
router.get('/globalmanage/recent.html', sessionRefresh, isLoggedIn, calcPerms, hasPerms(1), csrf, globalManageRecent);
router.get('/globalmanage/globallogs.html', sessionRefresh, isLoggedIn, calcPerms, hasPerms(1), csrf, globalManageLogs);
router.get('/globalmanage/news.html', sessionRefresh, isLoggedIn, calcPerms, hasPerms(0), csrf, globalManageNews);
router.get('/globalmanage/accounts.html', sessionRefresh, isLoggedIn, calcPerms, hasPerms(0), csrf, globalManageAccounts);
router.get('/globalmanage/settings.html', sessionRefresh, isLoggedIn, calcPerms, hasPerms(0), csrf, globalManageSettings);
router.get('/globalmanage/reports.html', useSession, sessionRefresh, isLoggedIn, calcPerms, hasPerms(1), csrf, globalManageReports);
router.get('/globalmanage/bans.html', useSession, sessionRefresh, isLoggedIn, calcPerms, hasPerms(1), csrf, globalManageBans);
router.get('/globalmanage/recent.html', useSession, sessionRefresh, isLoggedIn, calcPerms, hasPerms(1), csrf, globalManageRecent);
router.get('/globalmanage/globallogs.html', useSession, sessionRefresh, isLoggedIn, calcPerms, hasPerms(1), csrf, globalManageLogs);
router.get('/globalmanage/news.html', useSession, sessionRefresh, isLoggedIn, calcPerms, hasPerms(0), csrf, globalManageNews);
router.get('/globalmanage/accounts.html', useSession, sessionRefresh, isLoggedIn, calcPerms, hasPerms(0), csrf, globalManageAccounts);
router.get('/globalmanage/settings.html', useSession, sessionRefresh, isLoggedIn, calcPerms, hasPerms(0), csrf, globalManageSettings);
//captcha
router.get('/captcha', processIp, captcha); //get captcha image and cookie
@ -70,10 +71,9 @@ router.get('/bypass.html', blockBypass); //block bypass page
router.get('/bypass_minimal.html', setMinimal, blockBypass); //block bypass page
//accounts
router.get('/account.html', sessionRefresh, isLoggedIn, account); //page showing boards you are mod/owner of, links to password rese, logout, etc
router.get('/account.html', useSession, sessionRefresh, isLoggedIn, account); //page showing boards you are mod/owner of, links to password rese, logout, etc
router.get('/login.html', login);
router.get('/register.html', register);
router.get('/changepassword.html', changePassword);
module.exports = router;

@ -2,7 +2,8 @@
const Mongo = require(__dirname+'/db.js')
, db = Mongo.client.db('jschan').collection('accounts')
, bcrypt = require('bcrypt');
, bcrypt = require('bcrypt')
, cache = require(__dirname+'/../redis.js');
module.exports = {
@ -32,7 +33,7 @@ module.exports = {
// hash the password
const passwordHash = await bcrypt.hash(password, 12);
//add to db
return db.insertOne({
const res = await db.insertOne({
'_id': username,
original,
authLevel,
@ -40,17 +41,21 @@ module.exports = {
'ownedBoards': [],
'modBoards': []
});
cache.del(`users:${username}`);
return res;
},
changePassword: async (username, newPassword) => {
const passwordHash = await bcrypt.hash(newPassword, 12);
return db.updateOne({
const res = await db.updateOne({
'_id': username
}, {
'$set': {
'passwordHash': passwordHash
}
});
cache.del(`users:${username}`);
return res;
},
find: (filter, skip=0, limit=0) => {
@ -63,36 +68,42 @@ module.exports = {
}).skip(skip).limit(limit).toArray();
},
deleteMany: (usernames) => {
return db.deleteMany({
deleteMany: async (usernames) => {
const res = await db.deleteMany({
'_id': {
'$in': usernames
}
});
cache.del(usernames.map(n => `users:${n}`));
return res;
},
addOwnedBoard: (username, board) => {
return db.updateOne({
addOwnedBoard: async (username, board) => {
const res = await db.updateOne({
'_id': username
}, {
'$addToSet': {
'ownedBoards': board
}
});
cache.del(`users:${username}`);
return res;
},
removeOwnedBoard: (username, board) => {
return db.updateOne({
removeOwnedBoard: async (username, board) => {
const res = await db.updateOne({
'_id': username
}, {
'$pull': {
'ownedBoards': board
}
});
cache.del(`users:${username}`);
return res;
},
addModBoard: (usernames, board) => {
return db.updateMany({
addModBoard: async (usernames, board) => {
const res = await db.updateMany({
'_id': {
'$in': usernames
}
@ -101,10 +112,12 @@ module.exports = {
'modBoards': board
}
});
cache.del(`users:${username}`);
return res;
},
removeModBoard: (usernames, board) => {
return db.updateMany({
removeModBoard: async (usernames, board) => {
const res = await db.updateMany({
'_id': {
'$in': usernames
}
@ -113,6 +126,8 @@ module.exports = {
'modBoards': board
}
});
cache.del(`users:${username}`);
return res;
},
getOwnedOrModBoards: (usernames) => {
@ -140,9 +155,9 @@ module.exports = {
}).toArray();
},
setLevel: (usernames, level) => {
setLevel: async (usernames, level) => {
//increase users auth level
return db.updateMany({
const res = await db.updateMany({
'_id': {
'$in': usernames
}
@ -151,6 +166,8 @@ module.exports = {
'authLevel': level
}
});
cache.del(`users:${username}`);
return res;
},
deleteAll: () => {

@ -165,6 +165,7 @@ async function cache() {
Redis.deletePattern('boards:listed'),
Redis.deletePattern('board:*'),
Redis.deletePattern('banners:*'),
Redis.deletePattern('users:*'),
Redis.deletePattern('blacklisted:*'),
]);
Redis.redisClient.quit();

@ -2,8 +2,8 @@
module.exports = (req, res) => {
if (req.session) {
const { authenticated, user } = req.session;
if (authenticated === true && user != null) {
const { user } = res.locals;
if (user != null) {
if (user.authLevel < 4) { //assigned levels
return user.authLevel;
}

@ -1,13 +1,13 @@
'use strict';
module.exports = async (req, res, next) => {
if (req.session && req.session.authenticated === true) {
if (res.locals.user) {
return next();
}
let goto;
if (req.method === 'GET' && req.path) {
//coming from a GET page isLoggedIn middleware check
goto = req.path;
goto = encodeURIComponent(req.path);
}
return res.redirect(`/login.html${goto ? '?goto='+goto : ''}`);
}

@ -1,25 +1,31 @@
'use strict';
const { ipHeader, ipHashPermLevel } = require(__dirname+'/../configs/main.js')
, { isIP } = require('net')
, { parse } = require('ip6addr')
, hashIp = require(__dirname+'/haship.js');
module.exports = (req, res, next) => {
const ip = req.headers[ipHeader] || req.connection.remoteAddress;
const ipVersion = isIP(ip);
if (ipVersion) {
const delimiter = ipVersion === 4 ? '.' : ':';
let split = ip.split(delimiter);
try {
const ipParsed = parse(ip);
const ipStr = ipParsed.toString({
format: ipParsed.kind() === 'ipv4' ? 'v4' : 'v6',
zeroElide: false,
zeroPad: false,
});
const delimiter = ipParsed.kind() === 'ipv4' ? '.' : ':';
let split = ipStr.split(delimiter);
const qrange = split.slice(0,Math.floor(split.length*0.75)).join(delimiter);
const hrange = split.slice(0,Math.floor(split.length*0.5)).join(delimiter);
res.locals.ip = {
raw: ipHashPermLevel === -1 ? hashIp(ip) : ip,
single: hashIp(ip),
raw: ipHashPermLevel === -1 ? hashIp(ipStr) : ipStr,
single: hashIp(ipStr),
qrange: hashIp(qrange),
hrange: hashIp(hrange),
}
next();
} else {
} catch(e) {
console.error('Ip parse failed', e);
return res.status(400).render('message', {
'title': 'Bad request',
'message': 'Malformed IP' //should never get here

@ -1,20 +1,21 @@
'use strict';
const { Accounts } = require(__dirname+'/../db/');
const { Accounts } = require(__dirname+'/../db/')
, cache = require(__dirname+'/../redis.js');
module.exports = async (req, res, next) => {
if (req.session && req.session.authenticated === true) {
// keeping session updated incase user updated on global manage
const account = await Accounts.findOne(req.session.user.username);
if (req.session && req.session.user && !res.locals.user) {
const account = await Accounts.findOne(req.session.user);
if (!account) {
req.session.destroy();
} else {
req.session.user = {
res.locals.user = {
'username': account._id,
'authLevel': account.authLevel,
'modBoards': account.modBoards,
'ownedBoards': account.ownedBoards,
};
cache.set(`users:${req.session.user}`, res.locals.user, 3600);
}
}
next();

@ -0,0 +1,24 @@
'use strict';
const session = require('express-session')
, redisStore = require('connect-redis')(session)
, { sessionSecret, secureCookies } = require(__dirname+'/../configs/main.js')
, { redisClient } = require(__dirname+'/../redis.js')
, production = process.env.NODE_ENV === 'production'
, { DAY } = require(__dirname+'/timeutils.js');
module.exports = session({
secret: sessionSecret,
store: new redisStore({
client: redisClient,
}),
resave: false,
saveUninitialized: false,
rolling: true,
cookie: {
httpOnly: true,
secure: secureCookies && production,
sameSite: 'strict',
maxAge: DAY,
}
});

@ -277,7 +277,7 @@ module.exports = async (req, res, next) => {
const message = req.body.log_message || null;
let logUser;
if (res.locals.permLevel < 4) { //if staff
logUser = req.session.user.username;
logUser = req.session.user;
} else {
logUser = 'Unregistered User';
}

@ -12,7 +12,7 @@ module.exports = async (req, res, redirect) => {
const actionDate = new Date();
const banPromise = Bans.insertOne({
//note: raw ip and type single because of
//note: raw ip and type single because of
'type': 'single',
'ip': {
'single': isIP(req.body.ip) ? hashIp(req.body.ip) : req.body.ip,
@ -21,7 +21,7 @@ module.exports = async (req, res, redirect) => {
'reason': req.body.ban_reason || req.body.log_message || 'No reason specified',
'board': req.params.board || null,
'posts': null,
'issuer': req.session.user.username,
'issuer': req.session.user,
'date': actionDate,
'expireAt': new Date(actionDate.getTime() + (req.body.ban_duration || defaultBanDuration)),
'allowAppeal': req.body.no_appeal ? false : true,
@ -37,7 +37,7 @@ module.exports = async (req, res, redirect) => {
'date': actionDate,
'showUser': !req.body.hide_name || res.locals.permLevel >= 4 ? true : false,
'message': req.body.log_message || null,
'user': res.locals.permLevel < 4 ? req.session.user.username : 'Unregistered User',
'user': res.locals.permLevel < 4 ? req.session.user : 'Unregistered User',
'ip': {
'single': res.locals.ip.single,
'raw': res.locals.ip.raw

@ -41,7 +41,7 @@ module.exports = async (req, res, next) => {
'reason': banReason,
'board': banBoard,
'posts': req.body.preserve_post ? thisIpPosts : null,
'issuer': req.session.user.username,
'issuer': req.session.user,
'date': banDate,
'expireAt': banExpiry,
allowAppeal,
@ -78,7 +78,7 @@ module.exports = async (req, res, next) => {
'reason': banReason,
'board': banBoard,
'posts': null,
'issuer': req.session.user.username,
'issuer': req.session.user,
'date': banDate,
'expireAt': banExpiry,
allowAppeal,

@ -12,7 +12,7 @@ module.exports = async (req, res, next) => {
const { name, description } = req.body
, uri = req.body.uri.toLowerCase()
, tags = req.body.tags.split('\n').filter(n => n)
, owner = req.session.user.username;
, owner = req.session.user;
if (restrictedURIs.has(uri)) {
return dynamicResponse(req, res, 400, 'message', {

@ -122,7 +122,7 @@ todo: handle some more situations
}, {
'$set': {
edited: {
username: req.body.hide_name ? 'Hidden User' : req.session.user.username,
username: req.body.hide_name ? 'Hidden User' : req.session.user,
date: new Date(),
},
message,
@ -148,7 +148,7 @@ todo: handle some more situations
date: new Date(),
showUser: req.body.hide_name ? false : true,
message: req.body.log_message || null,
user: req.session.user.username,
user: req.session.user,
ip: {
single: res.locals.ip.single,
raw: res.locals.ip.raw,

@ -8,8 +8,12 @@ module.exports = async (req, res, next) => {
const username = req.body.username.toLowerCase();
const password = req.body.password;
const goto = req.body.goto || '/account.html';
const failRedirect = `/login.html${goto ? '?goto='+goto : ''}`
let goto = req.body.goto;
// we don't want to redirect the user to random sites
if (goto == null || !/^\/[0-9a-zA-Z][0-9a-zA-Z._/-]*$/.test(goto)) {
goto = '/account.html';
}
const failRedirect = `/login.html${goto ? '?goto='+encodeURIComponent(goto) : ''}`
//fetch an account
const account = await Accounts.findOne(username);
@ -30,13 +34,7 @@ module.exports = async (req, res, next) => {
if (passwordMatch === true) {
// add the account to the session and authenticate if password was correct
req.session.user = {
'username': account._id,
'authLevel': account.authLevel,
'ownedBoards': account.ownedBoards,
'modBoards': account.modBoards,
};
req.session.authenticated = true;
req.session.user = account._id;
//successful login
return res.redirect(goto);

@ -5,7 +5,7 @@ module.exports = async (req, res, next) => {
res
.set('Cache-Control', 'private, max-age=5')
.render('account', {
user: req.session.user,
user: res.locals.user,
});
}

20
package-lock.json generated

@ -788,8 +788,7 @@
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
"optional": true
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
"assign-symbols": {
"version": "1.0.0",
@ -2708,8 +2707,7 @@
"extsprintf": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
"optional": true
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
},
"fancy-log": {
"version": "1.3.3",
@ -4035,6 +4033,15 @@
"ipaddr.js": "^1.8.1"
}
},
"ip6addr": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/ip6addr/-/ip6addr-0.2.3.tgz",
"integrity": "sha512-qA9DXRAUW+lT47/i/4+Q3GHPwZjGt/atby1FH/THN6GVATA6+Pjp2nztH7k6iKeil7hzYnBwfSsxjthlJ8lJKw==",
"requires": {
"assert-plus": "^1.0.0",
"jsprim": "^1.4.0"
}
},
"ipaddr.js": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
@ -4300,8 +4307,7 @@
"json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
"optional": true
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
},
"json-schema-traverse": {
"version": "0.4.1",
@ -4333,7 +4339,6 @@
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
"optional": true,
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
@ -7967,7 +7972,6 @@
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
"optional": true,
"requires": {
"assert-plus": "^1.0.0",
"core-util-is": "1.0.2",

@ -30,6 +30,7 @@
"highlight.js": "^10.1.2",
"i18n-iso-countries": "^6.0.0",
"ioredis": "^4.14.1",
"ip6addr": "^0.2.3",
"mongodb": "^3.6.0",
"node-fetch": "^2.6.0",
"path": "^0.12.7",

@ -5,14 +5,12 @@ process
.on('unhandledRejection', console.error);
const express = require('express')
, session = require('express-session')
, redisStore = require('connect-redis')(session)
, path = require('path')
, app = express()
, server = require('http').createServer(app)
, cookieParser = require('cookie-parser')
, { cacheTemplates, boardDefaults, sessionSecret, globalLimits,
enableUserBoardCreation, enableUserAccountCreation, secureCookies,
, { cacheTemplates, boardDefaults, globalLimits,
enableUserBoardCreation, enableUserAccountCreation,
debugLogs, ipHashPermLevel, meta, port, enableWebring } = require(__dirname+'/configs/main.js')
, referrerCheck = require(__dirname+'/helpers/referrercheck.js')
, { themes, codeThemes } = require(__dirname+'/helpers/themes.js')
@ -20,7 +18,6 @@ const express = require('express')
, Socketio = require(__dirname+'/socketio.js')
, commit = require(__dirname+'/helpers/commit.js')
, dynamicResponse = require(__dirname+'/helpers/dynamic.js')
, { DAY } = require(__dirname+'/helpers/timeutils.js')
, CachePugTemplates = require('cache-pug-templates');
(async () => {
@ -46,24 +43,7 @@ const express = require('express')
app.use(cookieParser());
// session store
const sessionMiddleware = session({
secret: sessionSecret,
store: new redisStore({
client: redisClient,
}),
resave: false,
saveUninitialized: false,
rolling: true,
cookie: {
httpOnly: true,
secure: secureCookies && production,
sameSite: 'strict',
maxAge: DAY,
}
});
//add session middleware to express
app.use(sessionMiddleware);
const sessionMiddleware = require(__dirname+'/helpers/usesession.js');
// connect socketio
debugLogs && console.log('STARTING WEBSOCKET');

Loading…
Cancel
Save