Add v1.2.0 migration for filters stuff

Add global limits filters max
Remove unused settings body checks in board/global settings controllers related to filters
Update en locale with a few more filter strings
merge-requests/341/head
Thomas Lynch 11 months ago
parent 132b474a0d
commit 2a51aabf92
  1. 3
      configs/template.js.example
  2. 9
      controllers/forms/boardsettings.js
  3. 13
      controllers/forms/globalsettings.js
  4. 8
      db/filters.js
  5. 6
      locales/en-GB.json
  6. 72
      migrations/1.2.0.js
  7. 14
      models/forms/addfilter.js
  8. 5
      models/forms/changeglobalsettings.js
  9. 4
      package.json
  10. 3
      views/pages/globalmanagesettings.pug

@ -327,6 +327,9 @@ module.exports = {
customPages: {
max: 10, //max number of custom pages per board
maxLength: 10000, //max number of characters to allow per page
},
filters: {
max: 50,
}
},

@ -14,10 +14,10 @@ const changeBoardSettings = require(__dirname+'/../../models/forms/changeboardse
module.exports = {
paramConverter: paramConverter({
timeFields: ['ban_duration', 'delete_protection_age'],
trimFields: ['filters', 'tags', 'announcement', 'description', 'name', 'custom_css', 'language'],
timeFields: ['delete_protection_age'],
trimFields: ['tags', 'announcement', 'description', 'name', 'custom_css', 'language'],
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',
numberFields: ['lock_reset', 'captcha_reset', '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', 'delete_protection_count'],
}),
@ -34,7 +34,6 @@ module.exports = {
{ result: lengthBody(req.body.description, 0, globalLimits.fieldLength.description), expected: false, error: __('Board description must be %s characters or less', globalLimits.fieldLength.description) },
{ result: lengthBody(req.body.announcements, 0, 5000), expected: false, error: __('Board announcements must be 5000 characters or less') },
{ result: lengthBody(req.body.tags, 0, 2000), expected: false, error: __('Tags length must be 2000 characters or less') },
{ result: lengthBody(req.body.filters, 0, 20000), expected: false, error: __('Filters length must be 20000 characters or less') },
{ result: lengthBody(req.body.custom_css, 0, globalLimits.customCss.max), expected: false, error: __('Custom CSS must be %s characters or less', globalLimits.customCss.max) },
{ result: arrayInBody(globalLimits.customCss.filters, req.body.custom_css), permission: Permissions.ROOT, expected: false, error: __('Custom CSS strict mode is enabled and does not allow the following: "%s"', globalLimits.customCss.filters.join('", "')) },
{ result: lengthBody(req.body.name, 1, globalLimits.fieldLength.boardname), expected: false, error: __('Board name must be 1-%s characters', globalLimits.fieldLength.boardname) },
@ -63,14 +62,12 @@ module.exports = {
error: __('Max reply message length must be 0-%s and not less than "Min Reply Message Length" (currently %s)', globalLimits.fieldLength.message, res.locals.board.settings.minReplyMessageLength) },
{ result: numberBody(req.body.lock_mode, 0, 2), expected: true, error: __('Invalid lock mode') },
{ result: numberBody(req.body.captcha_mode, 0, 2), expected: true, error: __('Invalid captcha mode') },
{ result: numberBody(req.body.filter_mode, 0, 2), expected: true, error: __('Invalid filter mode') },
{ result: numberBody(req.body.tph_trigger, 0, 10000), expected: true, error: __('Invalid tph trigger threshold') },
{ result: numberBody(req.body.tph_trigger_action, 0, 4), expected: true, error: __('Invalid tph trigger action') },
{ result: numberBody(req.body.pph_trigger, 0, 10000), expected: true, error: __('Invalid pph trigger threshold') },
{ result: numberBody(req.body.pph_trigger_action, 0, 4), expected: true, error: __('Invalid pph trigger action') },
{ 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.language, i18n.getLocales()), expected: true, error: __('Invalid language') },

@ -13,15 +13,15 @@ const changeGlobalSettings = require(__dirname+'/../../models/forms/changeglobal
module.exports = {
paramConverter: paramConverter({
timeFields: ['hot_threads_max_age', 'inactive_account_time', 'ban_duration', 'board_defaults_filter_ban_duration', 'default_ban_duration', 'block_bypass_expire_after_time', 'dnsbl_cache_time', 'board_defaults_delete_protection_age'],
timeFields: ['hot_threads_max_age', 'inactive_account_time', 'default_ban_duration', 'block_bypass_expire_after_time', 'dnsbl_cache_time', 'board_defaults_delete_protection_age'],
trimFields: ['captcha_options_grid_question', 'captcha_options_grid_trues', 'captcha_options_grid_falses', 'captcha_options_font', 'allowed_hosts', 'dnsbl_blacklists', 'other_mime_types',
'highlight_options_language_subset', 'global_limits_custom_css_filters', 'board_defaults_filters', 'filters', 'archive_links', 'reverse_links', 'language', 'board_defaults_language'],
numberFields: ['inactive_account_action', 'abandoned_board_action', 'filter_mode', 'auth_level', 'captcha_options_text_wave', 'captcha_options_text_paint', 'captcha_options_text_noise',
numberFields: ['inactive_account_action', 'abandoned_board_action', 'auth_level', 'captcha_options_text_wave', 'captcha_options_text_paint', 'captcha_options_text_noise',
'captcha_options_grid_noise', 'captcha_options_grid_edge', 'captcha_options_generate_limit', 'captcha_options_grid_size', 'captcha_options_grid_image_size',
'captcha_options_num_distorts_min', 'captcha_options_num_distorts_max', 'captcha_options_distortion', 'captcha_options_grid_icon_y_offset', 'flood_timers_same_content_same_ip', 'flood_timers_same_content_any_ip',
'flood_timers_any_content_same_ip', 'block_bypass_expire_after_uses', 'rate_limit_cost_captcha', 'rate_limit_cost_board_settings', 'rate_limit_cost_edit_post',
'overboard_limit', 'hot_threads_limit', 'hot_threads_threshold', 'overboard_catalog_limit', 'lock_wait', 'prune_modlogs', 'prune_ips', 'thumb_size', 'video_thumb_percentage', 'quote_limit', 'preview_replies',
'sticky_preview_replies', 'early_404_fraction', 'early_404_replies', 'max_recent_news', 'highlight_options_threshold', 'global_limits_thread_limit_min',
'sticky_preview_replies', 'early_404_fraction', 'early_404_replies', 'max_recent_news', 'highlight_options_threshold', 'global_limits_thread_limit_min', 'global_limits_filters_max',
'global_limits_thread_limit_max', 'global_limits_reply_limit_min', 'global_limits_reply_limit_max', 'global_limits_bump_limit_min', 'global_limits_bump_limit_max',
'global_limits_post_files_max', 'global_limits_post_files_size_max', 'global_limits_asset_files_total', 'global_limits_asset_files_max', 'global_limits_asset_files_size_max',
'global_limits_banner_files_width', 'global_limits_banner_files_height', 'global_limits_banner_files_max',
@ -33,7 +33,7 @@ module.exports = {
'board_defaults_lock_mode', 'board_defaults_file_r9k_mode', 'board_defaults_message_r9k_mode', 'board_defaults_captcha_mode', 'board_defaults_tph_trigger',
'board_defaults_pph_trigger', 'board_defaults_tph_trigger_action', 'board_defaults_pph_trigger_action', 'board_defaults_captcha_reset', 'board_defaults_lock_reset',
'board_defaults_thread_limit', 'board_defaults_reply_limit', 'board_defaults_bump_limit', 'board_defaults_max_files', 'board_defaults_min_thread_message_length',
'board_defaults_min_reply_message_length', 'board_defaults_max_thread_message_length', 'board_defaults_max_reply_message_length', 'board_defaults_filter_mode',
'board_defaults_min_reply_message_length', 'board_defaults_max_thread_message_length', 'board_defaults_max_reply_message_length',
'board_defaults_delete_protection_count', 'frontend_script_default_tegaki_height', 'frontend_script_default_tegaki_width', 'global_limits_post_files_size_image_resolution', 'global_limits_post_files_size_video_resolution']
}),
@ -79,8 +79,6 @@ module.exports = {
{ result: numberBody(req.body.abandoned_board_action, 0, 3), expected: true, error: __('Abandoned board action must be a number from 0-3') },
{ result: lengthBody(req.body.global_announcement, 0, 10000), expected: false, error: __('Global announcement must not exceed 10000 characters') },
{ result: lengthBody(req.body.filters, 0, 50000), expected: false, error: __('Filter text cannot exceed 50000 characters') },
{ result: numberBody(req.body.filter_mode, 0, 2), expected: true, error: __('Filter mode must be a number from 0-2') },
{ result: numberBody(req.body.ban_duration), expected: true, error: __('Invalid filter auto ban duration') },
{ result: lengthBody(req.body.allowed_hosts, 0, 10000), expected: false, error: __('Allowed hosts must not exceed 10000 characters') },
{ result: lengthBody(req.body.country_code_header, 0, 100), expected: false, error: __('Country code header length must not exceed 100 characters') },
{ result: lengthBody(req.body.ip_header, 0, 100), expected: false, error: __('IP header length must not exceed 100 characters') },
@ -170,6 +168,7 @@ module.exports = {
{ result: numberBody(req.body.global_limits_field_length_description), expected: true, error: __('Global limit board description field length must be a number') },
{ result: numberBody(req.body.global_limits_multi_input_posts_anon), expected: true, error: __('Multi input anon limit must be a number') },
{ result: numberBody(req.body.global_limits_multi_input_posts_staff), expected: true, error: __('Multi input staff limit must be a number') },
{ result: numberBody(req.body.global_limits_filters_max), expected: true, error: __('Filters max must be a number') },
{ result: numberBody(req.body.global_limits_custom_css_max), expected: true, error: __('Custom css max must be a number') },
{ result: lengthBody(req.body.global_limits_custom_css_filters, 0, 10000), expected: false, error: __('Custom css filters must not exceed 10000 characters') },
{ result: numberBody(req.body.global_limits_custom_pages_max), expected: true, error: __('Custom pages max must be a number') },
@ -196,11 +195,9 @@ module.exports = {
{ result: numberBody(req.body.board_defaults_min_reply_message_length), expected: true, error: __('Board defaults min reply message length must be a number') },
{ result: minmaxBody(req.body.board_defaults_min_thread_message_length, req.body.board_defaults_max_thread_message_length), expected: true, error: __('Board defaults thread message length min must be less than max') },
{ result: minmaxBody(req.body.board_defaults_min_reply_message_length, req.body.board_defaults_max_reply_message_length), expected: true, error: __('Board defaults reply message length min must be less than max') },
{ result: numberBody(req.body.board_defaults_filter_mode, 0, 2), expected: true, error: __('Board defaults filter mode must be a number from 0-2') },
{ result: numberBody(req.body.frontend_script_default_volume, 0, 100), expected: true, error: __('Default volume must be a number from 0-100') },
{ result: numberBody(req.body.frontend_script_default_tegaki_width), expected: true, error: __('Tegaki width must be a number') },
{ result: numberBody(req.body.frontend_script_default_tegaki_height), expected: true, error: __('Tegaki height must be a number') },
{ result: numberBody(req.body.board_defaults_filter_ban_duration), expected: true, error: __('Board defaults filter ban duration must be a number') },
{ result: numberBody(req.body.board_defaults_delete_protection_age, 0), expected: true, error: __('Invalid board defaults OP thread age delete protection') },
{ result: numberBody(req.body.board_defaults_delete_protection_count, 0), expected: true, error: __('Invalid board defaults OP thread reply count delete protection') },
{ result: lengthBody(req.body.webring_following, 0, 10000), expected: false, error: __('Webring following list must not exceed 10000 characters') },

@ -17,6 +17,10 @@ module.exports = {
.toArray();
},
count: (board) => {
return db.countDocuments({'board': board});
},
findOne: (board, id) => {
return db.findOne({
'_id': id,
@ -40,8 +44,8 @@ module.exports = {
});
},
insertOne: (filters) => {
return db.insertOne(filters);
insertOne: (filter) => {
return db.insertOne(filter);
},
deleteMany: (board, ids) => {

@ -1396,5 +1396,9 @@
"%s earlier": "%s earlier",
"Lock+Unlist board": "Lock+Unlist board",
"Please enter at least one allowed host in the \"Allowed Hosts\" field when the \"Referer Check\" option is selected.": "Please enter at least one allowed host in the \"Allowed Hosts\" field when the \"Referer Check\" option is selected.",
"pt-BR": "Brazilian Portuguese"
"pt-BR": "Brazilian Portuguese",
"Filters max must be a number": "Filters max must be a number",
"Max Filters Per Board": "Max Filters Per Board",
"Filters FAQ": "Filters FAQ",
"Total number of filters would exceed global limit of %s": "Total number of filters would exceed global limit of %s"
}

@ -0,0 +1,72 @@
'use strict';
module.exports = async(db, redis) => {
console.log('Updating globalsettings to add filter limit');
await db.collection('globalsettings').updateOne({ _id: 'globalsettings' }, {
'$set': {
'globalLimits.filters': {
max: 50,
},
},
});
console.log('Updating globalsettings to convert old filters into new filter db format');
const globalSettings = await db.collection('globalsettings').findOne({ _id: 'globalsettings' });
if (globalSettings.filters.length > 0) {
await db.collection('filters').insertOne({
board: null,
filters: globalSettings.filters,
filterMode: globalSettings.filterMode,
filterMessage: null,
filterBanDuration: globalSettings.filterBanDuration,
filterBanAppealable: globalSettings.filterBanAppealable ? true : false,
strictFiltering: globalSettings.strictFiltering ? true : false,
});
}
await db.collection('globalsettings').updateOne({ _id: 'globalsettings' }, {
'$unset': {
filters: '',
filterMode: '',
filterBanDuration: '',
filterBanAppealable: '',
strictFiltering: '',
'boardDefaults.filters': '',
'boardDefaults.filterMode': '',
'boardDefaults.filterBanDuration': '',
'boardDefaults.filterBanAppealable': '',
'boardDefaults.strictFiltering': '',
},
});
console.log('Updating boards to convert old filters into new filter db format');
const allBoards = await db.collection('boards').find({}).toArray();
for (let b of allBoards) {
if (b.settings.filters.length > 0) {
await db.collection('filters').insertOne({
board: b._id,
filters: b.settings.filters,
filterMode: b.settings.filterMode,
filterMessage: null,
filterBanDuration: b.settings.filterBanDuration,
filterBanAppealable: b.settings.filterBanAppealable ? true : false,
strictFiltering: b.settings.strictFiltering ? true : false,
});
}
}
await db.collection('boards').updateMany({}, {
'$unset': {
'settings.filters': '',
'settings.filterMode': '',
'settings.filterBanDuration': '',
'settings.filterBanAppealable': '',
'settings.strictFiltering': '',
},
});
console.log('Clearing globalsettings cache');
await redis.deletePattern('globalsettings');
console.log('Clearing boards cache');
await redis.deletePattern('board:*');
};

@ -1,12 +1,26 @@
'use strict';
const { Filters } = require(__dirname+'/../../db/')
, config = require(__dirname+'/../../lib/misc/config.js')
, dynamicResponse = require(__dirname+'/../../lib/misc/dynamic.js');
module.exports = async (req, res) => {
const { globalLimits } = config.get;
const { __ } = res.locals;
if (req.params.board) {
const filterCount = await Filters.count(req.params.board);
if (filterCount >= globalLimits.filters.max) {
return dynamicResponse(req, res, 400, 'message', {
'title': __('Bad request'),
'message': __('Total number of filters would exceed global limit of %s', globalLimits.filters.max),
'redirect': `/${req.params.board}/manage/filters.html`,
});
}
}
const filter = {
'board': req.params.board ? req.params.board : null,
'filters': req.body.filters.split(/\r?\n/).filter(n => n),

@ -265,7 +265,10 @@ module.exports = async (req, res) => {
customPages: {
max: numberSetting(req.body.global_limits_custom_pages_max, oldSettings.globalLimits.customPages.max),
maxLength: numberSetting(req.body.global_limits_custom_pages_max_length, oldSettings.globalLimits.customPages.maxLength),
}
},
filters: {
max: numberSetting(req.body.global_limits_filters_max, oldSettings.globalLimits.filters.max),
},
},
boardDefaults: {
language: trimSetting(req.body.board_defaults_language, oldSettings.boardDefaults.language),

@ -1,7 +1,7 @@
{
"name": "jschan",
"version": "1.1.1",
"migrateVersion": "1.0.5",
"version": "1.2.0",
"migrateVersion": "1.2.0",
"description": "",
"main": "server.js",
"dependencies": {

@ -279,6 +279,9 @@ block content
.row
.label #{__('Total Assets Per Board')}
input(type='number' name='global_limits_asset_files_total' value=settings.globalLimits.assetFiles.total)
.row
.label #{__('Max Filters Per Board')}
input(type='number' name='global_limits_filters_max' value=settings.globalLimits.filters.max)
.row
h4.mv-5 #{__('Field Length Limits')}
.row

Loading…
Cancel
Save