Stert on setting for BO to prevent deleting old threads or ones with a lot of replies, ref #365

jschan
Thomas Lynch 3 years ago
parent 024a47a286
commit 20db8154e7
  1. 2
      CHANGELOG.md
  2. 2
      configs/template.js.example
  3. 7
      controllers/forms/boardsettings.js
  4. 14
      migrations/0.1.8.js
  5. 22
      models/forms/actionhandler.js
  6. 2
      models/forms/changeboardsettings.js
  7. 2
      package.json
  8. 6
      views/pages/managesettings.pug

@ -66,3 +66,5 @@
- Much improved nginx configuration for installation, script does most of the work
- Fixed settings form asking to save password -.-
- Multiple files & post flags now shown in catalog view
- Faster, more efficient global settings changes
- Add option for board owner to prevent OP deleting threads that are too old or have too many replies

@ -406,6 +406,8 @@ module.exports = {
filters: [], //words/phrases to block
filterMode: 0, //0=nothing, 1=prevent post, 2=auto ban
filterBanDuration: 0, //duration (in ms) to ban if filter mode=2
deleteProtectionAge: 0, //prevent non-staff OP from deleting their thread if it older than this age in ms
deleteProtectionCount: 0, //prevent non-staff op deleting their thread if it has more than this many replies
strictFiltering: false,
announcement: {
raw: null,

@ -1,3 +1,4 @@
'use strict';
const changeBoardSettings = require(__dirname+'/../../models/forms/changeboardsettings.js')
@ -12,12 +13,12 @@ const changeBoardSettings = require(__dirname+'/../../models/forms/changeboardse
module.exports = {
paramConverter: paramConverter({
timeFields: ['ban_duration'],
timeFields: ['ban_duration', 'delete_protection_age'],
trimFields: ['filters', 'moderators', 'tags', 'announcement', 'description', 'name', 'custom_css'],
allowedArrays: ['countries'],
numberFields: ['lock_reset', 'captcha_reset', 'filter_mode', 'lock_mode', 'message_r9k_mode', 'file_r9k_mode', 'captcha_mode', 'tph_trigger', 'pph_trigger', 'pph_trigger_action',
'tph_trigger_action', 'bump_limit', 'reply_limit', 'max_files', 'thread_limit', 'max_thread_message_length', 'max_reply_message_length', 'min_thread_message_length',
'min_reply_message_length'],
'min_reply_message_length', 'delete_protection_count'],
}),
controller: async (req, res, next) => {
@ -68,6 +69,8 @@ module.exports = {
{ result: numberBody(req.body.lock_reset, 0, 2), expected: true, error: 'Invalid trigger reset lock' },
{ result: numberBody(req.body.captcha_reset, 0, 2), expected: true, error: 'Invalid trigger reset captcha' },
{ result: numberBody(req.body.ban_duration, 0), expected: true, error: 'Invalid filter auto ban duration' },
{ result: numberBody(req.body.delete_protection_age, 0), expected: true, error: 'Invalid OP thread age delete protection' },
{ result: numberBody(req.body.delete_protection_count, 0), expected: true, error: 'Invalid OP thread reply count delete protection' },
{ result: inArrayBody(req.body.theme, themes), expected: true, error: 'Invalid theme' },
{ result: inArrayBody(req.body.code_theme, codeThemes), expected: true, error: 'Invalid code theme' },
], res.locals.permLevel);

@ -0,0 +1,14 @@
'use strict';
module.exports = async(db, redis) => {
console.log('Adding OP delete protection options to board settings');
await db.collection('boards').updateMany({}, {
'$set': {
'settings.deleteProtectionAge': 0,
'settings.deleteProtectionCount': 0,
}
});
console.log('Clearing boards cache');
await redis.deletePattern('board:*');
};

@ -56,7 +56,7 @@ module.exports = async (req, res, next) => {
redirect,
});
}
res.locals.posts = passwordPosts
res.locals.posts = passwordPosts;
}
//affected boards, list and page numbers
@ -96,6 +96,26 @@ module.exports = async (req, res, next) => {
messages.push(message);
}
if (deleting) {
if (res.locals.permLevel >= 4) {
//delete protection. this could only be single board actions obvously with permLevel >=4
const { deleteProtectionAge, deleteProtectionCount } = threadBoards[res.locals.posts[0].board].settings;
if (deleteProtectionAge > 0 || deleteProtectionCount > 0) {
const protectedThread = res.locals.posts.some(p => {
return p.thread === null //is a thread
&& ((deleteProtectionCount > 0 && p.replyposts > deleteProtectionCount) //and it has more replies than the protection count
|| (deleteProtectionAge > 0 && new Date(p.date + deleteProtectionAge) > new Date())); //or was created too recently
});
if (protectedThread != null) {
//alternatively, the above .some() could become a filter like some other options and silently not delete,
//but i think in this case it would be important to notify the user that their own thread(s) cant be deleted yet
return dynamicResponse(req, res, 403, 'message', {
'title': 'Forbidden',
'error': 'You cannot delete old threads or threads with too many replies',
redirect,
});
}
}
}
const postsBefore = res.locals.posts.length;
if (req.body.delete_ip_board || req.body.delete_ip_global || req.body.delete_ip_thread) {
const deletePostIps = res.locals.posts.map(x => x.ip.single);

@ -122,6 +122,8 @@ module.exports = async (req, res, next) => {
'fileR9KMode': numberSetting(req.body.file_r9k_mode, oldSettings.fileR9KMode),
'filterMode': numberSetting(req.body.filter_mode, oldSettings.filterMode),
'filterBanDuration': numberSetting(req.body.ban_duration, oldSettings.filterBanDuration),
'deleteProtectionAge': numberSetting(req.body.delete_protection_age, oldSettings.deleteProtectionAge),
'deleteProtectionCount': numberSetting(req.body.delete_protection_count, oldSettings.deleteProtectionCount),
'filters': arraySetting(req.body.filters, oldSettings.filters, 50),
'blockedCountries': req.body.countries || [],
'disableAnonymizerFilePosting': booleanSetting(req.body.disable_anonymizer_file_posting),

@ -1,7 +1,7 @@
{
"name": "jschan",
"version": "0.1.8",
"migrateVersion": "0.1.6",
"migrateVersion": "0.1.8",
"description": "",
"main": "server.js",
"dependencies": {

@ -212,6 +212,12 @@ block content
option(value='0', selected=board.settings.messageR9KMode === 0) Off
option(value='1', selected=board.settings.messageR9KMode === 1) Per Thread
option(value='2', selected=board.settings.messageR9KMode === 2) Board Wide
.row
.label OP Reply Count Delete Protection
input(type='number' name='delete_protection_count' value=board.settings.deleteProtectionCount)
.row
.label OP Thread Age Delete Protection
input(type='text' name='delete_protection_age' placeholder='e.g. 1w' value=board.settings.deleteProtectionAge)
.col.w900
.row
h4.mv-5 Antispam

Loading…
Cancel
Save