'use strict' ;
const changeBoardSettings = require ( _ _dirname + '/../../models/forms/changeboardsettings.js' )
, { themes , codeThemes } = require ( _ _dirname + '/../../helpers/themes.js' )
, { Ratelimits } = require ( _ _dirname + '/../../db/' )
, dynamicResponse = require ( _ _dirname + '/../../helpers/dynamic.js' )
, { globalLimits , rateLimitCost } = require ( _ _dirname + '/../../configs/main.js' ) ;
module . exports = async ( req , res , next ) => {
const errors = [ ] ;
//TODO: add helpers for different checks, passing name, min/max and return true with error if hit
if ( req . body . description && ( req . body . description . length < 1 || req . body . description . length > 50 ) ) {
errors . push ( 'Board description must be 1-50 characters' ) ;
}
if ( req . body . announcements && ( req . body . announcements . length < 1 || req . body . announcements . length > 2000 ) ) {
errors . push ( 'Board announcements must be 1-2000 characters' ) ;
}
if ( req . body . tags && req . body . tags . length > 2000 ) {
errors . push ( 'Tags length must be 2000 characters or less' ) ;
}
if ( req . body . filters && req . body . filters . length > 2000 ) {
errors . push ( 'Filters length must be 2000 characters or less' ) ;
}
if ( req . body . custom _css && globalLimits . customCss . enabled ) {
if ( res . locals . permLevel > 1 && globalLimits . customCss . strict && globalLimits . customCss . filters . some ( filter => req . body . custom _css . includes ( filter ) ) ) {
errors . push ( ` Custom CSS strict mode is enabled and does not allow the following: " ${ globalLimits . customCss . filters . join ( '", "' ) } " ` ) ;
}
if ( req . body . custom _css . length > globalLimits . customCss . max ) {
errors . push ( ` Custom CSS must be ${ globalLimits . customCss . max } characters or less ` ) ;
}
}
if ( req . body . moderators && req . body . moderators . length > 500 ) {
errors . push ( 'Moderators length must be 500 characters orless' ) ;
}
if ( req . body . name && ( req . body . name . length < 1 || req . body . name . length > 50 ) ) {
errors . push ( 'Board name must be 1-50 characters' ) ;
}
if ( req . body . default _name && ( req . body . default _name . length < 1 || req . body . default _name . length > 50 ) ) {
errors . push ( 'Anon name must be 1-50 characters' ) ;
}
if ( typeof req . body . reply _limit === 'number'
&& ( req . body . reply _limit < globalLimits . replyLimit . min
|| req . body . reply _limit > globalLimits . replyLimit . max ) ) {
errors . push ( ` Reply Limit must be ${ globalLimits . replyLimit . min } - ${ globalLimits . replyLimit . max } ` ) ;
}
if ( typeof req . body . bump _limit === 'number'
&& ( req . body . bump _limit < globalLimits . bumpLimit . min
|| req . body . bump _limit > globalLimits . bumpLimit . max ) ) {
errors . push ( ` Bump Limit must be ${ globalLimits . bumpLimit . min } - ${ globalLimits . bumpLimit . max } ` ) ;
}
if ( typeof req . body . thread _limit === 'number'
&& ( req . body . thread _limit < globalLimits . threadLimit . min
|| req . body . thread _limit > globalLimits . threadLimit . max ) ) {
errors . push ( ` Threads Limit must be ${ globalLimits . threadLimit . min } - ${ globalLimits . threadLimit . max } ` ) ;
}
if ( typeof req . body . max _files === 'number' && ( req . body . max _files < 0 || req . body . max _files > globalLimits . postFiles . max ) ) {
errors . push ( ` Max files must be 0- ${ globalLimits . postFiles . max } ` ) ;
}
//make sure new min/max message dont conflict
if ( typeof req . body . min _thread _message _length === 'number'
&& typeof req . body . max _thread _message _length === 'number'
&& req . body . min _thread _message _length
&& req . body . max _thread _message _length
&& req . body . min _thread _message _length > req . body . max _thread _message _length ) {
errors . push ( 'Min and max thread message lengths must not violate eachother' ) ;
}
if ( typeof req . body . min _reply _message _length === 'number'
&& typeof req . body . max _reply _message _length === 'number'
&& req . body . min _reply _message _length > req . body . max _reply _message _length ) {
errors . push ( 'Min and max reply message lengths must not violate eachother' ) ;
}
//make sure existing min/max message dont conflict
const minThread = Math . min ( globalLimits . fieldLength . message , res . locals . board . settings . maxThreadMessageLength ) || globalLimits . fieldLength . message ;
if ( typeof req . body . min _thread _message _length === 'number'
&& ( req . body . min _thread _message _length < 0
|| req . body . min _thread _message _length > minThread ) ) {
errors . push ( ` Min thread message length must be 0- ${ globalLimits . fieldLength . message } and not more than "Max Thread Message Length" (currently ${ res . locals . board . settings . maxThreadMessageLength } ) ` ) ;
}
const minReply = Math . min ( globalLimits . fieldLength . message , res . locals . board . settings . maxReplyMessageLength ) || globalLimits . fieldLength . message ;
if ( typeof req . body . min _reply _message _length === 'number'
&& ( req . body . min _reply _message _length < 0
|| req . body . min _reply _message _length > minReply ) ) {
errors . push ( ` Min reply message length must be 0- ${ globalLimits . fieldLength . message } and not more than "Max Reply Message Length" (currently ${ res . locals . board . settings . maxReplyMessageLength } ) ` ) ;
}
if ( typeof req . body . max _thread _message _length === 'number'
&& ( req . body . max _thread _message _length < 0
|| req . body . max _thread _message _length > globalLimits . fieldLength . message
|| ( req . body . max _thread _message _length
&& req . body . max _thread _message _length < res . locals . board . settings . minThreadMessageLength ) ) ) {
errors . push ( ` Max thread message length must be 0- ${ globalLimits . fieldLength . message } and not less than "Min Thread Message Length" (currently ${ res . locals . board . settings . minThreadMessageLength } ) ` ) ;
}
if ( typeof req . body . max _reply _message _length === 'number'
&& ( req . body . max _reply _message _length < 0
|| req . body . max _reply _message _length > globalLimits . fieldLength . message
|| ( req . body . max _reply _message _length
&& req . body . max _reply _message _length < res . locals . board . settings . minReplyMessageLength ) ) ) {
errors . push ( ` Max reply message length must be 0- ${ globalLimits . fieldLength . message } and not less than "Min Reply Message Length" (currently ${ res . locals . board . settings . minReplyMessageLength } ) ` ) ;
}
if ( typeof req . body . lock _mode === 'number' && ( req . body . lock _mode < 0 || req . body . lock _mode > 2 ) ) {
errors . push ( 'Invalid lock mode' ) ;
}
if ( typeof req . body . captcha _mode === 'number' && ( req . body . captcha _mode < 0 || req . body . captcha _mode > 2 ) ) {
errors . push ( 'Invalid captcha mode' ) ;
}
if ( typeof req . body . tph _trigger === 'number' && ( req . body . tph _trigger < 0 || req . body . tph _trigger > 10000 ) ) {
errors . push ( 'Invalid tph trigger threshold' ) ;
}
if ( typeof req . body . tph _trigger _action === 'number' && ( req . body . tph _trigger _action < 0 || req . body . tph _trigger _action > 4 ) ) {
errors . push ( 'Invalid tph trigger action' ) ;
}
if ( typeof req . body . filter _mode === 'number' && ( req . body . filter _mode < 0 || req . body . filter _mode > 2 ) ) {
errors . push ( 'Invalid filter mode' ) ;
}
if ( typeof req . body . ban _duration === 'number' && req . body . ban _duration <= 0 ) {
errors . push ( 'Invalid filter auto ban duration' ) ;
}
if ( req . body . theme && ! themes . includes ( req . body . theme ) ) {
errors . push ( 'Invalid theme' ) ;
}
if ( req . body . code _theme && ! codeThemes . includes ( req . body . code _theme ) ) {
errors . push ( 'Invalid code theme' ) ;
}
if ( errors . length > 0 ) {
return dynamicResponse ( req , res , 400 , 'message' , {
'title' : 'Bad request' ,
'errors' : errors ,
'redirect' : ` / ${ req . params . board } /manage/settings.html `
} ) ;
}
if ( res . locals . permLevel > 1 ) { //if not global staff or above
const ratelimitBoard = await Ratelimits . incrmentQuota ( req . params . board , 'settings' , rateLimitCost . boardSettings ) ; //2 changes a minute
// const ratelimitIp = await Ratelimits.incrmentQuota(res.locals.ip.single, 'settings', rateLimitCost.boardSettings);
if ( ratelimitBoard > 100 /* || ratelimitIp > 100 */ ) {
return dynamicResponse ( req , res , 429 , 'message' , {
'title' : 'Ratelimited' ,
'error' : 'You are changing settings too quickly, please wait a minute and try again' ,
'redirect' : ` / ${ req . params . board } /manage/settings.html `
} ) ;
}
}
try {
await changeBoardSettings ( req , res , next ) ;
} catch ( err ) {
return next ( err ) ;
}
}