From f1abc3c224d1f8fc3680350d900610a8d6648925 Mon Sep 17 00:00:00 2001 From: Thomas Lynch Date: Fri, 3 Jul 2020 19:59:58 +1000 Subject: [PATCH] Start on selective spoilering references #170 filename stripping references #204 --- controllers/forms/actions.js | 2 +- gulp/res/js/forms.js | 34 ++++++++++++++-------------------- gulp/res/js/uploaditem.js | 19 +++++++++++++++++++ gulpfile.js | 1 + helpers/paramconverter.js | 2 +- models/forms/makepost.js | 18 ++++++++++-------- views/includes/footer.pug | 2 ++ views/includes/navbar.pug | 2 +- views/includes/postform.pug | 11 ++++++----- views/includes/uploaditem.pug | 2 ++ views/mixins/catalogtile.pug | 2 +- views/mixins/post.pug | 4 ++-- views/mixins/uploaditem.pug | 14 ++++++++++++++ views/pages/boardlist.pug | 3 +++ views/pages/overboard.pug | 2 +- views/pages/thread.pug | 2 +- 16 files changed, 79 insertions(+), 41 deletions(-) create mode 100644 gulp/res/js/uploaditem.js create mode 100644 views/includes/uploaditem.pug create mode 100644 views/mixins/uploaditem.pug diff --git a/controllers/forms/actions.js b/controllers/forms/actions.js index 38d8e8d7..9bec38d0 100644 --- a/controllers/forms/actions.js +++ b/controllers/forms/actions.js @@ -46,7 +46,7 @@ module.exports = async (req, res, next) => { if (req.body.delete && !res.locals.board.settings.userPostDelete) { errors.push('Post deletion is disabled on this board'); } - if (req.body.spoiler && !res.locals.board.settings.userPostSpoiler) { + if ((req.body.spoiler_all || req.body.spoiler) && !res.locals.board.settings.userPostSpoiler) { errors.push('File spoilers are disabled on this board'); } if (req.body.unlink_file && !res.locals.board.settings.userPostUnlink) { diff --git a/gulp/res/js/forms.js b/gulp/res/js/forms.js index 16a7e523..b047cf05 100644 --- a/gulp/res/js/forms.js +++ b/gulp/res/js/forms.js @@ -265,37 +265,31 @@ class formHandler { this.fileInput.removeAttribute('required'); } this.files.push(file); - //add to upload list - const listElem = document.createElement('div'); - listElem.classList.add('upload-item'); - const thumb = document.createElement('img'); - const name = document.createElement('p'); - const remove = document.createElement('a'); - name.textContent = file.name; - remove.textContent = 'X'; + const item = { + spoilers: this.fileUploadList.dataset.spoilers === 'true', + name: file.name + } switch (file.type.split('/')[0]) { case 'image': - thumb.src = URL.createObjectURL(file); + item.url = URL.createObjectURL(file); break; case 'audio': - thumb.src = '/file/audio.png' + item.url = '/file/audio.png' break; case 'video': - thumb.src = '/file/video.png' + item.url = '/file/video.png' break; default: - thumb.src = '/file/attachment.png' + item.url = '/file/attachment.png' break; } - thumb.classList.add('upload-thumb'); - remove.classList.add('close'); - listElem.appendChild(thumb); - listElem.appendChild(name); - listElem.appendChild(remove); - remove.addEventListener('click', () => { - this.removeFile(listElem, file.name, file.size); + const uploadItemHtml = uploaditem({ uploaditem: item }); + this.fileUploadList.insertAdjacentHTML('beforeend', uploadItemHtml); + const fileElem = this.fileUploadList.lastChild; + const lastClose = fileElem.querySelector('.close'); + lastClose.addEventListener('click', () => { + this.removeFile(fileElem, file.name, file.size); }) - this.fileUploadList.appendChild(listElem); this.fileUploadList.style.display = 'unset'; } diff --git a/gulp/res/js/uploaditem.js b/gulp/res/js/uploaditem.js new file mode 100644 index 00000000..a6b81e81 --- /dev/null +++ b/gulp/res/js/uploaditem.js @@ -0,0 +1,19 @@ +function pug_attr(t,e,n,r){if(!1===e||null==e||!e&&("class"===t||"style"===t))return"";if(!0===e)return" "+(r?t:t+'="'+t+'"');var f=typeof e;return"object"!==f&&"function"!==f||"function"!=typeof e.toJSON||(e=e.toJSON()),"string"==typeof e||(e=JSON.stringify(e),n||-1===e.indexOf('"'))?(n&&(e=pug_escape(e))," "+t+'="'+e+'"'):" "+t+"='"+e.replace(/'/g,"'")+"'"} +function pug_escape(e){var a=""+e,t=pug_match_html.exec(a);if(!t)return e;var r,c,n,s="";for(r=t.index,c=0;r]/;function uploaditem(locals) {var pug_html = "", pug_mixins = {}, pug_interp;; + var locals_for_with = (locals || {}); + + (function (uploaditem) { + pug_mixins["uploaditem"] = pug_interp = function(item){ +var block = (this && this.block), attributes = (this && this.attributes) || {}; +pug_html = pug_html + "\u003Cdiv\u003E\u003Cdiv class=\"upload-item\"\u003E\u003Cimg" + (" class=\"upload-thumb\""+pug_attr("src", item.url, true, false)) + "\u002F\u003E\u003Cp\u003E" + (pug_escape(null == (pug_interp = item.name) ? "" : pug_interp)) + "\u003C\u002Fp\u003E\u003Ca class=\"close\"\u003EX\u003C\u002Fa\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"row sb\"\u003E"; +if (item.spoilers) { +pug_html = pug_html + "\u003Clabel\u003E\u003Cinput" + (" type=\"checkbox\" name=\"spoiler\""+pug_attr("value", item.name, true, false)) + "\u002F\u003ESpoiler\u003C\u002Flabel\u003E"; +} +pug_html = pug_html + "\u003Clabel\u003E\u003Cinput" + (" type=\"checkbox\" name=\"strip_filename\""+pug_attr("value", item.name, true, false)) + "\u002F\u003EStrip Filename\u003C\u002Flabel\u003E\u003C\u002Fdiv\u003E\u003C\u002Fdiv\u003E"; +}; +pug_mixins["uploaditem"](uploaditem); + }.call(this, "uploaditem" in locals_for_with ? + locals_for_with.uploaditem : + typeof uploaditem !== 'undefined' ? uploaditem : undefined)); + ;;return pug_html;} \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 28506137..6e24cdf3 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -197,6 +197,7 @@ function scripts() { fs.writeFileSync('gulp/res/js/timezone.js', serverTimeZone); fs.writeFileSync('gulp/res/js/post.js', pug.compileFileClient(`${paths.pug.src}/includes/post.pug`, { compileDebug: false, debug: false, name: 'post' })); fs.writeFileSync('gulp/res/js/modal.js', pug.compileFileClient(`${paths.pug.src}/includes/modal.pug`, { compileDebug: false, debug: false, name: 'modal' })); + fs.writeFileSync('gulp/res/js/uploaditem.js', pug.compileFileClient(`${paths.pug.src}/includes/uploaditem.pug`, { compileDebug: false, debug: false, name: 'uploaditem' })); fs.symlinkSync(__dirname+'/node_modules/socket.io-client/dist/socket.io.slim.js', __dirname+'/gulp/res/js/socket.io.js', 'file'); } catch (e) { if (e.code !== 'EEXIST') { diff --git a/helpers/paramconverter.js b/helpers/paramconverter.js index 93d633fc..17e1cbad 100644 --- a/helpers/paramconverter.js +++ b/helpers/paramconverter.js @@ -1,7 +1,7 @@ 'use strict'; const { ObjectId } = require(__dirname+'/../db/db.js') - , allowedArrays = new Set(['checkednews', 'checkedposts', 'globalcheckedposts', + , allowedArrays = new Set(['checkednews', 'checkedposts', 'globalcheckedposts', 'spoiler', 'strip_filename', 'checkedreports', 'checkedbans', 'checkedbanners', 'checkedaccounts', 'countries']) //only these should be arrays, since express bodyparser can output arrays , trimFields = ['tags', 'uri', 'moderators', 'filters', 'announcement', 'description', 'message', 'name', 'subject', 'email', 'postpassword', 'password', 'default_name', 'report_reason', 'ban_reason', 'log_message', 'custom_css'] //trim if we dont want filed with whitespace diff --git a/models/forms/makepost.js b/models/forms/makepost.js index fba6e79b..59b432eb 100644 --- a/models/forms/makepost.js +++ b/models/forms/makepost.js @@ -29,6 +29,8 @@ const path = require('path') module.exports = async (req, res, next) => { +console.log(req.body) + //spam/flood check const flood = await spamCheck(req, res); if (flood) { @@ -178,12 +180,13 @@ module.exports = async (req, res, next) => { //get metadata let processedFile = { - hash: file.sha256, - filename: file.filename, //could probably remove since we have hash and extension - originalFilename: file.name, - mimetype: file.mimetype, - size: file.size, - extension, + spoiler: (res.locals.permLevel >= 4 || userPostSpoiler) && req.body.spoiler && req.body.spoiler.includes(file.name), + hash: file.sha256, + filename: file.filename, //could probably remove since we have hash and extension + originalFilename: req.body.strip_filename && req.body.strip_filename.includes(file.name) ? file.filename : file.name, + mimetype: file.mimetype, + size: file.size, + extension, }; //type and subtype @@ -321,9 +324,8 @@ module.exports = async (req, res, next) => { password = createHash('sha256').update(postPasswordSecret + req.body.postpassword).digest('base64'); } - //spoiler files only if board settings allow - const spoiler = userPostSpoiler && req.body.spoiler ? true : false; + const spoiler = (res.locals.permLevel >= 4 || userPostSpoiler) && req.body.spoiler_all ? true : false; //forceanon hide reply subjects so cant be used as name for replies //forceanon and sageonlyemail only allow sage email diff --git a/views/includes/footer.pug b/views/includes/footer.pug index 8a347d4c..7c99b659 100644 --- a/views/includes/footer.pug +++ b/views/includes/footer.pug @@ -1,6 +1,8 @@ unless minimal small.footer#bottom | - + a(href='/news.html') news + | - a(href='/rules.html') rules | - a(href='/faq.html') faq diff --git a/views/includes/navbar.pug b/views/includes/navbar.pug index 9c124e6e..33dc5884 100644 --- a/views/includes/navbar.pug +++ b/views/includes/navbar.pug @@ -1,7 +1,7 @@ unless minimal nav.navbar a.nav-item(href='/index.html') Home - a.nav-item(href='/news.html') News + //a.nav-item(href='/all.html') Overboard a.nav-item(href='/boards.html' style=(enableWebring ? 'line-height: 1.5em' : null)) | Boards if enableWebring diff --git a/views/includes/postform.pug b/views/includes/postform.pug index 759eefa2..390e6281 100644 --- a/views/includes/postform.pug +++ b/views/includes/postform.pug @@ -26,7 +26,7 @@ section.form-wrapper.flex-center .label Sage label.postform-style.ph-5 input(type='checkbox', name='email', value='sage') - else + else section.row .label Email input(type='text', name='email', autocomplete='off' maxlength=globalLimits.fieldLength.email) @@ -54,11 +54,12 @@ section.form-wrapper.flex-center span.col include ./filelabel.pug input#file(type='file', name='file' multiple required=fileRequired ) - .upload-list + .upload-list(data-spoilers=(board.settings.userPostSpoiler ? 'true' : 'false')) if board.settings.userPostSpoiler - label.postform-style.ph-5.ml-1.fh - input(type='checkbox', name='spoiler', value='true') - | Spoiler + noscript + label.postform-style.ph-5.ml-1.fh + input(type='checkbox', name='spoiler_all', value='true') + | Spoiler if board.settings.userPostSpoiler || board.settings.userPostDelete || board.settings.userPostUnlink || modview section.row .label Password diff --git a/views/includes/uploaditem.pug b/views/includes/uploaditem.pug new file mode 100644 index 00000000..03cebd7b --- /dev/null +++ b/views/includes/uploaditem.pug @@ -0,0 +1,2 @@ +include ../mixins/uploaditem.pug ++uploaditem(uploaditem) diff --git a/views/mixins/catalogtile.pug b/views/mixins/catalogtile.pug index 7c038453..5b1287c4 100644 --- a/views/mixins/catalogtile.pug +++ b/views/mixins/catalogtile.pug @@ -22,7 +22,7 @@ mixin catalogtile(board, post, index) .post-file-src a(href=postURL) - const file = post.files[0] - if post.spoiler + if post.spoiler || file.spoiler div.spoilerimg.catalog-thumb else if file.attachment div.attachmentimg.catalog-thumb diff --git a/views/mixins/post.pug b/views/mixins/post.pug index a8b7e732..b2f6cd9a 100644 --- a/views/mixins/post.pug +++ b/views/mixins/post.pug @@ -63,7 +63,7 @@ mixin post(post, truncate, manage=false, globalmanage=false, ban=false) each file in post.files .post-file span.post-file-info - span: a(href='/file/'+file.filename title='Download '+file.originalFilename download=file.originalFilename) #{post.spoiler ? 'Spoiler File' : file.originalFilename} + span: a(href='/file/'+file.filename title='Download '+file.originalFilename download=file.originalFilename) #{post.spoiler || file.spoiler ? 'Spoiler File' : file.originalFilename} br span | (#{file.sizeString} @@ -75,7 +75,7 @@ mixin post(post, truncate, manage=false, globalmanage=false, ban=false) - const type = file.mimetype.split('/')[0] .post-file-src(data-type=type data-attachment=(file.attachment ? "true" : "false")) a(target='_blank' href=`/file/${file.filename}`) - if post.spoiler + if post.spoiler || file.spoiler div.spoilerimg.file-thumb else if file.attachment div.attachmentimg.file-thumb diff --git a/views/mixins/uploaditem.pug b/views/mixins/uploaditem.pug new file mode 100644 index 00000000..2c298198 --- /dev/null +++ b/views/mixins/uploaditem.pug @@ -0,0 +1,14 @@ +mixin uploaditem(item) + div + .upload-item + img.upload-thumb(src=item.url) + p #{item.name} + a.close X + .row.sb + if item.spoilers + label + input(type='checkbox', name='spoiler', value=item.name) + | Spoiler + label + input(type='checkbox', name='strip_filename', value=item.name) + | Strip Filename diff --git a/views/pages/boardlist.pug b/views/pages/boardlist.pug index e80fff10..d105dd3c 100644 --- a/views/pages/boardlist.pug +++ b/views/pages/boardlist.pug @@ -5,6 +5,9 @@ block head block content h1.board-title Board List + h4.board-description + | or try the + a(href='/all.html') overboard .flexcenter.mv-10 form.form-post(action=`/boards.html` method='GET') input(type='hidden' value=page) diff --git a/views/pages/overboard.pug b/views/pages/overboard.pug index 1d1ec21b..dd76102e 100644 --- a/views/pages/overboard.pug +++ b/views/pages/overboard.pug @@ -7,7 +7,7 @@ block head block content .board-header h1.board-title Overboard - h4.board-description Recently bumped threads from all boards + h4.board-description Recently bumped threads from all listed boards hr(size=1) if threads.length === 0 p No posts. diff --git a/views/pages/thread.pug b/views/pages/thread.pug index 4125f250..268611d1 100644 --- a/views/pages/thread.pug +++ b/views/pages/thread.pug @@ -13,7 +13,7 @@ block head meta(property='og:url', content=meta.url) meta(property='og:description', content=thread.nomarkup) if thread.files.length > 0 - if thread.spoiler + if thread.spoiler || thread.files[0].spoiler meta(property='og:image', content='/file/spoiler.png') else - const file = thread.files[0];