separate manage pages for bans, reports, settings and banners

merge-requests/208/head
fatchan 5 years ago
parent 2786704849
commit 7c0561d2ec
  1. 2
      controllers/forms/boardsettings.js
  2. 4
      controllers/forms/deletebanners.js
  3. 2
      controllers/forms/transfer.js
  4. 2
      controllers/forms/uploadbanners.js
  5. 9
      controllers/pages.js
  6. 4
      helpers/checks/haspermsmiddleware.js
  7. 1
      helpers/checks/isloggedin.js
  8. 2
      models/forms/changeboardsettings.js
  9. 3
      models/forms/deletebanners.js
  10. 2
      models/forms/transferboard.js
  11. 2
      models/forms/uploadbanners.js
  12. 17
      models/pages/manage.js
  13. 9
      models/pages/manage/banners.js
  14. 19
      models/pages/manage/bans.js
  15. 8
      models/pages/manage/index.js
  16. 19
      models/pages/manage/reports.js
  17. 9
      models/pages/manage/settings.js
  18. 2
      views/includes/navbar.pug
  19. 11
      views/mixins/managenav.pug
  20. 213
      views/pages/manage.pug
  21. 32
      views/pages/managebanners.pug
  22. 28
      views/pages/managebans.pug
  23. 25
      views/pages/managereports.pug
  24. 175
      views/pages/managesettings.pug

@ -67,7 +67,7 @@ module.exports = async (req, res, next) => {
return res.status(400).render('message', {
'title': 'Bad request',
'errors': errors,
'redirect': `/${req.params.board}/manage.html`
'redirect': `/${req.params.board}/manage/settings.html`
});
}

@ -14,7 +14,7 @@ module.exports = async (req, res, next) => {
return res.status(400).render('message', {
'title': 'Bad request',
'errors': errors,
'redirect': `/${req.params.board}/manage.html`
'redirect': `/${req.params.board}/manage/banners.html`
})
}
@ -23,7 +23,7 @@ module.exports = async (req, res, next) => {
return res.status(400).render('message', {
'title': 'Bad request',
'message': 'Invalid banners selected',
'redirect': `/${req.params.board}/manage.html`
'redirect': `/${req.params.board}/manage/banners.html`
})
}
}

@ -24,7 +24,7 @@ module.exports = async (req, res, next) => {
return res.status(400).render('message', {
'title': 'Bad request',
'errors': errors,
'redirect': `/${req.params.board}/manage.html`
'redirect': `/${req.params.board}/manage/settings.html`
})
}

@ -30,7 +30,7 @@ module.exports = async (req, res, next) => {
return res.status(400).render('message', {
'title': 'Bad request',
'errors': errors,
'redirect': `/${req.params.board}/manage.html`
'redirect': `/${req.params.board}/manage/banners.html`
})
}

@ -15,6 +15,7 @@ const express = require('express')
, home = require(__dirname+'/../models/pages/home.js')
, register = require(__dirname+'/../models/pages/register.js')
, manage = require(__dirname+'/../models/pages/manage.js')
, { managereports, managebanners, managesettings, managebans } = require(__dirname+'/../models/pages/manage/') //todo: refactor more into categories like this
, globalManage = require(__dirname+'/../models/pages/globalmanage.js')
, changePassword = require(__dirname+'/../models/pages/changepassword.js')
, login = require(__dirname+'/../models/pages/login.js')
@ -82,11 +83,15 @@ router.get('/logout', (req, res, next) => {
//public board banners page
router.get('/:board/banners.html', Boards.exists, banners);
//board manage page
router.get('/:board/manage.html', sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(3), csrf, manage);
//board manage pages
router.get('/:board/manage/reports.html', sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(3), csrf, managereports);
router.get('/:board/manage/bans.html', sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(3), csrf, managebans);
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);
//global manage page
router.get('/globalmanage.html', sessionRefresh, isLoggedIn, calcPerms, hasPerms(1), csrf, globalManage);
//todo: separate pages for global rports, bans, user management and news jsut like per-board manage pages
module.exports = router;

@ -9,10 +9,10 @@ module.exports = (requiredLevel) => {
return res.status(403).render('message', {
'title': 'Forbidden',
'message': 'No Permission',
'redirect': '/'
'redirect': req.headers.referer || '/'
});
}
next();
})
});
}

@ -2,7 +2,6 @@
module.exports = async (req, res, next) => {
if (req.session.authenticated === true) {
return next();
}
const board = req.params ? req.params.board : null;

@ -151,7 +151,7 @@ module.exports = async (req, res, next) => {
return res.render('message', {
'title': 'Success',
'message': 'Updated settings.',
'redirect': `/${req.params.board}/manage.html`
'redirect': `/${req.params.board}/manage/settings.html`
});
}

@ -1,3 +1,4 @@
'use strict';
const { remove } = require('fs-extra')
@ -7,7 +8,7 @@ const { remove } = require('fs-extra')
module.exports = async (req, res, next) => {
const redirect = `/${req.params.board}/manage.html`;
const redirect = `/${req.params.board}/manage/banners.html`;
//delete file of all selected banners
await Promise.all(req.body.checkedbanners.map(async filename => {

@ -10,7 +10,7 @@ module.exports = async (req, res, next) => {
return res.status(400).render('message', {
'title': 'Bad request',
'message': 'Cannot transfer to account that does not exist',
'redirect': `/${req.params.board}/manage.html`
'redirect': `/${req.params.board}/manage/settings.html`
});
}

@ -12,7 +12,7 @@ const path = require('path')
module.exports = async (req, res, next) => {
const redirect = `/${req.params.board}/manage.html`
const redirect = `/${req.params.board}/manage/banners.html`
// check all mime types before we try saving anything
for (let i = 0; i < res.locals.numFiles; i++) {

@ -1,24 +1,9 @@
'use strict';
const Posts = require(__dirname+'/../../db/posts.js')
, Bans = require(__dirname+'/../../db/bans.js')
module.exports = async (req, res, next) => {
let reports;
let bans;
try {
reports = await Posts.getReports(req.params.board);
bans = await Bans.getBoardBans(req.params.board);
} catch (err) {
return next(err)
}
//render the page
res.render('manage', {
csrf: req.csrfToken(),
reports,
bans,
//csrf: req.csrfToken(),
});
}

@ -0,0 +1,9 @@
'use strict';
module.exports = async (req, res, next) => {
res.render('managebanners', {
csrf: req.csrfToken(),
});
}

@ -0,0 +1,19 @@
'use strict';
const Bans = require(__dirname+'/../../../db/bans.js');
module.exports = async (req, res, next) => {
let bans;
try {
bans = await Bans.getBoardBans(req.params.board);
} catch (err) {
return next(err)
}
res.render('managebans', {
csrf: req.csrfToken(),
bans,
});
}

@ -0,0 +1,8 @@
'use strict';
module.exports = {
managereports: require(__dirname+'/reports.js'),
managesettings: require(__dirname+'/settings.js'),
managebans: require(__dirname+'/bans.js'),
managebanners: require(__dirname+'/banners.js'),
}

@ -0,0 +1,19 @@
'use strict';
const Posts = require(__dirname+'/../../../db/posts.js');
module.exports = async (req, res, next) => {
let reports;
try {
reports = await Posts.getReports(req.params.board);
} catch (err) {
return next(err)
}
res.render('managereports', {
csrf: req.csrfToken(),
reports,
});
}

@ -0,0 +1,9 @@
'use strict';
module.exports = async (req, res, next) => {
res.render('managesettings', {
csrf: req.csrfToken(),
});
}

@ -1,6 +1,6 @@
nav.navbar#top
a.nav-item(href='/') Home
a.nav-item(href='/news.html') News
a.nav-item(href=`/${board ? board._id+'/' : 'global'}manage.html`) Manage
a.nav-item(href=`/${board ? board._id+'/manage/settings' : 'globalmanage'}.html`) Manage
a.nav-item(href='/create.html') Create
a.nav-item.right(href='/logout') Logout

@ -0,0 +1,11 @@
mixin managenav(selected)
nav.pages
a(href=`/${board._id}/index.html`) [Index]
|
a(href=`/${board._id}/manage/reports.html` class=(selected === 'reports' ? 'bold' : '')) [Reports]
|
a(href=`/${board._id}/manage/bans.html` class=(selected === 'bans' ? 'bold' : '')) [Bans]
|
a(href=`/${board._id}/manage/settings.html` class=(selected === 'settings' ? 'bold' : '')) [Settings]
|
a(href=`/${board._id}/manage/banners.html` class=(selected === 'banners' ? 'bold' : '')) [Banners]

@ -1,6 +1,5 @@
extends ../layout.pug
include ../mixins/post.pug
include ../mixins/ban.pug
include ../mixins/managenav.pug
block head
script(src='/js/all.js')
@ -9,212 +8,6 @@ block head
block content
include ../includes/boardheader.pug
br
h4.no-m-p Transfer ownership:
section.form-wrapper.flexleft.mt-10
form.form-post(action=`/forms/board/${board._id}/transfer`, enctype='application/x-www-form-urlencoded', method='POST')
input(type='hidden' name='_csrf' value=csrf)
section.row
.label New owner username
input(type='text' name='username' placeholder=board.owner required)
input(type='submit', value='submit')
+managenav('main')
hr(size=1)
h4.no-m-p Delete board:
section.form-wrapper.flexleft.mt-10
form.form-post(action=`/forms/board/${board._id}/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')
hr(size=1)
h4.no-m-p Settings:
section.form-wrapper.flexleft.mt-10
form.form-post(action=`/forms/board/${board._id}/settings` method='POST' enctype='application/x-www-form-urlencoded')
input(type='hidden' name='_csrf' value=csrf)
section.row
.label Board name
input(type='text' name='name' value=board.settings.name)
section.row
.label Board Description
input(type='text' name='description' value=board.settings.description)
section.row
.label Tags
textarea(name='tags' placeholder='newline separated, max 10') #{board.settings.tags.join('\n')}
section.row
.label Announcement
textarea(name='announcement' placeholder='supports post styling') #{board.settings.announcement.raw}
section.row
.label Anon Name
input(type='text' name='default_name' value=board.settings.defaultName)
section.row
.label Max Files
input(type='number' name='max_files' value=board.settings.maxFiles max=globalLimits.postFiles.max)
section.row
.label Allow Video Files
label.postform-style.ph-5
input(type='checkbox', name='files_allow_video', value='true' checked=board.settings.allowedFileTypes.video)
section.row
.label Allow Image Files
label.postform-style.ph-5
input(type='checkbox', name='files_allow_image', value='true' checked=board.settings.allowedFileTypes.image)
section.row
.label Allow Animated Image Files
label.postform-style.ph-5
input(type='checkbox', name='files_allow_animated_image', value='true' checked=board.settings.allowedFileTypes.animatedImage)
section.row
.label Early 404
label.postform-style.ph-5
input(type='checkbox', name='early404', value='true' checked=board.settings.early404)
section.row
.label IDs
label.postform-style.ph-5
input(type='checkbox', name='ids', value='true' checked=board.settings.ids)
section.row
.label Geo Flags
label.postform-style.ph-5
input(type='checkbox', name='flags', value='true' checked=board.settings.flags)
section.row
.label User Post Deletion
label.postform-style.ph-5
input(type='checkbox', name='user_post_delete', value='true' checked=board.settings.userPostDelete)
section.row
.label User File Spoilering
label.postform-style.ph-5
input(type='checkbox', name='user_post_spoiler', value='true' checked=board.settings.userPostSpoiler)
section.row
.label User File Unlinking
label.postform-style.ph-5
input(type='checkbox', name='user_post_unlink', value='true' checked=board.settings.userPostUnlink)
section.row
.label Force Anon
label.postform-style.ph-5
input(type='checkbox', name='force_anon', value='true' checked=board.settings.forceAnon)
section.row
.label Force Thread Subject
label.postform-style.ph-5
input(type='checkbox', name='force_thread_subject', value='true' checked=board.settings.forceThreadSubject)
section.row
.label Force Thread Message
label.postform-style.ph-5
input(type='checkbox', name='force_thread_message', value='true' checked=board.settings.forceThreadMessage)
section.row
.label Force Thread File
label.postform-style.ph-5
input(type='checkbox', name='force_thread_file', value='true' checked=board.settings.forceThreadFile)
section.row
.label Force Reply Message
label.postform-style.ph-5
input(type='checkbox', name='force_reply_message', value='true' checked=board.settings.forceReplyMessage)
section.row
.label Force Reply File
label.postform-style.ph-5
input(type='checkbox', name='force_reply_file', value='true' checked=board.settings.forceReplyFile)
section.row
.label Min Thread Message Length
input(type='number' name='min_thread_message_length' value=board.settings.minThreadMessageLength max=globalLimits.messageLength.max)
section.row
.label Min Reply Message Length
input(type='number' name='min_reply_message_length' value=board.settings.minReplyMessageLength max=globalLimits.messageLength.max)
section.row
.label Thread Limit
input(type='number' name='thread_limit' value=board.settings.threadLimit min=globalLimits.threadLimit.min max=globalLimits.threadLimit.max)
section.row
.label Reply Limit
input(type='number' name='reply_limit' value=board.settings.replyLimit min=globalLimits.replyLimit.min max=globalLimits.replyLimit.max)
section.row
.label Moderators
textarea(name='moderators' placeholder='newline separated, max 10') #{board.settings.moderators.join('\n')}
section.row
.label Board Locked
label.postform-style.ph-5
input(type='checkbox', name='locked', value='true' checked=board.settings.locked)
section.row
.label Unlisted
label.postform-style.ph-5
input(type='checkbox', name='unlisted', value='true' checked=board.settings.unlisted)
section.row
.label Theme
select(name='theme')
each theme in themes
option(value=theme selected=board.settings.theme === theme) #{theme}
section.row
.label Captcha Mode
select(name='captcha_mode')
option(value='0', selected=board.settings.captchaMode === 0) No Captcha
option(value='1', selected=board.settings.captchaMode === 1) Captcha for new thread
option(value='2', selected=board.settings.captchaMode === 2) Captcha for all posts
section.row
.label TPH Trigger Threshold
input(type='number', name='tph_trigger', value=board.settings.tphTrigger)
section.row
.label TPH Trigger Action
select(name='tph_trigger_action')
option(value='0', selected=board.settings.tphTriggerAction === 0) Do nothing
option(value='1', selected=board.settings.tphTriggerAction === 1) Enable captcha for new thread
option(value='2', selected=board.settings.tphTriggerAction === 2) Enable captcha for all posts
option(value='3', selected=board.settings.tphTriggerAction === 3) Lock Board
section.row
.label Filters
textarea(name='filters' placeholder='newline separated, max 50') #{board.settings.filters.join('\n')}
section.row
.label Filter Mode
select(name='filter_mode')
option(value='0', selected=board.settings.filterMode === 0) Do nothing
option(value='1', selected=board.settings.filterMode === 1) Block post
option(value='2', selected=board.settings.filterMode === 2) Auto ban
section.row
.label Filter Auto Ban Duration
input(type='text' name='ban_duration' placeholder='e.g. 1w' value=board.settings.filterBanDuration)
input(type='submit', value='save settings')
hr(size=1)
h4.no-m-p Add Banners:
section.form-wrapper.flexleft.mt-10
form.form-post(action=`/forms/board/${board._id}/addbanners`, enctype='multipart/form-data', method='POST')
input(type='hidden' name='_csrf' value=csrf)
section.row
.label Upload
.required *
input#file(type='file', name='file' multiple required)
input(type='submit', value='submit')
hr(size=1)
if board.banners.length > 0
h4.no-m-p Delete Banners:
section.form-wrapper.flexleft.mt-10
form.form-post(action=`/forms/board/${board._id}/deletebanners`, enctype='application/x-www-form-urlencoded', method='POST')
input(type='hidden' name='_csrf' value=csrf)
each banner in board.banners
label.banner-check
input(type='checkbox' name='checkedbanners[]' value=banner)
img.board-banner(src=`/banner/${board._id}/${banner}` width='300' height='100')
input(type='submit', value='delete')
hr(size=1)
h4.no-m-p Reports:
form(action=`/forms/board/${board._id}/modactions` method='POST' enctype='application/x-www-form-urlencoded')
input(type='hidden' name='_csrf' value=csrf)
if reports.length === 0
p No reports.
else
for report in reports
section.thread
+post(report, false, true)
hr(size=1)
include ../includes/actionfooter_manage.pug
hr(size=1)
h4.no-m-p Bans & Appeals:
form(action=`/forms/board/${board._id}/unban` method='POST' enctype='application/x-www-form-urlencoded')
input(type='hidden' name='_csrf' value=csrf)
if bans.length === 0
p No bans.
hr(size=1)
else
for ban in bans
section.thread
+ban(ban)
hr(size=1)
section.action-wrapper
input(type='submit', value='unban')
p Welcome to the management page. #[a(href=`/{board._id}/index.html`) Return]

@ -0,0 +1,32 @@
extends ../layout.pug
include ../mixins/managenav.pug
block head
script(src='/js/theme.js')
title /#{board._id}/ - Manage Banners
block content
include ../includes/boardheader.pug
br
+managenav('banners')
hr(size=1)
h4.no-m-p Add Banners:
section.form-wrapper.flexleft.mt-10
form.form-post(action=`/forms/board/${board._id}/addbanners`, enctype='multipart/form-data', method='POST')
input(type='hidden' name='_csrf' value=csrf)
section.row
.label Upload
.required *
input#file(type='file', name='file' multiple required)
input(type='submit', value='submit')
if board.banners.length > 0
hr(size=1)
h4.no-m-p Delete Banners:
section.form-wrapper.flexleft.mt-10
form.form-post(action=`/forms/board/${board._id}/deletebanners`, enctype='application/x-www-form-urlencoded', method='POST')
input(type='hidden' name='_csrf' value=csrf)
each banner in board.banners
label.banner-check
input(type='checkbox' name='checkedbanners[]' value=banner)
img.board-banner(src=`/banner/${board._id}/${banner}` width='300' height='100')
input(type='submit', value='delete')

@ -0,0 +1,28 @@
extends ../layout.pug
include ../mixins/ban.pug
include ../mixins/managenav.pug
block head
script(src='/js/theme.js')
script(src='/js/expand.js')
script(src='/js/hover.js')
title /#{board._id}/ - Manage Bans & Appeals
block content
include ../includes/boardheader.pug
br
+managenav('bans')
hr(size=1)
h4.no-m-p Bans & Appeals:
form(action=`/forms/board/${board._id}/unban` method='POST' enctype='application/x-www-form-urlencoded')
input(type='hidden' name='_csrf' value=csrf)
if bans.length === 0
p No bans.
else
for ban in bans
section.thread
+ban(ban)
hr(size=1)
section.action-wrapper
input(type='submit', value='unban')

@ -0,0 +1,25 @@
extends ../layout.pug
include ../mixins/post.pug
include ../mixins/ban.pug
include ../mixins/managenav.pug
block head
script(src='/js/all.js')
title /#{board._id}/ - Manage
block content
include ../includes/boardheader.pug
br
+managenav('reports')
hr(size=1)
h4.no-m-p Reports:
form(action=`/forms/board/${board._id}/modactions` method='POST' enctype='application/x-www-form-urlencoded')
input(type='hidden' name='_csrf' value=csrf)
if reports.length === 0
p No reports.
else
for report in reports
section.thread
+post(report, false, true)
hr(size=1)
include ../includes/actionfooter_manage.pug

@ -0,0 +1,175 @@
extends ../layout.pug
include ../mixins/post.pug
include ../mixins/ban.pug
include ../mixins/managenav.pug
block head
script(src='/js/all.js')
title /#{board._id}/ - Manage
block content
include ../includes/boardheader.pug
br
+managenav('settings')
hr(size=1)
h4.no-m-p Transfer ownership:
section.form-wrapper.flexleft.mt-10
form.form-post(action=`/forms/board/${board._id}/transfer`, enctype='application/x-www-form-urlencoded', method='POST')
input(type='hidden' name='_csrf' value=csrf)
section.row
.label New owner username
input(type='text' name='username' placeholder=board.owner required)
input(type='submit', value='submit')
hr(size=1)
h4.no-m-p Delete board:
section.form-wrapper.flexleft.mt-10
form.form-post(action=`/forms/board/${board._id}/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')
hr(size=1)
h4.no-m-p Settings:
section.form-wrapper.flexleft.mt-10
form.form-post(action=`/forms/board/${board._id}/settings` method='POST' enctype='application/x-www-form-urlencoded')
input(type='hidden' name='_csrf' value=csrf)
section.row
.label Board name
input(type='text' name='name' value=board.settings.name)
section.row
.label Board Description
input(type='text' name='description' value=board.settings.description)
section.row
.label Tags
textarea(name='tags' placeholder='newline separated, max 10') #{board.settings.tags.join('\n')}
section.row
.label Announcement
textarea(name='announcement' placeholder='supports post styling') #{board.settings.announcement.raw}
section.row
.label Anon Name
input(type='text' name='default_name' value=board.settings.defaultName)
section.row
.label Max Files
input(type='number' name='max_files' value=board.settings.maxFiles max=globalLimits.postFiles.max)
section.row
.label Allow Video Files
label.postform-style.ph-5
input(type='checkbox', name='files_allow_video', value='true' checked=board.settings.allowedFileTypes.video)
section.row
.label Allow Image Files
label.postform-style.ph-5
input(type='checkbox', name='files_allow_image', value='true' checked=board.settings.allowedFileTypes.image)
section.row
.label Allow Animated Image Files
label.postform-style.ph-5
input(type='checkbox', name='files_allow_animated_image', value='true' checked=board.settings.allowedFileTypes.animatedImage)
section.row
.label Early 404
label.postform-style.ph-5
input(type='checkbox', name='early404', value='true' checked=board.settings.early404)
section.row
.label IDs
label.postform-style.ph-5
input(type='checkbox', name='ids', value='true' checked=board.settings.ids)
section.row
.label Geo Flags
label.postform-style.ph-5
input(type='checkbox', name='flags', value='true' checked=board.settings.flags)
section.row
.label User Post Deletion
label.postform-style.ph-5
input(type='checkbox', name='user_post_delete', value='true' checked=board.settings.userPostDelete)
section.row
.label User File Spoilering
label.postform-style.ph-5
input(type='checkbox', name='user_post_spoiler', value='true' checked=board.settings.userPostSpoiler)
section.row
.label User File Unlinking
label.postform-style.ph-5
input(type='checkbox', name='user_post_unlink', value='true' checked=board.settings.userPostUnlink)
section.row
.label Force Anon
label.postform-style.ph-5
input(type='checkbox', name='force_anon', value='true' checked=board.settings.forceAnon)
section.row
.label Force Thread Subject
label.postform-style.ph-5
input(type='checkbox', name='force_thread_subject', value='true' checked=board.settings.forceThreadSubject)
section.row
.label Force Thread Message
label.postform-style.ph-5
input(type='checkbox', name='force_thread_message', value='true' checked=board.settings.forceThreadMessage)
section.row
.label Force Thread File
label.postform-style.ph-5
input(type='checkbox', name='force_thread_file', value='true' checked=board.settings.forceThreadFile)
section.row
.label Force Reply Message
label.postform-style.ph-5
input(type='checkbox', name='force_reply_message', value='true' checked=board.settings.forceReplyMessage)
section.row
.label Force Reply File
label.postform-style.ph-5
input(type='checkbox', name='force_reply_file', value='true' checked=board.settings.forceReplyFile)
section.row
.label Min Thread Message Length
input(type='number' name='min_thread_message_length' value=board.settings.minThreadMessageLength max=globalLimits.messageLength.max)
section.row
.label Min Reply Message Length
input(type='number' name='min_reply_message_length' value=board.settings.minReplyMessageLength max=globalLimits.messageLength.max)
section.row
.label Thread Limit
input(type='number' name='thread_limit' value=board.settings.threadLimit min=globalLimits.threadLimit.min max=globalLimits.threadLimit.max)
section.row
.label Reply Limit
input(type='number' name='reply_limit' value=board.settings.replyLimit min=globalLimits.replyLimit.min max=globalLimits.replyLimit.max)
section.row
.label Moderators
textarea(name='moderators' placeholder='newline separated, max 10') #{board.settings.moderators.join('\n')}
section.row
.label Board Locked
label.postform-style.ph-5
input(type='checkbox', name='locked', value='true' checked=board.settings.locked)
section.row
.label Unlisted
label.postform-style.ph-5
input(type='checkbox', name='unlisted', value='true' checked=board.settings.unlisted)
section.row
.label Theme
select(name='theme')
each theme in themes
option(value=theme selected=board.settings.theme === theme) #{theme}
section.row
.label Captcha Mode
select(name='captcha_mode')
option(value='0', selected=board.settings.captchaMode === 0) No Captcha
option(value='1', selected=board.settings.captchaMode === 1) Captcha for new thread
option(value='2', selected=board.settings.captchaMode === 2) Captcha for all posts
section.row
.label TPH Trigger Threshold
input(type='number', name='tph_trigger', value=board.settings.tphTrigger)
section.row
.label TPH Trigger Action
select(name='tph_trigger_action')
option(value='0', selected=board.settings.tphTriggerAction === 0) Do nothing
option(value='1', selected=board.settings.tphTriggerAction === 1) Enable captcha for new thread
option(value='2', selected=board.settings.tphTriggerAction === 2) Enable captcha for all posts
option(value='3', selected=board.settings.tphTriggerAction === 3) Lock Board
section.row
.label Filters
textarea(name='filters' placeholder='newline separated, max 50') #{board.settings.filters.join('\n')}
section.row
.label Filter Mode
select(name='filter_mode')
option(value='0', selected=board.settings.filterMode === 0) Do nothing
option(value='1', selected=board.settings.filterMode === 1) Block post
option(value='2', selected=board.settings.filterMode === 2) Auto ban
section.row
.label Filter Auto Ban Duration
input(type='text' name='ban_duration' placeholder='e.g. 1w' value=board.settings.filterBanDuration)
input(type='submit', value='save settings')
Loading…
Cancel
Save