mirror of https://gitgud.io/fatchan/jschan.git
parent
2649a1b6d3
commit
7ce421de3b
45 changed files with 867 additions and 157 deletions
@ -0,0 +1,43 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
const addFilter = require(__dirname+'/../../models/forms/addfilter.js') |
||||||
|
, dynamicResponse = require(__dirname+'/../../lib/misc/dynamic.js') |
||||||
|
, paramConverter = require(__dirname+'/../../lib/middleware/input/paramconverter.js') |
||||||
|
, { checkSchema, lengthBody, numberBody } = require(__dirname+'/../../lib/input/schema.js'); |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
|
||||||
|
paramConverter: paramConverter({ |
||||||
|
timeFields: ['filter_ban_duration'], |
||||||
|
trimFields: ['filters', 'filter_message'], |
||||||
|
numberFields: ['filter_mode'], |
||||||
|
objectIdFields: ['filter_id'], |
||||||
|
}), |
||||||
|
|
||||||
|
controller: async (req, res, next) => { |
||||||
|
|
||||||
|
const { __ } = res.locals; |
||||||
|
|
||||||
|
const errors = await checkSchema([ |
||||||
|
{ 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.filter_ban_duration), expected: true, error: __('Invalid filter auto ban duration') }, |
||||||
|
]); |
||||||
|
|
||||||
|
if (errors.length > 0) { |
||||||
|
return dynamicResponse(req, res, 400, 'message', { |
||||||
|
'title': __('Bad request'), |
||||||
|
'errors': req.params.board, |
||||||
|
'redirect': req.params.board ? `/${req.params.board}/manage/filters.html` : '/globalmanage/filters.html' |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
await addFilter(req, res, next); |
||||||
|
} catch (err) { |
||||||
|
return next(err); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}; |
@ -0,0 +1,39 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
const deleteFilter = require(__dirname+'/../../models/forms/deletefilter.js') |
||||||
|
, dynamicResponse = require(__dirname+'/../../lib/misc/dynamic.js') |
||||||
|
, paramConverter = require(__dirname+'/../../lib/middleware/input/paramconverter.js') |
||||||
|
, { checkSchema, lengthBody } = require(__dirname+'/../../lib/input/schema.js'); |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
|
||||||
|
paramConverter: paramConverter({ |
||||||
|
allowedArrays: ['checkedfilters'], |
||||||
|
objectIdArrays: ['checkedfilters'] |
||||||
|
}), |
||||||
|
|
||||||
|
controller: async (req, res, next) => { |
||||||
|
|
||||||
|
const { __ } = res.locals; |
||||||
|
|
||||||
|
const errors = await checkSchema([ |
||||||
|
{ result: lengthBody(req.body.checkedfilters, 1), expected: false, error: __('Must select at least one filter to delete') }, |
||||||
|
]); |
||||||
|
|
||||||
|
if (errors.length > 0) { |
||||||
|
return dynamicResponse(req, res, 400, 'message', { |
||||||
|
'title': __('Bad request'), |
||||||
|
'errors': errors, |
||||||
|
'redirect': req.params.board ? `/${req.params.board}/manage/filters.html` : '/globalmanage/filters.html' |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
await deleteFilter(req, res, next); |
||||||
|
} catch (err) { |
||||||
|
return next(err); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}; |
@ -0,0 +1,44 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
const editFilter = require(__dirname+'/../../models/forms/editfilter.js') |
||||||
|
, dynamicResponse = require(__dirname+'/../../lib/misc/dynamic.js') |
||||||
|
, paramConverter = require(__dirname+'/../../lib/middleware/input/paramconverter.js') |
||||||
|
, { checkSchema, lengthBody, numberBody, existsBody } = require(__dirname+'/../../lib/input/schema.js'); |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
|
||||||
|
paramConverter: paramConverter({ |
||||||
|
timeFields: ['filter_ban_duration'], |
||||||
|
trimFields: ['filters', 'filter_message'], |
||||||
|
numberFields: ['filter_mode'], |
||||||
|
objectIdFields: ['filter_id'], |
||||||
|
}), |
||||||
|
|
||||||
|
controller: async (req, res, next) => { |
||||||
|
|
||||||
|
const { __ } = res.locals; |
||||||
|
|
||||||
|
const errors = await checkSchema([ |
||||||
|
{ result: existsBody(req.body.filter_id), expected: true, error: __('Missing filter id') }, |
||||||
|
{ 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.filter_ban_duration), expected: true, error: __('Invalid filter auto ban duration') }, |
||||||
|
]); |
||||||
|
|
||||||
|
if (errors.length > 0) { |
||||||
|
return dynamicResponse(req, res, 400, 'message', { |
||||||
|
'title': __('Bad request'), |
||||||
|
'errors': errors, |
||||||
|
'redirect': req.headers.referer || (req.params.board ? `/${req.params.board}/manage/filters.html` : '/globalmanage/filters.html') |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
await editFilter(req, res, next); |
||||||
|
} catch (err) { |
||||||
|
return next(err); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}; |
@ -0,0 +1,64 @@ |
|||||||
|
|
||||||
|
'use strict'; |
||||||
|
|
||||||
|
const Mongo = require(__dirname+'/db.js') |
||||||
|
, db = Mongo.db.collection('filters'); |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
|
||||||
|
db, |
||||||
|
|
||||||
|
// null board retrieves global filters only
|
||||||
|
findForBoard: (board=null, limit=0) => { |
||||||
|
return db.find({'board': board}).sort({ |
||||||
|
'_id': -1 |
||||||
|
}) |
||||||
|
.limit(limit) |
||||||
|
.toArray(); |
||||||
|
}, |
||||||
|
|
||||||
|
findOne: (board, id) => { |
||||||
|
return db.findOne({ |
||||||
|
'_id': id, |
||||||
|
'board': board, |
||||||
|
}); |
||||||
|
}, |
||||||
|
|
||||||
|
updateOne: (board, id, filters, strictFiltering, filterMode, filterMessage, filterBanDuration, filterBanAppealable) => { |
||||||
|
return db.updateOne({ |
||||||
|
'_id': id, |
||||||
|
'board': board, |
||||||
|
}, { |
||||||
|
'$set': { |
||||||
|
'filters': filters, |
||||||
|
'strictFiltering': strictFiltering, |
||||||
|
'filterMode': filterMode, |
||||||
|
'filterMessage': filterMessage, |
||||||
|
'filterBanDuration': filterBanDuration, |
||||||
|
'filterBanAppealable': filterBanAppealable, |
||||||
|
} |
||||||
|
}); |
||||||
|
}, |
||||||
|
|
||||||
|
insertOne: (filters) => { |
||||||
|
return db.insertOne(filters); |
||||||
|
}, |
||||||
|
|
||||||
|
deleteMany: (board, ids) => { |
||||||
|
return db.deleteMany({ |
||||||
|
'_id': { |
||||||
|
'$in': ids |
||||||
|
}, |
||||||
|
'board': board |
||||||
|
}); |
||||||
|
}, |
||||||
|
|
||||||
|
deleteBoard: (board) => { |
||||||
|
return db.deleteMany({'board': board}); |
||||||
|
}, |
||||||
|
|
||||||
|
deleteAll: () => { |
||||||
|
return db.deleteMany({}); |
||||||
|
}, |
||||||
|
|
||||||
|
}; |
@ -0,0 +1,13 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
module.exports = (filters, combinedString, strictCombinedString) => { |
||||||
|
|
||||||
|
for (const filter of filters) { |
||||||
|
const string = filter.strictFiltering ? strictCombinedString : combinedString; |
||||||
|
const hitFilter = filter.filters.find(match => { return string.includes(match.toLowerCase()); }); |
||||||
|
if (hitFilter) { |
||||||
|
return [ hitFilter, filter.filterMode, filter.filterMessage, filter.filterBanDuration, filter.filterBanAppealable ]; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
}; |
@ -0,0 +1,28 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
const { Filters } = require(__dirname+'/../../db/') |
||||||
|
, dynamicResponse = require(__dirname+'/../../lib/misc/dynamic.js'); |
||||||
|
|
||||||
|
module.exports = async (req, res) => { |
||||||
|
|
||||||
|
const { __ } = res.locals; |
||||||
|
|
||||||
|
const filter = { |
||||||
|
'board': req.params.board ? req.params.board : null, |
||||||
|
'filters': req.body.filters.split(/\r?\n/).filter(n => n), |
||||||
|
'strictFiltering': req.body.strict_filtering ? true : false, |
||||||
|
'filterMode': req.body.filter_mode, |
||||||
|
'filterMessage': req.body.filter_message, |
||||||
|
'filterBanDuration': req.body.filter_ban_duration, |
||||||
|
'filterBanAppealable': req.body.filter_ban_appealable ? true : false, |
||||||
|
}; |
||||||
|
|
||||||
|
await Filters.insertOne(filter); |
||||||
|
|
||||||
|
return dynamicResponse(req, res, 200, 'message', { |
||||||
|
'title': __('Success'), |
||||||
|
'message': __('Added filter'), |
||||||
|
'redirect': req.params.board ? `/${req.params.board}/manage/filters.html` : '/globalmanage/filters.html' |
||||||
|
}); |
||||||
|
|
||||||
|
}; |
@ -0,0 +1,26 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
const { Filters } = require(__dirname+'/../../db/') |
||||||
|
, dynamicResponse = require(__dirname+'/../../lib/misc/dynamic.js'); |
||||||
|
|
||||||
|
module.exports = async (req, res) => { |
||||||
|
|
||||||
|
const { __, __n } = res.locals; |
||||||
|
|
||||||
|
const deletedFilters = await Filters.deleteMany(req.params.board, req.body.checkedfilters).then(result => result.deletedCount); |
||||||
|
|
||||||
|
if (deletedFilters === 0 || deletedFilters < req.body.checkedfilters.length) { |
||||||
|
return dynamicResponse(req, res, 400, 'message', { |
||||||
|
'title': __('Bad request'), |
||||||
|
'error': __n('Deleted %s filters', deletedFilters), |
||||||
|
'redirect': req.headers.referer || (req.params.board ? `/${req.params.board}/manage/filters.html` : '/globalmanage/filters.html') |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
return dynamicResponse(req, res, 200, 'message', { |
||||||
|
'title': __('Success'), |
||||||
|
'message': __n('Deleted %s filters', deletedFilters), |
||||||
|
'redirect': req.params.board ? `/${req.params.board}/manage/filters.html` : '/globalmanage/filters.html' |
||||||
|
}); |
||||||
|
|
||||||
|
}; |
@ -0,0 +1,35 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
const { Filters } = require(__dirname+'/../../db/') |
||||||
|
, dynamicResponse = require(__dirname+'/../../lib/misc/dynamic.js'); |
||||||
|
|
||||||
|
module.exports = async (req, res) => { |
||||||
|
|
||||||
|
const { __ } = res.locals; |
||||||
|
|
||||||
|
const updated = await Filters.updateOne( |
||||||
|
req.params.board, |
||||||
|
req.body.filter_id, |
||||||
|
req.body.filters.split(/\r?\n/).filter(n => n), |
||||||
|
req.body.strict_filtering ? true : false, |
||||||
|
req.body.filter_mode, |
||||||
|
req.body.filter_message, |
||||||
|
req.body.filter_ban_duration, |
||||||
|
req.body.filter_ban_appealable ? true : false |
||||||
|
).then(r => r.matchedCount); |
||||||
|
|
||||||
|
if (updated === 0) { |
||||||
|
return dynamicResponse(req, res, 400, 'message', { |
||||||
|
'title': __('Bad request'), |
||||||
|
'error': __('Filter does not exist'), |
||||||
|
'redirect': req.headers.referer || (req.params.board ? `/${req.params.board}/manage/filters.html` : '/globalmanage/filters.html') |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
return dynamicResponse(req, res, 200, 'message', { |
||||||
|
'title': __('Success'), |
||||||
|
'message': __('Updated filter'), |
||||||
|
'redirect': req.params.board ? `/${req.params.board}/manage/filters.html` : '/globalmanage/filters.html' |
||||||
|
}); |
||||||
|
|
||||||
|
}; |
@ -0,0 +1,26 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
const { Filters } = require(__dirname+'/../../../db/'); |
||||||
|
|
||||||
|
module.exports = async (req, res, next) => { |
||||||
|
|
||||||
|
let filter; |
||||||
|
try { |
||||||
|
filter = await Filters.findOne(null, req.params.filterid); |
||||||
|
} catch (err) { |
||||||
|
return next(err); |
||||||
|
} |
||||||
|
|
||||||
|
if (!filter) { |
||||||
|
return next(); |
||||||
|
} |
||||||
|
|
||||||
|
res |
||||||
|
.set('Cache-Control', 'private, max-age=5') |
||||||
|
.render('globaleditfilter', { |
||||||
|
csrf: req.csrfToken(), |
||||||
|
permissions: res.locals.permissions, |
||||||
|
filter, |
||||||
|
}); |
||||||
|
|
||||||
|
}; |
@ -0,0 +1,22 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
const { Filters } = require(__dirname+'/../../../db/'); |
||||||
|
|
||||||
|
module.exports = async (req, res, next) => { |
||||||
|
|
||||||
|
let filters; |
||||||
|
try { |
||||||
|
filters = await Filters.findForBoard(null); |
||||||
|
} catch (err) { |
||||||
|
return next(err); |
||||||
|
} |
||||||
|
|
||||||
|
res |
||||||
|
.set('Cache-Control', 'private, max-age=5') |
||||||
|
.render('globalmanagefilters', { |
||||||
|
csrf: req.csrfToken(), |
||||||
|
permissions: res.locals.permissions, |
||||||
|
filters, |
||||||
|
}); |
||||||
|
|
||||||
|
}; |
@ -0,0 +1,26 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
const { Filters } = require(__dirname+'/../../../db/'); |
||||||
|
|
||||||
|
module.exports = async (req, res, next) => { |
||||||
|
|
||||||
|
let filter; |
||||||
|
try { |
||||||
|
filter = await Filters.findOne(req.params.board, req.params.filterid); |
||||||
|
} catch (err) { |
||||||
|
return next(err); |
||||||
|
} |
||||||
|
|
||||||
|
if (!filter) { |
||||||
|
return next(); |
||||||
|
} |
||||||
|
|
||||||
|
res |
||||||
|
.set('Cache-Control', 'private, max-age=5') |
||||||
|
.render('editfilter', { |
||||||
|
csrf: req.csrfToken(), |
||||||
|
permissions: res.locals.permissions, |
||||||
|
filter, |
||||||
|
}); |
||||||
|
|
||||||
|
}; |
@ -0,0 +1,22 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
const { Filters } = require(__dirname+'/../../../db/'); |
||||||
|
|
||||||
|
module.exports = async (req, res, next) => { |
||||||
|
|
||||||
|
let filters; |
||||||
|
try { |
||||||
|
filters = await Filters.findForBoard(req.params.board); |
||||||
|
} catch (err) { |
||||||
|
return next(err); |
||||||
|
} |
||||||
|
|
||||||
|
res |
||||||
|
.set('Cache-Control', 'private, max-age=5') |
||||||
|
.render('managefilters', { |
||||||
|
csrf: req.csrfToken(), |
||||||
|
permissions: res.locals.permissions, |
||||||
|
filters, |
||||||
|
}); |
||||||
|
|
||||||
|
}; |
@ -0,0 +1,28 @@ |
|||||||
|
input(type='hidden' name='_csrf' value=csrf) |
||||||
|
input(type='hidden' name='filter_id' value=filter._id) |
||||||
|
.table-container.flex-center.mv-5 |
||||||
|
table |
||||||
|
tr |
||||||
|
th #{__('Filters')} |
||||||
|
th #{__('Strict Filtering')} |
||||||
|
th #{__('Filter Mode')} |
||||||
|
th #{__('Block/Ban Message')} |
||||||
|
th #{__('Filter Auto Ban Duration')} |
||||||
|
th #{__('Filter Bans Appealable')} |
||||||
|
tr |
||||||
|
td |
||||||
|
textarea(name='filters' rows='2' placeholder=__('Newline separated') required) #{filter.filters.join('\n')} |
||||||
|
td.text-center |
||||||
|
input(type='checkbox', name='strict_filtering', value='true', checked=filter.strictFiltering) |
||||||
|
td |
||||||
|
select(name='filter_mode') |
||||||
|
option(value='0', selected=filter.filterMode === 0) #{__('Do nothing')} |
||||||
|
option(value='1', selected=filter.filterMode === 1) #{__('Block post')} |
||||||
|
option(value='2', selected=filter.filterMode === 2) #{__('Ban')} |
||||||
|
td |
||||||
|
input(type='text' name='filter_message' placeholder=__('e.g. Rule 1: No ad spam') value=filter.filterMessage) |
||||||
|
td |
||||||
|
input(type='text' name='filter_ban_duration' placeholder=__('e.g. 3d') value=filter.filterBanDuration) |
||||||
|
td.text-center |
||||||
|
input(type='checkbox', name='filter_ban_appealable', value='true', checked=filter.filterBanAppealable) |
||||||
|
input(type='submit', value=__('Save')) |
@ -0,0 +1,29 @@ |
|||||||
|
input(type='hidden' name='_csrf' value=csrf) |
||||||
|
.table-container.flex-center.mv-5 |
||||||
|
table |
||||||
|
tr |
||||||
|
th #{__('Filters')} |
||||||
|
th #{__('Strict Filtering')} |
||||||
|
th #{__('Filter Mode')} |
||||||
|
th #{__('Block/Ban Message')} |
||||||
|
th #{__('Filter Auto Ban Duration')} |
||||||
|
th #{__('Filter Bans Appealable')} |
||||||
|
tr |
||||||
|
td |
||||||
|
textarea(name='filters' rows='2' placeholder=__('Newline separated') required) |
||||||
|
td.text-center |
||||||
|
label |
||||||
|
input(type='checkbox', name='strict_filtering', value='true') |
||||||
|
td |
||||||
|
select(name='filter_mode') |
||||||
|
option(value='0', selected=true) #{__('Do nothing')} |
||||||
|
option(value='1') #{__('Block post')} |
||||||
|
option(value='2') #{__('Ban')} |
||||||
|
td |
||||||
|
input(type='text' name='filter_message' placeholder=__('e.g. Rule 1: No ad spam')) |
||||||
|
td |
||||||
|
input(type='text' name='filter_ban_duration' placeholder=__('e.g. 3d')) |
||||||
|
td.text-center |
||||||
|
label |
||||||
|
input(type='checkbox', name='filter_ban_appealable', value='true') |
||||||
|
input(type='submit', value=__('Submit')) |
@ -0,0 +1,32 @@ |
|||||||
|
mixin filter(f, globalmanage=false) |
||||||
|
.anchor(id=f._id) |
||||||
|
tr |
||||||
|
td |
||||||
|
input.left.post-check(type='checkbox', name='checkedfilters' value=f._id) |
||||||
|
td |
||||||
|
each line in f.filters |
||||||
|
pre.no-m-p.nowrap !{line} |
||||||
|
td.text-center |
||||||
|
label |
||||||
|
input(type='checkbox', name='strict_filtering', value='true', checked=f.strictFiltering, disabled='true') |
||||||
|
td |
||||||
|
if f.filterMode === 0 |
||||||
|
p.no-m-p.nowrap #{__('Do nothing')} |
||||||
|
else if f.filterMode === 1 |
||||||
|
p.no-m-p.nowrap #{__('Block post')} |
||||||
|
else if f.filterMode === 2 |
||||||
|
p.no-m-p.nowrap #{__('Ban')} |
||||||
|
else |
||||||
|
p.no-m-p.nowrap ? |
||||||
|
td |
||||||
|
p.no-m-p !{f.filterMessage} |
||||||
|
td |
||||||
|
p.no-m-p(style='text-align:right;') !{f.filterBanDuration} |
||||||
|
td.text-center |
||||||
|
label |
||||||
|
input(type='checkbox', name='filter_ban_appealable', value='true', checked=f.filterBanAppealable, disabled='true') |
||||||
|
td |
||||||
|
if globalmanage |
||||||
|
a.ml-5(href=`/globalmanage/editfilter/${f._id}.html`, style='overflow-wrap: break-word;') [#{__('Edit')}] |
||||||
|
else |
||||||
|
a.ml-5(href=`/${board._id}/manage/editfilter/${f._id}.html`, style='overflow-wrap: break-word;') [#{__('Edit')}] |
@ -0,0 +1,18 @@ |
|||||||
|
extends ../layout.pug |
||||||
|
include ../mixins/managenav.pug |
||||||
|
include ../mixins/boardheader.pug |
||||||
|
|
||||||
|
block head |
||||||
|
title /#{board._id}/ - #{__('Edit Filter')} |
||||||
|
|
||||||
|
block content |
||||||
|
+boardheader(__('Edit Filter')) |
||||||
|
br |
||||||
|
+managenav('filters') |
||||||
|
hr(size=1) |
||||||
|
h4.mv-5 |
||||||
|
a(href='/faq.html#filters') #{__('Filters FAQ')}: |
||||||
|
h4.mv-5 #{__('Edit Filter')}: |
||||||
|
.form-wrapper.flex-center.mv-10 |
||||||
|
form.form-post(action=`/forms/board/${board._id}/editfilter` method='POST') |
||||||
|
include ../includes/filtereditform.pug |
@ -0,0 +1,18 @@ |
|||||||
|
extends ../layout.pug |
||||||
|
include ../mixins/globalmanagenav.pug |
||||||
|
|
||||||
|
block head |
||||||
|
title #{__('Edit Filter')} |
||||||
|
|
||||||
|
block content |
||||||
|
h1.board-title #{__('Global Management')} |
||||||
|
br |
||||||
|
+globalmanagenav('filters', true) |
||||||
|
hr(size=1) |
||||||
|
h4.mv-5 |
||||||
|
a(href='/faq.html#filters') #{__('Filters FAQ')}: |
||||||
|
h4.no-m-p #{__('Edit Filter')}: |
||||||
|
include ../includes/stickynav.pug |
||||||
|
.form-wrapper.flex-center.mv-10 |
||||||
|
form.form-post(action='/forms/global/editfilter' method='POST') |
||||||
|
include ../includes/filtereditform.pug |
@ -0,0 +1,37 @@ |
|||||||
|
extends ../layout.pug |
||||||
|
include ../mixins/filter.pug |
||||||
|
include ../mixins/globalmanagenav.pug |
||||||
|
|
||||||
|
block head |
||||||
|
title #{__('Filters')} |
||||||
|
|
||||||
|
block content |
||||||
|
h1.board-title #{__('Global Management')} |
||||||
|
br |
||||||
|
+globalmanagenav('filters') |
||||||
|
hr(size=1) |
||||||
|
h4.mv-5 |
||||||
|
a(href='/faq.html#filters') #{__('Filters FAQ')}: |
||||||
|
h4.no-m-p #{__('Add Filter')}: |
||||||
|
.form-wrapper.flexleft |
||||||
|
form.form-post(action='/forms/global/addfilter', enctype='application/x-www-form-urlencoded', method='POST') |
||||||
|
include ../includes/filternewform.pug |
||||||
|
if filters.length > 0 |
||||||
|
hr(size=1) |
||||||
|
h4.no-m-p #{__('Manage Filters')}: |
||||||
|
.form-wrapper.flexleft |
||||||
|
form.form-post(action='/forms/global/deletefilter', enctype='application/x-www-form-urlencoded', method='POST') |
||||||
|
input(type='hidden' name='_csrf' value=csrf) |
||||||
|
table |
||||||
|
tr |
||||||
|
th |
||||||
|
th #{__('Filters')} |
||||||
|
th #{__('Strict Filtering')} |
||||||
|
th #{__('Filter Mode')} |
||||||
|
th #{__('Block/Ban Message')} |
||||||
|
th #{__('Filter Auto Ban Duration')} |
||||||
|
th #{__('Filter Bans Appealable')} |
||||||
|
th #{__('Edit')} |
||||||
|
each f in filters |
||||||
|
+filter(f, true) |
||||||
|
input(type='submit', value=__('Delete')) |
@ -0,0 +1,38 @@ |
|||||||
|
extends ../layout.pug |
||||||
|
include ../mixins/filter.pug |
||||||
|
include ../mixins/managenav.pug |
||||||
|
include ../mixins/boardheader.pug |
||||||
|
|
||||||
|
block head |
||||||
|
title /#{board._id}/ - #{__('Filters')} |
||||||
|
|
||||||
|
block content |
||||||
|
+boardheader(__('Filters')) |
||||||
|
br |
||||||
|
+managenav('filters') |
||||||
|
hr(size=1) |
||||||
|
h4.mv-5 |
||||||
|
a(href='/faq.html#filters') #{__('Filters FAQ')}: |
||||||
|
h4.mv-5 #{__('Add Filter')}: |
||||||
|
.form-wrapper.flexleft |
||||||
|
form.form-post(action=`/forms/board/${board._id}/addfilter`, enctype='application/x-www-form-urlencoded', method='POST') |
||||||
|
include ../includes/filternewform.pug |
||||||
|
if filters.length > 0 |
||||||
|
hr(size=1) |
||||||
|
h4.no-m-p #{__('Manage Filters')}: |
||||||
|
.form-wrapper.flexleft |
||||||
|
form.form-post(action=`/forms/board/${board._id}/deletefilter`, enctype='application/x-www-form-urlencoded', method='POST') |
||||||
|
input(type='hidden' name='_csrf' value=csrf) |
||||||
|
table |
||||||
|
tr |
||||||
|
th |
||||||
|
th #{__('Filters')} |
||||||
|
th #{__('Strict Filtering')} |
||||||
|
th #{__('Filter Mode')} |
||||||
|
th #{__('Block/Ban Message')} |
||||||
|
th #{__('Filter Auto Ban Duration')} |
||||||
|
th #{__('Filter Bans Appealable')} |
||||||
|
th #{__('Edit')} |
||||||
|
each f in filters |
||||||
|
+filter(f) |
||||||
|
input(type='submit', value=__('Delete')) |
Loading…
Reference in new issue