Merge branch 'develop'

indiachan-spamvector v1.0.4
Thomas Lynch 1 year ago
commit a0ef745a73
Signed by: fatchan
GPG Key ID: A7E5E8B7E11EE92D
  1. 12
      CHANGELOG.md
  2. 10
      controllers/forms.js
  3. 3
      controllers/forms/addassets.js
  4. 3
      controllers/forms/addflags.js
  5. 5
      controllers/forms/makepost.js
  6. 3
      controllers/forms/uploadbanners.js
  7. 6
      gulp/res/js/forms.js
  8. 7
      lib/misc/countries.js
  9. 7
      locales/en-GB.json
  10. 3
      locales/pt-PT.json
  11. 3
      locales/ru-RU.json
  12. 10
      package-lock.json
  13. 2
      package.json
  14. 2
      views/pages/bypass.pug
  15. 1
      views/pages/globalmanagesettings.pug

@ -1,10 +1,20 @@
### 1.0.4
- Translation improvements.
- Fix Tor hidden service country name not displaying correctly.
- Make global disabling of anonymizer file posting apply to board banners, flags, custompages.
### 1.0.3
- Translation improvements.
- Add back missing "Lock+Unlist" mode for handling ianctive boards.
- Npm audit.
### 1.0.2
- Translation improvements.
### 1.0.1
- Translation improvements.
- Add a link to board in mod view e.g. /test/ on globalmanage recent posts to give some context.
- Fix dockerignore for docker testing/development, was broken due to translations
- Fix dockerignore for docker testing/development, was broken due to translations.
### 1.0.0
Version 1.0.0 is here. jschan is stable and mature enough and has been for a while. There's no need to go to version 0.9999.9999 and I am comfortable enough to call it "Version 1".

@ -20,7 +20,7 @@ const express = require('express')
, dnsblCheck = require(__dirname+'/../lib/middleware/ip/dnsbl.js')
, blockBypass = require(__dirname+'/../lib/middleware/captcha/blockbypass.js')
, fileMiddlewares = require(__dirname+'/../lib/middleware/file/filemiddlewares.js')
, { setBoardLanguage } = require(__dirname+'/../lib/middleware/locale/locale.js')
, { setBoardLanguage, setQueryLanguage } = require(__dirname+'/../lib/middleware/locale/locale.js')
//controllers
, { deleteBoardController, editBansController, appealController, globalActionController, twofactorController,
actionController, addCustomPageController, deleteCustomPageController, addNewsController,
@ -62,15 +62,15 @@ router.post('/board/:board/deleteboard', useSession, sessionRefresh, csrf, Board
hasPerms.any(Permissions.MANAGE_BOARD_OWNER, Permissions.MANAGE_GLOBAL_BOARDS), deleteBoardController.controller); //delete board
//board crud banners, flags, assets, custompages
router.post('/board/:board/addbanners', useSession, sessionRefresh, Boards.exists, setBoardLanguage, fileMiddlewares.banner, csrf, calcPerms, isLoggedIn,
router.post('/board/:board/addbanners', geoIp, useSession, sessionRefresh, Boards.exists, setBoardLanguage, fileMiddlewares.banner, csrf, calcPerms, isLoggedIn,
hasPerms.one(Permissions.MANAGE_BOARD_CUSTOMISATION), numFiles, uploadBannersController.controller); //add banners
router.post('/board/:board/deletebanners', useSession, sessionRefresh, csrf, Boards.exists, setBoardLanguage, calcPerms, isLoggedIn,
hasPerms.one(Permissions.MANAGE_BOARD_CUSTOMISATION), deleteBannersController.paramConverter, deleteBannersController.controller); //delete banners
router.post('/board/:board/addassets', useSession, sessionRefresh, Boards.exists, setBoardLanguage, fileMiddlewares.asset, csrf, calcPerms, isLoggedIn,
router.post('/board/:board/addassets', geoIp, useSession, sessionRefresh, Boards.exists, setBoardLanguage, fileMiddlewares.asset, csrf, calcPerms, isLoggedIn,
hasPerms.one(Permissions.MANAGE_BOARD_CUSTOMISATION), numFiles, addAssetsController.controller); //add assets
router.post('/board/:board/deleteassets', useSession, sessionRefresh, csrf, Boards.exists, setBoardLanguage, calcPerms, isLoggedIn,
hasPerms.one(Permissions.MANAGE_BOARD_CUSTOMISATION), deleteAssetsController.paramConverter, deleteAssetsController.controller); //delete assets
router.post('/board/:board/addflags', useSession, sessionRefresh, Boards.exists, setBoardLanguage, fileMiddlewares.flag, csrf, calcPerms, isLoggedIn,
router.post('/board/:board/addflags', geoIp, useSession, sessionRefresh, Boards.exists, setBoardLanguage, fileMiddlewares.flag, csrf, calcPerms, isLoggedIn,
hasPerms.one(Permissions.MANAGE_BOARD_CUSTOMISATION), numFiles, addFlagsController.controller); //add flags
router.post('/board/:board/deleteflags', useSession, sessionRefresh, csrf, Boards.exists, setBoardLanguage, calcPerms, isLoggedIn,
hasPerms.one(Permissions.MANAGE_BOARD_CUSTOMISATION), deleteFlagsController.paramConverter, deleteFlagsController.controller); //delete flags
@ -123,7 +123,7 @@ router.post('/deletesessions', useSession, sessionRefresh, csrf, calcPerms, isLo
//removes captcha cookie, for refreshing for noscript users
router.post('/newcaptcha', newCaptchaForm);
//solve captcha for block bypass
router.post('/blockbypass', geoIp, processIp, useSession, sessionRefresh, calcPerms, verifyCaptcha, blockBypassForm);
router.post('/blockbypass', geoIp, processIp, useSession, sessionRefresh, calcPerms, setQueryLanguage, verifyCaptcha, blockBypassForm);
module.exports = router;

@ -14,10 +14,11 @@ module.exports = {
const { __ } = res.locals;
const { globalLimits } = config.get;
const { globalLimits, disableAnonymizerFilePosting } = config.get;
const errors = await checkSchema([
{ result: res.locals.numFiles === 0, expected: false, blocking: true, error: __('Must provide a file') },
{ result: (res.locals.anonymizer && disableAnonymizerFilePosting), expected: false, error: __('Posting files through anonymizers has been disabled globally') },
{ result: numberBody(res.locals.numFiles, 0, globalLimits.assetFiles.max), expected: true, error: __('Exceeded max asset uploads in one request of %s', globalLimits.assetFiles.max) },
{ result: numberBody(res.locals.board.assets.length+res.locals.numFiles, 0, globalLimits.assetFiles.total), expected: true, error: __('Total number of assets would exceed global limit of %s', globalLimits.assetFiles.total) },
]);

@ -14,10 +14,11 @@ module.exports = {
const { __ } = res.locals;
const { globalLimits } = config.get;
const { globalLimits, disableAnonymizerFilePosting } = config.get;
const errors = await checkSchema([
{ result: res.locals.numFiles === 0, expected: false, blocking: true, error: __('Must provide a file') },
{ result: (res.locals.anonymizer && disableAnonymizerFilePosting), expected: false, error: __('Posting files through anonymizers has been disabled globally') },
{ result: numberBody(res.locals.numFiles, 0, globalLimits.flagFiles.max), expected: true, error: __('Exceeded max flag uploads in one request of %s', globalLimits.flagFiles.max) },
{ result: numberBody(Object.keys(res.locals.board.flags).length+res.locals.numFiles, 0, globalLimits.flagFiles.total), expected: true, error: __('Total number of flags would exceed global limit of %s', globalLimits.flagFiles.total) },
]);

@ -1,6 +1,7 @@
'use strict';
const makePost = require(__dirname+'/../../models/forms/makepost.js')
, { Permissions } = require(__dirname+'/../../lib/permission/permissions.js')
, deleteTempFiles = require(__dirname+'/../../lib/file/deletetempfiles.js')
, dynamicResponse = require(__dirname+'/../../lib/misc/dynamic.js')
, { func: pruneFiles } = require(__dirname+'/../../schedules/tasks/prune.js')
@ -25,11 +26,11 @@ module.exports = {
const { globalLimits, disableAnonymizerFilePosting } = config.get;
const hasNoMandatoryFile = globalLimits.postFiles.max !== 0 && res.locals.board.settings.maxFiles !== 0 && res.locals.numFiles === 0;
//maybe add more duplicates here?
const disableBoardAnonymizerFilePosting = res.locals.board.settings.disableAnonymizerFilePosting && !res.locals.permissions.get(Permissions.MANAGE_BOARD_GENERAL);
const errors = await checkSchema([
{ result: (lengthBody(req.body.message, 1) && res.locals.numFiles === 0), expected: false, error: __('Posts must include a message or file') },
{ result: (res.locals.anonymizer && (disableAnonymizerFilePosting || res.locals.board.settings.disableAnonymizerFilePosting)
{ result: (res.locals.anonymizer && (disableAnonymizerFilePosting || disableBoardAnonymizerFilePosting)
&& res.locals.numFiles > 0), expected: false, error: __(`Posting files through anonymizers has been disabled ${disableAnonymizerFilePosting ? 'globally' : 'on this board'}`) },
{ result: res.locals.numFiles > res.locals.board.settings.maxFiles, blocking: true, expected: false, error: __(`Too many files. Max files per post ${res.locals.board.settings.maxFiles < globalLimits.postFiles.max ? 'on this board ' : ''}is %s`, res.locals.board.settings.maxFiles) },
{ result: (lengthBody(req.body.subject, 1) && (!existsBody(req.body.thread)

@ -14,10 +14,11 @@ module.exports = {
const { __ } = res.locals;
const { globalLimits } = config.get;
const { globalLimits, disableAnonymizerFilePosting } = config.get;
const errors = await checkSchema([
{ result: res.locals.numFiles === 0, expected: false, blocking: true, error: __('Must provide a file') },
{ result: (res.locals.anonymizer && disableAnonymizerFilePosting), expected: false, error: __('Posting files through anonymizers has been disabled globally') },
{ result: numberBody(res.locals.numFiles, 0, globalLimits.bannerFiles.max), expected: true, error: __('Exceeded max banner uploads in one request of %s', globalLimits.bannerFiles.max) },
{ result: numberBody(res.locals.board.banners.length+res.locals.numFiles, 0, globalLimits.bannerFiles.total), expected: true, error: __('Total number of banners would exceed global limit of %s', globalLimits.bannerFiles.total) },
]);

@ -1,4 +1,4 @@
/* globals __n modal Tegaki grecaptcha hcaptcha captchaController appendLocalStorageArray socket isThread setLocalStorage forceUpdate captchaController uploaditem */
/* globals __ __n modal Tegaki grecaptcha hcaptcha captchaController appendLocalStorageArray socket isThread setLocalStorage forceUpdate captchaController uploaditem */
async function videoThumbnail(file) {
return new Promise((resolve, reject) => {
const hiddenVideo = document.createElement('video');
@ -334,12 +334,12 @@ class postFormHandler {
} else {
//not a 200 so probably error
if (!this.captchaField && json.message === 'Incorrect captcha answer') {
if (!this.captchaField && json.message === __('Incorrect captcha answer')) {
/* add missing captcha field if we got an error about it and the form has no captcha field
(must have been enabeld after we loaded the page) */
captchaController.addMissingCaptcha();
this.captchaField = true;
} else if (json.message === 'Captcha expired') {
} else if (json.message === __('Captcha expired')) {
//if captcha is expired, just refresh the captcha
const captcha = this.form.querySelector('.captcharefresh');
if (captcha) {

@ -15,10 +15,15 @@ const countries = require('i18n-iso-countries')
'LOKI': 'Lokinet SNApp',
})));
//Monkey patch until https://github.com/michaelwittig/node-i18n-iso-countries/issues/322
const alpha3s = countries.getAlpha3Codes();
alpha3s['TOR'] = 'Tor Hidden Service';
alpha3s['LOKI'] = 'Lokinet SNApp';
i18n.getLocales()
.forEach(locale => {
const localeExtraCodesMap = { ...extraCountryNames };
for (let code in localeExtraCodesMap) {
for (const code in localeExtraCodesMap) {
localeExtraCodesMap[code] = i18n.__({
phrase: localeExtraCodesMap[code],
locale: locale,

@ -1051,7 +1051,7 @@
"Raw IPs": "Raw IPs",
"Reason": "Reason",
"Recent": "Recent",
"Recent Posts": "Recept Posts",
"Recent Posts": "Recent Posts",
"Recently bumped threads from multiple boards": "Recently bumped threads from multiple boards",
"Recording replay": "Recording replay",
"Recursive post hide": "Recursive post hide",
@ -1118,7 +1118,7 @@
"Secure Cookies": "Secure Cookies",
"Security": "Security",
"See Global Post History": "See Global Post History",
"Seen?": "Visto?",
"Seen?": "Seen?",
"Select/Drop/Paste files": {
"one": "Select/Drop/Paste file",
"other": "Select/Drop/Paste files"
@ -1392,5 +1392,6 @@
"Message too long.": "Message too long.",
"View the full text": "View the full text",
"View the full thread": "View the full thread",
"%s earlier": "%s earlier"
"%s earlier": "%s earlier",
"Lock+Unlist board": "Lock+Unlist board"
}

@ -1392,5 +1392,6 @@
"Message too long.": "Mensagem demasiado longa.",
"View the full text": "Ver texto completo",
"View the full thread": "Ver fio completo",
"%s earlier": "%s anteriores"
"%s earlier": "%s anteriores",
"Lock+Unlist board": "Trancar+Remover da lista"
}

@ -1392,5 +1392,6 @@
"Message too long.": "Сообщение слишком длинное.",
"View the full text": "Просмотреть полный текст",
"View the full thread": "Просмотреть полную ветку",
"%s earlier": "%s выше"
"%s earlier": "%s выше",
"Lock+Unlist board": "замок+исключить из списка"
}

10
package-lock.json generated

@ -1,12 +1,12 @@
{
"name": "jschan",
"version": "1.0.2",
"version": "1.0.4",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "jschan",
"version": "1.0.2",
"version": "1.0.4",
"license": "AGPL-3.0-only",
"dependencies": {
"@fatchan/express-fileupload": "^1.4.2",
@ -15432,9 +15432,9 @@
}
},
"node_modules/vm2": {
"version": "3.9.14",
"resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.14.tgz",
"integrity": "sha512-HgvPHYHeQy8+QhzlFryvSteA4uQLBCOub02mgqdR+0bN/akRZ48TGB1v0aCv7ksyc0HXx16AZtMHKS38alc6TA==",
"version": "3.9.16",
"resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.16.tgz",
"integrity": "sha512-3T9LscojNTxdOyG+e8gFeyBXkMlOBYDoF6dqZbj+MPVHi9x10UfiTAJIobuchRCp3QvC+inybTbMJIUrLsig0w==",
"dependencies": {
"acorn": "^8.7.0",
"acorn-walk": "^8.2.0"

@ -1,6 +1,6 @@
{
"name": "jschan",
"version": "1.0.2",
"version": "1.0.4",
"migrateVersion": "1.0.0",
"description": "",
"main": "server.js",

@ -6,7 +6,7 @@ block head
block content
h1.board-title #{__('Block Bypass')}
.form-wrapper.flex-center.mv-10
form.form-post(action='/forms/blockbypass' method='POST' data-captcha-preload='true')
form.form-post(action=`/forms/blockbypass?language=${encodeURIComponent(pageLanguage)}` method='POST' data-captcha-preload='true')
.row
.col
include ../includes/captcha.pug

@ -208,6 +208,7 @@ block content
select(name='abandoned_board_action')
option(value='0', selected=settings.abandonedBoardAction === 0) #{__('Do nothing')}
option(value='1', selected=settings.abandonedBoardAction === 1) #{__('Lock board')}
option(value='2', selected=settings.abandonedBoardAction === 2) #{__('Lock+Unlist board')}
option(value='3', selected=settings.abandonedBoardAction === 3) #{__('Delete board')}
.row
h4.mv-5 #{__('Global Limits')}

Loading…
Cancel
Save