From c4c2a1543ddd6d94b014c95222ebb62cb0325d44 Mon Sep 17 00:00:00 2001 From: Thomas Lynch Date: Fri, 12 Mar 2021 09:53:26 +0000 Subject: [PATCH] start on adding custom banners models and controllers arent done, things wont work yet. added a migration and updated the template.js with some new needed values, changed "banners" in manage to "assets" since it will hold both now refactor the banners file form into a mixin since its basically repeated for flags, and make it a tad more customisable --- configs/template.js.example | 4 ++++ controllers/forms.js | 22 ++++++++++-------- controllers/pages.js | 4 ++-- gulp/res/js/forms.js | 1 + gulp/res/js/hidefileinput.js | 7 +++--- gulp/res/js/uploaditem.js | 5 ++++- migrations/0.1.1.js | 18 +++++++++++++++ models/forms/create.js | 1 + models/pages/manage/assets.js | 11 +++++++++ package.json | 6 ++--- views/includes/filelabel.pug | 2 -- views/includes/postform.pug | 5 +++-- views/mixins/fileform.pug | 33 +++++++++++++++++++++++++++ views/mixins/filelabel.pug | 3 +++ views/mixins/managenav.pug | 2 +- views/mixins/uploaditem.pug | 7 +++--- views/pages/account.pug | 2 +- views/pages/manageassets.pug | 22 ++++++++++++++++++ views/pages/managebanners.pug | 42 ----------------------------------- 19 files changed, 127 insertions(+), 70 deletions(-) create mode 100644 migrations/0.1.1.js create mode 100644 models/pages/manage/assets.js delete mode 100644 views/includes/filelabel.pug create mode 100644 views/mixins/fileform.pug create mode 100644 views/mixins/filelabel.pug create mode 100644 views/pages/manageassets.pug delete mode 100644 views/pages/managebanners.pug diff --git a/configs/template.js.example b/configs/template.js.example index deebda02..ba502933 100644 --- a/configs/template.js.example +++ b/configs/template.js.example @@ -264,6 +264,10 @@ module.exports = { max: 10, //number of banners uploadable in one request total: 100, //max number of banners for a board }, + flagFiles: { + max: 10, //number of banners uploadable in one request + total: 100, //max number of flags for a board + }, bannerFilesSize: { //in bytes, 10MB default max: 10485760 }, diff --git a/controllers/forms.js b/controllers/forms.js index 5363ca69..6af1e0b6 100644 --- a/controllers/forms.js +++ b/controllers/forms.js @@ -35,6 +35,8 @@ const express = require('express') , deleteNewsController = require(__dirname+'/forms/deletenews.js') , uploadBannersController = require(__dirname+'/forms/uploadbanners.js') , deleteBannersController = require(__dirname+'/forms/deletebanners.js') + , addFlagsController = require(__dirname+'/forms/addflags.js') + , deleteFlagsController = require(__dirname+'/forms/deleteflags.js') , boardSettingsController = require(__dirname+'/forms/boardsettings.js') , transferController = require(__dirname+'/forms/transfer.js') , resignController = require(__dirname+'/forms/resign.js') @@ -67,14 +69,16 @@ router.post('/appeal', geoAndTor, torPreBypassCheck, processIp, useSession, sess router.post('/editpost', geoAndTor, torPreBypassCheck, processIp, useSession, sessionRefresh, csrf, paramConverter, Boards.bodyExists, calcPerms, hasPerms(3), editPostController); //board management forms -router.post('/board/:board/transfer', /*geoAndTor, torPreBypassCheck, processIp,*/ useSession, sessionRefresh, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(2), paramConverter, transferController); -router.post('/board/:board/settings', /*geoAndTor, torPreBypassCheck, processIp,*/ useSession, sessionRefresh, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(2), paramConverter, boardSettingsController); -router.post('/board/:board/addbanners', /*geoAndTor, torPreBypassCheck, processIp,*/ useSession, sessionRefresh, fileMiddlewares.handleBannerFiles, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(2), paramConverter, numFiles, uploadBannersController); //add banners -router.post('/board/:board/deletebanners', /*geoAndTor, torPreBypassCheck, processIp,*/ useSession, sessionRefresh, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(2), paramConverter, deleteBannersController); //delete banners -router.post('/board/:board/addcustompages', /*geoAndTor, torPreBypassCheck, processIp,*/ useSession, sessionRefresh, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(2), paramConverter, addCustomPageController); //add banners -router.post('/board/:board/deletecustompages', /*geoAndTor, torPreBypassCheck, processIp,*/ useSession, sessionRefresh, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(2), paramConverter, deleteCustomPageController); //delete banners -router.post('/board/:board/editbans', /*geoAndTor, torPreBypassCheck, processIp,*/ useSession, sessionRefresh, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(3), paramConverter, editBansController); //edit bans -router.post('/board/:board/deleteboard', /*geoAndTor, torPreBypassCheck, processIp,*/ useSession, sessionRefresh, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(config.get.deleteBoardPermLevel), deleteBoardController); //delete board +router.post('/board/:board/transfer', useSession, sessionRefresh, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(2), paramConverter, transferController); +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/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 +router.post('/board/:board/editbans', useSession, sessionRefresh, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(3), paramConverter, editBansController); //edit bans +router.post('/board/:board/deleteboard', useSession, sessionRefresh, csrf, Boards.exists, calcPerms, isLoggedIn, hasPerms(config.get.deleteBoardPermLevel), deleteBoardController); //delete board //global management forms router.post('/global/editbans', useSession, sessionRefresh, csrf, calcPerms, isLoggedIn, hasPerms(1), paramConverter, editBansController); //remove bans @@ -98,7 +102,7 @@ router.post('/deleteaccount', useSession, sessionRefresh, csrf, calcPerms, isLog //removes captcha cookie, for refreshing for noscript users router.post('/newcaptcha', newCaptcha); //solve captcha for block bypass -router.post('/blockbypass', geoAndTor, /*torPreBypassCheck,*/ processIp, verifyCaptcha, blockBypass); +router.post('/blockbypass', geoAndTor, processIp, verifyCaptcha, blockBypass); module.exports = router; diff --git a/controllers/pages.js b/controllers/pages.js index 69620a5a..00a3b5d0 100644 --- a/controllers/pages.js +++ b/controllers/pages.js @@ -16,7 +16,7 @@ const express = require('express') , csrf = require(__dirname+'/../helpers/checks/csrfmiddleware.js') , setMinimal = require(__dirname+'/../helpers/setminimal.js') //page models - , { manageRecent, manageReports, manageBanners, manageSettings, manageBans, + , { manageRecent, manageReports, manageAssets, manageSettings, manageBans, manageBoard, manageThread, manageLogs, manageCatalog, manageCustomPages } = require(__dirname+'/../models/pages/manage/') , { globalManageSettings, globalManageReports, globalManageBans, globalManageBoards, globalManageRecent, globalManageAccounts, globalManageNews, globalManageLogs } = require(__dirname+'/../models/pages/globalmanage/') @@ -52,7 +52,7 @@ router.get('/:board/manage/recent.(html|json)', useSession, sessionRefresh, isLo router.get('/:board/manage/bans.html', useSession, sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(3), csrf, manageBans); router.get('/:board/manage/logs.html', useSession, sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(3), csrf, manageLogs); router.get('/:board/manage/settings.html', useSession, sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(2), csrf, manageSettings); -router.get('/:board/manage/banners.html', useSession, sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(2), csrf, manageBanners); +router.get('/:board/manage/assets.html', useSession, sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(2), csrf, manageAssets); router.get('/:board/manage/custompages.html', useSession, sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(2), csrf, manageCustomPages); router.get('/:board/manage/catalog.html', useSession, sessionRefresh, isLoggedIn, Boards.exists, calcPerms, hasPerms(3), csrf, manageCatalog); router.get('/:board/manage/:page(1[0-9]{1,}|[2-9][0-9]{0,}|index).html', useSession, sessionRefresh, isLoggedIn, Boards.exists, paramConverter, calcPerms, hasPerms(3), csrf, manageBoard); diff --git a/gulp/res/js/forms.js b/gulp/res/js/forms.js index 4dd5b996..919822cb 100644 --- a/gulp/res/js/forms.js +++ b/gulp/res/js/forms.js @@ -324,6 +324,7 @@ class formHandler { } const item = { spoilers: this.fileUploadList.dataset.spoilers === 'true', + stripFilenames: this.fileUploadList.dataset.stripFilenames === 'true', name: file.name, hash: fileHash, } diff --git a/gulp/res/js/hidefileinput.js b/gulp/res/js/hidefileinput.js index 58822ffb..c37e75de 100644 --- a/gulp/res/js/hidefileinput.js +++ b/gulp/res/js/hidefileinput.js @@ -1,9 +1,8 @@ -const fileInput = document.getElementById('file'); -if (fileInput) { +document.querySelectorAll('input[type="file"]').forEach(fileInput => { //not using display: none because we still want to show the browser prompt for a "required" file fileInput.style.position = 'absolute'; fileInput.style.border = 'none'; fileInput.style.height = '1px'; fileInput.style.width = '1px'; -// fileInput.style.opacity = '0'; -} +// fileInput.style.opacity = '0'; // same effect as display:none in some browsers, ugh... +}); diff --git a/gulp/res/js/uploaditem.js b/gulp/res/js/uploaditem.js index 927e9924..aacd407e 100644 --- a/gulp/res/js/uploaditem.js +++ b/gulp/res/js/uploaditem.js @@ -12,7 +12,10 @@ pug_html = pug_html + "\u003Cdiv class=\"row sb\"\u003E"; if (item.spoilers) { pug_html = pug_html + "\u003Clabel\u003E\u003Cinput" + (" type=\"checkbox\" name=\"spoiler\""+pug_attr("value", item.hash, true, false)) + "\u002F\u003ESpoiler\u003C\u002Flabel\u003E"; } -pug_html = pug_html + "\u003Clabel\u003E\u003Cinput" + (" type=\"checkbox\" name=\"strip_filename\""+pug_attr("value", item.hash, true, false)) + "\u002F\u003EStrip Filename\u003C\u002Flabel\u003E\u003C\u002Fdiv\u003E"; +if (item.stripFilenames) { +pug_html = pug_html + "\u003Clabel\u003E\u003Cinput" + (" type=\"checkbox\" name=\"strip_filename\""+pug_attr("value", item.hash, true, false)) + "\u002F\u003EStrip Filename\u003C\u002Flabel\u003E"; +} +pug_html = pug_html + "\u003C\u002Fdiv\u003E"; } pug_html = pug_html + "\u003C\u002Fdiv\u003E"; }; diff --git a/migrations/0.1.1.js b/migrations/0.1.1.js new file mode 100644 index 00000000..9d064063 --- /dev/null +++ b/migrations/0.1.1.js @@ -0,0 +1,18 @@ +'use strict'; + +const fs = require('fs-extra'); + +module.exports = async(db, redis) => { + console.log('adding flags customisation db entries'); + const template = require(__dirname+'/../configs/template.js.example'); + await db.collection('globalsettings').updateOne({ _id: 'globalsettings' }, { + '$set': { + 'globalLimits.flagFiles': template.globalLimits.flagFiles, + } + }); + await db.collection('boards').updateMany({}, { + '$set': { + 'flags': [], + } + }); +}; diff --git a/models/forms/create.js b/models/forms/create.js index c088d26d..0763efbc 100644 --- a/models/forms/create.js +++ b/models/forms/create.js @@ -41,6 +41,7 @@ module.exports = async (req, res, next) => { '_id': uri, owner, 'banners': [], + 'flags': [], 'sequence_value': 1, 'pph': 0, 'ppd': 0, diff --git a/models/pages/manage/assets.js b/models/pages/manage/assets.js new file mode 100644 index 00000000..50ffad8c --- /dev/null +++ b/models/pages/manage/assets.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = async (req, res, next) => { + + res + .set('Cache-Control', 'private, max-age=5') + .render('manageassets', { + csrf: req.csrfToken(), + }); + +} diff --git a/package.json b/package.json index 83826cb3..fd90eb31 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,11 @@ { "name": "jschan", - "version": "0.1.0", - "migrateVersion": "0.1.0", + "version": "0.1.1", + "migrateVersion": "0.1.1", "description": "", "main": "server.js", "dependencies": { + "@fatchan/gulp-pug": "^4.0.1", "bcrypt": "^5.0.1", "bull": "^3.20.1", "cache-pug-templates": "^2.0.3", @@ -25,7 +26,6 @@ "gulp-clean-css": "^4.3.0", "gulp-concat": "^2.6.1", "gulp-less": "^4.0.1", - "@fatchan/gulp-pug": "^4.0.1", "gulp-replace": "^1.0.0", "gulp-uglify-es": "^2.0.0", "highlight.js": "^10.6.0", diff --git a/views/includes/filelabel.pug b/views/includes/filelabel.pug deleted file mode 100644 index 8a42aad9..00000000 --- a/views/includes/filelabel.pug +++ /dev/null @@ -1,2 +0,0 @@ -label.jsonly.postform-style.filelabel(for='file') - | Select/Drop/Paste file#{maxFiles > 1 ? 's' : ''} diff --git a/views/includes/postform.pug b/views/includes/postform.pug index 338a570d..84b420d5 100644 --- a/views/includes/postform.pug +++ b/views/includes/postform.pug @@ -1,3 +1,4 @@ +include ../mixins/filelabel.pug - const isThread = thread != null; - const subjectRequired = (!isThread && board.settings.forceThreadSubject); - const messageRequired = (!isThread && board.settings.forceThreadMessage) || (isThread && board.settings.forceReplyMessage); @@ -52,9 +53,9 @@ section.form-wrapper.flex-center small Max #{maxFiles} files small #{postFilesSize} total span.col - include ./filelabel.pug + +filelabel('file', maxFiles) input#file(type='file', name='file' multiple required=fileRequired ) - .upload-list(data-spoilers=(board.settings.userPostSpoiler ? 'true' : 'false')) + .upload-list(data-spoilers=(board.settings.userPostSpoiler ? 'true' : 'false') data-strip-filenames='false') if board.settings.userPostSpoiler noscript label.postform-style.ph-5.ml-1.fh diff --git a/views/mixins/fileform.pug b/views/mixins/fileform.pug new file mode 100644 index 00000000..1c600299 --- /dev/null +++ b/views/mixins/fileform.pug @@ -0,0 +1,33 @@ +include ./filelabel.pug + +mixin fileform(name, max, total, addpath, deletepath, checkname, fileList) + - 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 + form.form-post(action=addpath, enctype='multipart/form-data', method='POST') + input(type='hidden' name='_csrf' value=csrf) + .row + .label + span #{capitalName}#{max > 1 ? 's' : ''} + span.required * + if max > 1 + | + | + small (Max #{max}) + span.col + +filelabel(name, max) + input(id=name type='file', name='file' multiple required) + .upload-list(data-spoilers='false' data-strip-filenames='false') + input(type='submit', value='submit') + if fileList.length > 0 + hr(size=1) + h4.no-m-p Delete #{capitalName}s: + .form-wrapper.flexleft.mt-10 + 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 + label.banner-check + input(type='checkbox' name=checkname value=file) + img.board-banner(src=`${filepath}/${file}` loading='lazy') + input(type='submit', value='delete') diff --git a/views/mixins/filelabel.pug b/views/mixins/filelabel.pug new file mode 100644 index 00000000..d9878840 --- /dev/null +++ b/views/mixins/filelabel.pug @@ -0,0 +1,3 @@ +mixin filelabel(id, max) + label.jsonly.postform-style.filelabel(for=id) + | Select/Drop/Paste file#{max > 1 ? 's' : ''} diff --git a/views/mixins/managenav.pug b/views/mixins/managenav.pug index a3c5bfa3..031726fe 100644 --- a/views/mixins/managenav.pug +++ b/views/mixins/managenav.pug @@ -19,6 +19,6 @@ mixin managenav(selected, upLevel) if permLevel < 3 a(href=`${upLevel ? '../' : ''}settings.html` class=(selected === 'settings' ? 'bold' : '')) [Settings] | - a(href=`${upLevel ? '../' : ''}banners.html` class=(selected === 'banners' ? 'bold' : '')) [Banners] + a(href=`${upLevel ? '../' : ''}assets.html` class=(selected === 'assets' ? 'bold' : '')) [Assets] | a(href=`${upLevel ? '../' : ''}custompages.html` class=(selected === 'custompages' ? 'bold' : '')) [Custom Pages] diff --git a/views/mixins/uploaditem.pug b/views/mixins/uploaditem.pug index e20207f1..a6da14ec 100644 --- a/views/mixins/uploaditem.pug +++ b/views/mixins/uploaditem.pug @@ -10,6 +10,7 @@ mixin uploaditem(item) label input(type='checkbox', name='spoiler', value=item.hash) | Spoiler - label - input(type='checkbox', name='strip_filename', value=item.hash) - | Strip Filename + if item.stripFilenames + label + input(type='checkbox', name='strip_filename', value=item.hash) + | Strip Filename diff --git a/views/pages/account.pug b/views/pages/account.pug index e4232c78..00067d59 100644 --- a/views/pages/account.pug +++ b/views/pages/account.pug @@ -64,7 +64,7 @@ block content | , a(href=`/${b}/manage/settings.html`) Settings | , - a(href=`/${b}/manage/banners.html`) Banners + a(href=`/${b}/manage/assets.html`) Assets | , a(href=`/${b}/manage/custompages.html`) Custom Pages else diff --git a/views/pages/manageassets.pug b/views/pages/manageassets.pug new file mode 100644 index 00000000..e5d47d5c --- /dev/null +++ b/views/pages/manageassets.pug @@ -0,0 +1,22 @@ +extends ../layout.pug +include ../mixins/managenav.pug +include ../mixins/boardheader.pug +include ../mixins/fileform.pug + +block head + title /#{board._id}/ - Manage Assets + +block content + +boardheader('Assets') + br + +managenav('assets') + hr(size=1) + +fileform('banner', globalLimits.bannerFiles.max, globalLimits.bannerFiles.total, + `/forms/board/${board._id}/addbanners`, `/forms/board/${board._id}/deletebanners`, + 'checkedbanners', board.banners) + hr(size=1) + +fileform('flag', globalLimits.flagFiles.max, globalLimits.flagFiles.total, + `/forms/board/${board._id}/addflags`, `/forms/board/${board._id}/deleteflags`, + 'checkedflags', board.flags) + hr(size=1) + p todo: custom other files diff --git a/views/pages/managebanners.pug b/views/pages/managebanners.pug deleted file mode 100644 index 4aad33cd..00000000 --- a/views/pages/managebanners.pug +++ /dev/null @@ -1,42 +0,0 @@ -extends ../layout.pug -include ../mixins/managenav.pug -include ../mixins/boardheader.pug - -block head - title /#{board._id}/ - Manage Banners - -block content - +boardheader('Banners') - br - +managenav('banners') - hr(size=1) - h4.no-m-p Add Banners (Max #{globalLimits.bannerFiles.total}) - .form-wrapper.flexleft.mt-10 - form.form-post(action=`/forms/board/${board._id}/addbanners`, enctype='multipart/form-data', method='POST') - input(type='hidden' name='_csrf' value=csrf) - .row - - const maxFiles = globalLimits.bannerFiles.max; - .label - span Banner#{maxFiles > 1 ? 's' : ''} - span.required * - if maxFiles > 1 - | - | - small (Max #{maxFiles}) - span.col - include ../includes/filelabel.pug - input#file(type='file', name='file' multiple required) - .upload-list - input(type='submit', value='submit') - if board.banners.length > 0 - hr(size=1) - h4.no-m-p Delete Banners: - .form-wrapper.flexleft.mt-10 - form.form-post(action=`/forms/board/${board._id}/deletebanners`, enctype='application/x-www-form-urlencoded', method='POST') - input(type='hidden' name='_csrf' value=csrf) - .catalog - each banner in board.banners - label.banner-check - input(type='checkbox' name='checkedbanners' value=banner) - img.board-banner(src=`/banner/${board._id}/${banner}` loading='lazy') - input(type='submit', value='delete')