modal shows bans, and are appealable from the modal

bugfix already appealed bans showing as "appealable"
minor ban form/ban mixin tweaks
no more sketchy way of "clearing" the form and resubmitting to show bans page. nice!
indiachan-spamvector
Thomas Lynch 2 years ago
parent 2391e3293c
commit 7805054635
  1. 2
      gulp/res/js/captcha.js
  2. 59
      gulp/res/js/forms.js
  3. 10
      lib/middleware/permission/bancheck.js
  4. 3
      models/forms/editpost.js
  5. 3
      models/forms/makepost.js
  6. 2
      views/includes/banform.pug
  7. 2
      views/mixins/ban.pug
  8. 6
      views/mixins/modal.pug

@ -29,7 +29,7 @@ class CaptchaController {
clearTimeout(this.refreshTimer); //this wont throw an error if its null, so no need to check clearTimeout(this.refreshTimer); //this wont throw an error if its null, so no need to check
const captchaAge = this.captchaAge(); const captchaAge = this.captchaAge();
if (captchaAge != null) { if (captchaAge != null) {
console.log('Refreshing captcha in ', 300000-captchaAge) console.log('Refreshing captcha in ', 300000-captchaAge);
this.refreshTimer = setTimeout(() => { this.refreshTimer = setTimeout(() => {
this.refreshCaptchas(); this.refreshCaptchas();
}, 300000-captchaAge); }, 300000-captchaAge);

@ -31,11 +31,22 @@ async function videoThumbnail(file) {
}); });
} }
function doModal(data, postcallback) { function doModal(data, postcallback, loadcallback) {
try { try {
const modalHtml = modal({ modal: data }); const modalHtml = modal({ modal: data });
let checkInterval; let checkInterval;
document.body.insertAdjacentHTML('afterbegin', modalHtml); document.body.insertAdjacentHTML('afterbegin', modalHtml);
const modals = document.getElementsByClassName('modal');
const modalBgs = document.getElementsByClassName('modal-bg');
if (modals.length > 1) {
const latestModalIndex = parseInt(document.defaultView.getComputedStyle(modals[1], null).getPropertyValue('z-index'));
//from appeals, or holding enter. make sure they show up above the previous modal
modals[0].style.zIndex = latestModalIndex + 3;
modalBgs[0].style.zIndex = latestModalIndex + 2;
}
if (loadcallback != null) {
loadcallback();
}
document.getElementById('modalclose').onclick = () => { document.getElementById('modalclose').onclick = () => {
removeModal(); removeModal();
clearInterval(checkInterval); clearInterval(checkInterval);
@ -46,9 +57,9 @@ function doModal(data, postcallback) {
}; };
const modalframe = document.getElementById('modalframe'); const modalframe = document.getElementById('modalframe');
if (modalframe) { if (modalframe) {
//if theres a modal frame and user has default theme, style it
if (localStorage.getItem('theme') === 'default') { if (localStorage.getItem('theme') === 'default') {
modalframe.onload = () => { modalframe.onload = () => {
//if theres a modal frame and user has default theme, style it
const currentTheme = document.head.querySelector('#theme').href; const currentTheme = document.head.querySelector('#theme').href;
modalframe.contentDocument.styleSheets[1].ownerNode.href = currentTheme; modalframe.contentDocument.styleSheets[1].ownerNode.href = currentTheme;
} }
@ -64,7 +75,7 @@ function doModal(data, postcallback) {
} }
} }
} catch(e) { } catch(e) {
console.error(e) console.error(e);
} }
} }
@ -202,8 +213,7 @@ class postFormHandler {
postData.set('captcha', captchaResponse); postData.set('captcha', captchaResponse);
} }
} }
if (this.banned if (this.minimal
|| this.minimal
|| (postData instanceof URLSearchParams && postData.get('edit') === '1')) { || (postData instanceof URLSearchParams && postData.get('edit') === '1')) {
return true; return true;
} else { } else {
@ -251,9 +261,7 @@ class postFormHandler {
if (xhr.responseURL if (xhr.responseURL
&& xhr.responseURL !== `${location.origin}${this.form.getAttribute('action')}`) { && xhr.responseURL !== `${location.origin}${this.form.getAttribute('action')}`) {
window.location = xhr.responseURL; window.location = xhr.responseURL;
return; return; //edits
} else if (xhr.responseText) {
//
} }
} else { } else {
if (json.postId) { if (json.postId) {
@ -278,11 +286,7 @@ class postFormHandler {
forceUpdate(); forceUpdate();
} }
} }
//dont reset on edit, keep the new values in there. todo: add exceptions/better handling for this situation
const formAction = this.form.getAttribute('action');
if (this.resetOnSubmit) { if (this.resetOnSubmit) {
//formAction !== '/forms/editpost'
//!formAction.endsWith('/settings')) {
this.reset(); this.reset();
} }
} else { } else {
@ -301,15 +305,32 @@ class postFormHandler {
if (captcha) { if (captcha) {
captcha.dispatchEvent(new Event('click')); captcha.dispatchEvent(new Event('click'));
} }
} else if (json.bans) {
doModal(json, null, () => {
const modalBanned = document.getElementById('modalbanned');
const modalBanForm = modalBanned.querySelector('form');
const modalAppealHandler = new postFormHandler(modalBanForm);
for (let modalFormElement of modalAppealHandler.form.elements) {
//for ease of appeal, pre-check all the bans in this case.
if (modalFormElement.type === 'checkbox') {
modalFormElement.checked = true;
}
}
const appealCaptcha = modalAppealHandler.captchaField;
if (appealCaptcha) {
captchaController.setupCaptchaField(appealCaptcha);
}
});
} else {
doModal(json, () => {
this.formSubmit(e);
});
} }
doModal(json, () => {
this.formSubmit(e);
});
} else { } else {
//for bans, post form to show TODO: make modal support bans json and send dynamicresponse from it (but what about appeals, w/ captcha, etc?) doModal({
this.clearFiles(); //dont resubmit files 'title': 'Error',
this.banned = true; 'message': 'Something broke'
this.form.dispatchEvent(new Event('submit')); });
} }
} }
this.submit.value = this.originalSubmitText; this.submit.value = this.originalSubmitText;

@ -22,10 +22,12 @@ module.exports = async (req, res, next) => {
if (bans && bans.length > 0) { if (bans && bans.length > 0) {
const unseenBans = bans.filter(b => !b.seen).map(b => b._id); const unseenBans = bans.filter(b => !b.seen).map(b => b._id);
await Bans.markSeen(unseenBans); //mark bans as seen await Bans.markSeen(unseenBans); //mark bans as seen
bans.forEach(ban => ban.seen = true); //mark seen as true in memory for user viewed ban page bans.forEach(ban => {
//todo: make a dynamicresponse, handle in frontend modal. ban.ip.raw = null;
return res.status(403).render('ban', { ban.seen = true
bans: bans, }); //mark seen as true in memory for user viewed ban page
return dynamicResponse(req, res, 403, 'ban', {
bans,
}); });
} }

@ -69,7 +69,8 @@ todo: handle some more situations
}; };
const insertedResult = await Bans.insertOne(ban); const insertedResult = await Bans.insertOne(ban);
ban._id = insertedResult.insertedId; ban._id = insertedResult.insertedId;
return res.status(403).render('ban', { ban.ip.raw = null; //for dynamicresponse
return dynamicResponse(req, res, 403, 'ban', {
bans: [ban] bans: [ban]
}); });
} }

@ -163,7 +163,8 @@ ${res.locals.numFiles > 0 ? req.files.file.map(f => f.name+'|'+(f.phash || '')).
}; };
const insertedResult = await Bans.insertOne(ban); const insertedResult = await Bans.insertOne(ban);
ban._id = insertedResult.insertedId; ban._id = insertedResult.insertedId;
return res.status(403).render('ban', { ban.ip.raw = null; //for dynamicresponse
return dynamicResponse(req, res, 403, 'ban', {
bans: [ban] bans: [ban]
}); });
} }

@ -4,7 +4,7 @@ form.form-post(action=`/forms/appeal`, enctype='application/x-www-form-urlencode
+ban(ban, true) +ban(ban, true)
- const allowAppeal = bans.filter(ban => ban.allowAppeal === true && !ban.appeal).length > 0; - const allowAppeal = bans.filter(ban => ban.allowAppeal === true && !ban.appeal).length > 0;
if allowAppeal === true if allowAppeal === true
h4.no-m-p Appeal bans: h4.no-m-p Appeal:
.form-wrapper.flexleft.mt-10 .form-wrapper.flexleft.mt-10
input(type='hidden' name='_csrf' value=csrf) input(type='hidden' name='_csrf' value=csrf)
.row .row

@ -35,7 +35,7 @@ mixin ban(ban, banpage)
else else
| ⨯ | ⨯
td td
if ban.allowAppeal if ban.allowAppeal && !ban.appeal
| ✓ | ✓
else else
| ⨯ | ⨯

@ -1,9 +1,15 @@
include ../mixins/ban.pug
mixin modal(data) mixin modal(data)
.modal-bg(style=data.hidden?'display:none':'') .modal-bg(style=data.hidden?'display:none':'')
.modal(id=(data.settings ? 'settingsmodal' : '') style=data.hidden?'display:none':'') .modal(id=(data.settings ? 'settingsmodal' : '') style=data.hidden?'display:none':'')
.row .row
p.bold #{data.title} p.bold #{data.title}
a.close.postform-style#modalclose × a.close.postform-style#modalclose ×
if data.bans
h1.board-title Banned!
.row#modalbanned
- const bans = data.bans
include ../includes/banform.pug
if data.message || data.messages || data.error || data.errors if data.message || data.messages || data.error || data.errors
.row .row
ul.nomarks ul.nomarks

Loading…
Cancel
Save