it works, with some kinks still to get through

indiachan-spamvector
Thomas Lynch 3 years ago
parent f5c834a5d6
commit 042445d28c
  1. 3
      configs/template.js.example
  2. 2
      controllers/forms.js
  3. 2
      controllers/forms/addflags.js
  4. 2
      controllers/forms/deleteflags.js
  5. 16
      db/boards.js
  6. 6
      gulp/res/css/style.css
  7. 13
      gulp/res/js/flag.js
  8. 11
      migrations/0.1.1.js
  9. 28
      models/forms/addflags.js
  10. 3
      models/forms/changeboardsettings.js
  11. 3
      models/forms/changeglobalsettings.js
  12. 9
      models/forms/deleteflags.js
  13. 15
      models/forms/makepost.js
  14. 10
      views/includes/postform.pug
  15. 6
      views/mixins/fileform.pug
  16. 8
      views/mixins/post.pug
  17. 6
      views/pages/globalmanagesettings.pug
  18. 4
      views/pages/manageassets.pug
  19. 6
      views/pages/managesettings.pug

@ -364,7 +364,8 @@ module.exports = {
sageOnlyEmail: false, //only allow sage email
early404: true, //delete threads beyond the first 1/3 of pages with less than 5 replies
ids: false, //show per thread poster ID based on ip
flags: false, //show geo flags, requires nginx setup
geoFlags: false, //show geo flags, requires nginx setup
customFlags: false, //show custom flags
userPostDelete: true, //allow users to delete their posts
userPostSpoiler: true, //allow user to spoiler their post files
userPostUnlink: true, //alow user to unlink files fomr their post

@ -73,7 +73,7 @@ router.post('/board/:board/transfer', useSession, sessionRefresh, csrf, Boards.e
router.post('/board/:board/settings', useSession, sessionRefresh, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(2), paramConverter, boardSettingsController);
router.post('/board/:board/addbanners', useSession, sessionRefresh, fileMiddlewares.handleBannerFiles, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(2), paramConverter, numFiles, uploadBannersController); //add banners
router.post('/board/:board/deletebanners', useSession, sessionRefresh, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(2), paramConverter, deleteBannersController); //delete banners
router.post('/board/:board/addflags', useSession, sessionRefresh, fileMiddlewares.handleBannerFiles, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(2), paramConverter, numFiles, addFlagsController); //add flags
router.post('/board/:board/addflags', useSession, sessionRefresh, fileMiddlewares.handleFlagFiles, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(2), paramConverter, numFiles, addFlagsController); //add flags
router.post('/board/:board/deleteflags', useSession, sessionRefresh, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(2), paramConverter, deleteFlagsController); //delete flags
router.post('/board/:board/addcustompages', useSession, sessionRefresh, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(2), paramConverter, addCustomPageController); //add banners
router.post('/board/:board/deletecustompages', useSession, sessionRefresh, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(2), paramConverter, deleteCustomPageController); //delete banners

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

@ -20,7 +20,7 @@ module.exports = async (req, res, next) => {
}
for (let i = 0; i < req.body.checkedflags.length; i++) {
if (!res.locals.board.flags.includes(req.body.checkedflags[i])) {
if (!res.locals.board.flags[req.body.checkedflags[i]]) {
return dynamicResponse(req, res, 400, 'message', {
'title': 'Bad request',
'message': 'Invalid flags selected',

@ -137,14 +137,16 @@ module.exports = {
return module.exports.addToArray(board, 'banners', filenames)
},
removeFlags: (board, filenames) => {
setFlags: (board, flags) => {
cache.del(`board:${board}`);
return module.exports.removeFromArray(board, 'flags', filenames);
},
addFlags: (board, filenames) => {
cache.del(`board:${board}`);
return module.exports.addToArray(board, 'flags', filenames)
//could use dot notation and set flags.x for only changes? seems a bit unsafe though and couldnt have . in name
return db.updateOne({
'_id': board,
}, {
'$set': {
'flags': flags,
}
});
},
getLocalListed: async () => {

@ -904,6 +904,12 @@ input:invalid, textarea:invalid {
height: 22px;
}
#selected-flag {
border: 1px solid var(--post-outline-color);
width: 32px;
height: 22px;
}
.board-description {
text-align:center;
margin: 0;

@ -0,0 +1,13 @@
window.addEventListener('DOMContentLoaded', function(e) {
const customFlagInput = document.getElementById('customflag');
const selectedFlagImage = document.getElementById('selected-flag');
if (customFlagInput && selectedFlagImage) {
const updateFlag = () => {
selectedFlagImage.src = customFlagInput.options[customFlagInput.options.selectedIndex].dataset.src || '';
};
customFlagInput.addEventListener('change', updateFlag, false);
updateFlag();
}
});

@ -1,6 +1,7 @@
'use strict';
const fs = require('fs-extra');
const fs = require('fs-extra')
, uploadDirectory = require(__dirname+'/../helpers/files/uploadDirectory.js');
module.exports = async(db, redis) => {
console.log('adding flags customisation');
@ -10,11 +11,19 @@ module.exports = async(db, redis) => {
'$set': {
'globalLimits.flagFiles': template.globalLimits.flagFiles,
'globalLimits.flagFilesSize': template.globalLimits.flagFilesSize,
'boardDefaults.customFlags': false,
},
'$rename': {
'boardDefaults.flags': 'boardDefaults.geoFlags',
}
});
await db.collection('boards').updateMany({}, {
'$set': {
'flags': [],
'settings.customFlags': false,
},
'$rename': {
'settings.flags': 'settings.geoFlags',
}
});
};

@ -50,27 +50,18 @@ module.exports = async (req, res, next) => {
}
}
const filenames = [];
const newFlags = {};
for (let i = 0; i < res.locals.numFiles; i++) {
const file = req.files.file[i];
let noExt = path.parse(file.name).name;
//match case for real country flags
if (noExt.length === 2 && countryCodesSet.has(noExt.toUpperCase())) {
file.name = file.name.toUpperCase();
}
//check if already exists
const exists = await res.locals.board.flags
.some(f => path.parse(f).name.toLowerCase() === noExt.toLowerCase());
if (exists) {
await remove(file.tempFilePath);
continue;
noExt = noExt.toUpperCase();
}
//add to list after checking it doesnt already exist
filenames.push(file.name);
newFlags[noExt] = file.name;
//then upload it
await moveUpload(file, file.name, `flag/${req.params.board}`);
@ -82,17 +73,10 @@ module.exports = async (req, res, next) => {
deleteTempFiles(req).catch(e => console.error);
// no new flags added, so they all must already existed
if (filenames.length === 0) {
return dynamicResponse(req, res, 400, 'message', {
'title': 'Bad request',
'message': `Flag${res.locals.numFiles > 1 ? 's' : ''} already exist${res.locals.numFiles > 1 ? '' : 's'}`,
'redirect': redirect
});
}
const updatedFlags = { ...res.locals.board.flags, ...newFlags };
// add flags in db
await Boards.addFlags(req.params.board, filenames);
await Boards.setFlags(req.params.board, updatedFlags);
/*
should we rebuild here if (overwriting country flag){}?
@ -100,7 +84,7 @@ module.exports = async (req, res, next) => {
return dynamicResponse(req, res, 200, 'message', {
'title': 'Success',
'message': `Uploaded ${filenames.length} new flags.`,
'message': `Uploaded ${res.locals.numFiles} new flags.`,
'redirect': redirect
});

@ -72,7 +72,8 @@ module.exports = async (req, res, next) => {
'unlistedWebring': booleanSetting(req.body.unlisted_webring),
'early404': booleanSetting(req.body.early404),
'ids': booleanSetting(req.body.ids),
'flags': booleanSetting(req.body.flags),
'geoFlags': booleanSetting(req.body.geo_flags),
'customFlags': booleanSetting(req.body.custom_flags),
'forceAnon': booleanSetting(req.body.force_anon),
'sageOnlyEmail': booleanSetting(req.body.sage_only_email),
'userPostDelete': booleanSetting(req.body.user_post_delete),

@ -243,7 +243,8 @@ module.exports = async (req, res, next) => {
sageOnlyEmail: booleanSetting(req.body.board_defaults_sage_only_email, oldSettings.boardDefaults.sageOnlyEmail),
early404: booleanSetting(req.body.board_defaults_early_404, oldSettings.boardDefaults.early404),
ids: booleanSetting(req.body.board_defaults_ids, oldSettings.boardDefaults.ids),
flags: booleanSetting(req.body.board_defaults_flags, oldSettings.boardDefaults.flags),
customFlags: booleanSetting(req.body.board_defaults_custom_flags, oldSettings.boardDefaults.customFlags),
geoFlags: booleanSetting(req.body.board_defaults_geo_flags, oldSettings.boardDefaults.geoFlags),
userPostDelete: booleanSetting(req.body.board_defaults_user_post_delete, oldSettings.boardDefaults.userPostDelete),
userPostSpoiler: booleanSetting(req.body.board_defaults_user_post_spoiler, oldSettings.boardDefaults.userPostSpoiler),
userPostUnlink: booleanSetting(req.body.board_defaults_user_post_unlink, oldSettings.boardDefaults.userPostUnlink),

@ -9,13 +9,16 @@ module.exports = async (req, res, next) => {
const redirect = `/${req.params.board}/manage/assets.html`;
const updatedFlags = res.locals.board.flags;
//delete file of all selected flags
await Promise.all(req.body.checkedflags.map(async filename => {
remove(`${uploadDirectory}/flag/${req.params.board}/${filename}`);
await Promise.all(req.body.checkedflags.map(async flagName => {
remove(`${uploadDirectory}/flag/${req.params.board}/${res.locals.board.flags[flagName]}`);
delete res.locals.board.flags[flagName];
}));
//remove from db
const amount = await Boards.removeFlags(req.params.board, req.body.checkedflags);
await Boards.setFlags(req.params.board, updatedFlags);
return dynamicResponse(req, res, 200, 'message', {
'title': 'Success',

@ -54,7 +54,7 @@ module.exports = async (req, res, next) => {
const { filterBanDuration, filterMode, filters, blockedCountries, threadLimit, ids, userPostSpoiler,
lockReset, captchaReset, pphTrigger, tphTrigger, tphTriggerAction, pphTriggerAction,
maxFiles, sageOnlyEmail, forceAnon, replyLimit, disableReplySubject,
captchaMode, lockMode, allowedFileTypes, flags, fileR9KMode, messageR9KMode } = res.locals.board.settings;
captchaMode, lockMode, allowedFileTypes, customFlags, geoFlags, fileR9KMode, messageR9KMode } = res.locals.board.settings;
if (res.locals.permLevel >= 4
&& res.locals.country
&& blockedCountries.includes(res.locals.country.code)) {
@ -393,9 +393,20 @@ ${res.locals.numFiles > 0 ? req.files.file.map(f => f.name+'|'+(f.phash || '')).
// }
}
let country = null;
if (flags === true) {
if (geoFlags === true) {
country = res.locals.country;
}
if (customFlags === true) {
if (req.body.customflag && res.locals.board.flags[req.body.customflag] != null) {
//if customflags allowed, and its a valid selection
country = {
name: req.body.customflag,
code: req.body.customflag,
src: res.locals.board.flags[req.body.customflag],
custom: true, //this will help
};
}
}
let password = null;
if (req.body.postpassword) {
password = createHash('sha256').update(postPasswordSecret + req.body.postpassword).digest('base64');

@ -65,6 +65,16 @@ section.form-wrapper.flex-center
section.row
.label Password
input(type='password', name='postpassword', placeholder='Password to delete/spoiler/unlink later' maxlength='50')
if modview || board.settings.customFlags === true
- const boardFlags = Object.entries(board.flags)
if boardFlags.length > 0
section.row
.label Flag
select#customflag(name='customflag')
option(value='') #{board.settings.geoFlags === true ? 'Country Flag' : ''}
each flag in boardFlags
option(value=flag[0] data-src=`/flag/${board._id}/${flag[1]}`) #{flag[0]}
img.jsonly#selected-flag
if ((board.settings.captchaMode === 1 && !isThread) || board.settings.captchaMode === 2) && !modview
if captchaType === 'text'
include ./captchasidelabel.pug

@ -1,6 +1,6 @@
include ./filelabel.pug
mixin fileform(name, max, total, addPath, deletePath, checkName, fileList, filePath, imageClass)
mixin fileform(name, max, total, addPath, deletePath, checkName, fileList, nameList, filePath, imageClass)
- const capitalName = `${name.charAt(0).toUpperCase()}${name.substring(1)}`;
h4.no-m-p Add #{capitalName}s (Max #{globalLimits.bannerFiles.total})
.form-wrapper.flexleft.mt-10
@ -26,9 +26,9 @@ mixin fileform(name, max, total, addPath, deletePath, checkName, fileList, fileP
form.form-post(action=deletePath, enctype='application/x-www-form-urlencoded', method='POST')
input(type='hidden' name='_csrf' value=csrf)
.catalog
each file in fileList
each file, index in fileList
label.banner-check
input(type='checkbox' name=checkName value=file)
input(type='checkbox' name=checkName value=nameList[index])
img(class=imageClass src=`${filePath}/${file}` loading='lazy')
small #{file.substring(0, file.lastIndexOf('.'))}
input(type='submit', value='delete')

@ -32,8 +32,12 @@ mixin post(post, truncate, manage=false, globalmanage=false, ban=false, overboar
span.post-name #{post.name}
|
if post.country && post.country.code
span(class=`flag flag-${post.country.code.toLowerCase()}` title=post.country.name alt=post.country.name)
|
if post.country.custom === true
img.flag(src=`/flag/${post.board}/${post.country.src}` title=post.country.name alt=post.country.name)
|
else
span(class=`flag flag-${post.country.code.toLowerCase()}` title=post.country.name alt=post.country.name)
|
if post.tripcode
span.post-tripcode #{post.tripcode}
|

@ -650,7 +650,11 @@ block content
.row
.label Geo Flags
label.postform-style.ph-5
input(type='checkbox', name='board_defaults_flags', value='true' checked=settings.boardDefaults.flags)
input(type='checkbox', name='board_defaults_geo_flags', value='true' checked=settings.boardDefaults.geoFlags)
.row
.label Custom Flags
label.postform-style.ph-5
input(type='checkbox', name='board_defaults_custom_flags', value='true' checked=settings.boardDefaults.customFlags)
.row
.label User Post Deletion
label.postform-style.ph-5

@ -13,10 +13,10 @@ block content
hr(size=1)
+fileform('banner', globalLimits.bannerFiles.max, globalLimits.bannerFiles.total,
`/forms/board/${board._id}/addbanners`, `/forms/board/${board._id}/deletebanners`,
'checkedbanners', board.banners, `/banners/${board._id}`, 'board-banner')
'checkedbanners', board.banners, board.banners, `/banners/${board._id}`, 'board-banner')
hr(size=1)
+fileform('flag', globalLimits.flagFiles.max, globalLimits.flagFiles.total,
`/forms/board/${board._id}/addflags`, `/forms/board/${board._id}/deleteflags`,
'checkedflags', board.flags, `/flag/${board._id}`, 'board-flag')
'checkedflags', Object.values(board.flags), Object.keys(board.flags), `/flag/${board._id}`, 'board-flag')
hr(size=1)
p todo: custom other files

@ -77,7 +77,11 @@ block content
.row
.label Geo Flags
label.postform-style.ph-5
input(type='checkbox', name='flags', value='true' checked=board.settings.flags)
input(type='checkbox', name='geo_flags', value='true' checked=board.settings.geoFlags)
.row
.label Custom Flags
label.postform-style.ph-5
input(type='checkbox', name='custom_flags', value='true' checked=board.settings.customFlags)
.row
.label SFW
label.postform-style.ph-5

Loading…
Cancel
Save