|
|
@ -1,7 +1,6 @@ |
|
|
|
'use strict'; |
|
|
|
'use strict'; |
|
|
|
|
|
|
|
|
|
|
|
const path = require('path') |
|
|
|
const { createHash, randomBytes } = require('crypto') |
|
|
|
, { createHash, randomBytes } = require('crypto') |
|
|
|
|
|
|
|
, randomBytesAsync = require('util').promisify(randomBytes) |
|
|
|
, randomBytesAsync = require('util').promisify(randomBytes) |
|
|
|
, { remove, emptyDir, pathExists, stat: fsStat } = require('fs-extra') |
|
|
|
, { remove, emptyDir, pathExists, stat: fsStat } = require('fs-extra') |
|
|
|
, uploadDirectory = require(__dirname+'/../../lib/file/uploaddirectory.js') |
|
|
|
, uploadDirectory = require(__dirname+'/../../lib/file/uploaddirectory.js') |
|
|
@ -34,7 +33,7 @@ const path = require('path') |
|
|
|
, dynamicResponse = require(__dirname+'/../../lib/misc/dynamic.js') |
|
|
|
, dynamicResponse = require(__dirname+'/../../lib/misc/dynamic.js') |
|
|
|
, { buildThread } = require(__dirname+'/../../lib/build/tasks.js'); |
|
|
|
, { buildThread } = require(__dirname+'/../../lib/build/tasks.js'); |
|
|
|
|
|
|
|
|
|
|
|
module.exports = async (req, res, next) => { |
|
|
|
module.exports = async (req, res) => { |
|
|
|
|
|
|
|
|
|
|
|
const { filterBanAppealable, checkRealMimeTypes, thumbSize, thumbExtension, videoThumbPercentage, |
|
|
|
const { filterBanAppealable, checkRealMimeTypes, thumbSize, thumbExtension, videoThumbPercentage, |
|
|
|
strictFiltering, animatedGifThumbnails, audioThumbnails, dontStoreRawIps } = config.get; |
|
|
|
strictFiltering, animatedGifThumbnails, audioThumbnails, dontStoreRawIps } = config.get; |
|
|
@ -42,7 +41,7 @@ module.exports = async (req, res, next) => { |
|
|
|
//spam/flood check
|
|
|
|
//spam/flood check
|
|
|
|
const flood = await spamCheck(req, res); |
|
|
|
const flood = await spamCheck(req, res); |
|
|
|
if (flood) { |
|
|
|
if (flood) { |
|
|
|
deleteTempFiles(req).catch(e => console.error); |
|
|
|
deleteTempFiles(req).catch(console.error); |
|
|
|
return dynamicResponse(req, res, 429, 'message', { |
|
|
|
return dynamicResponse(req, res, 429, 'message', { |
|
|
|
'title': 'Flood detected', |
|
|
|
'title': 'Flood detected', |
|
|
|
'message': 'Please wait before making another post, or a post similar to another user', |
|
|
|
'message': 'Please wait before making another post, or a post similar to another user', |
|
|
@ -51,18 +50,18 @@ module.exports = async (req, res, next) => { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// check if this is responding to an existing thread
|
|
|
|
// check if this is responding to an existing thread
|
|
|
|
let redirect = `/${req.params.board}/` |
|
|
|
let redirect = `/${req.params.board}/`; |
|
|
|
let salt = null; |
|
|
|
let salt = null; |
|
|
|
let thread = null; |
|
|
|
let thread = null; |
|
|
|
const isStaffOrGlobal = res.locals.permissions.hasAny(Permissions.MANAGE_GLOBAL_GENERAL, Permissions.MANAGE_BOARD_GENERAL); |
|
|
|
const isStaffOrGlobal = res.locals.permissions.hasAny(Permissions.MANAGE_GLOBAL_GENERAL, Permissions.MANAGE_BOARD_GENERAL); |
|
|
|
const { filterBanDuration, filterMode, filters, blockedCountries, threadLimit, ids, userPostSpoiler, |
|
|
|
const { filterBanDuration, filterMode, filters, blockedCountries, threadLimit, ids, userPostSpoiler, |
|
|
|
lockReset, captchaReset, pphTrigger, tphTrigger, tphTriggerAction, pphTriggerAction, |
|
|
|
pphTrigger, tphTrigger, tphTriggerAction, pphTriggerAction, |
|
|
|
sageOnlyEmail, forceAnon, replyLimit, disableReplySubject, |
|
|
|
sageOnlyEmail, forceAnon, replyLimit, disableReplySubject, |
|
|
|
captchaMode, lockMode, allowedFileTypes, customFlags, geoFlags, fileR9KMode, messageR9KMode } = res.locals.board.settings; |
|
|
|
captchaMode, lockMode, allowedFileTypes, customFlags, geoFlags, fileR9KMode, messageR9KMode } = res.locals.board.settings; |
|
|
|
if (!isStaffOrGlobal |
|
|
|
if (!isStaffOrGlobal |
|
|
|
&& res.locals.country //permission for this or nah?
|
|
|
|
&& res.locals.country //permission for this or nah?
|
|
|
|
&& blockedCountries.includes(res.locals.country.code)) { |
|
|
|
&& blockedCountries.includes(res.locals.country.code)) { |
|
|
|
await deleteTempFiles(req).catch(e => console.error); |
|
|
|
await deleteTempFiles(req).catch(console.error); |
|
|
|
return dynamicResponse(req, res, 403, 'message', { |
|
|
|
return dynamicResponse(req, res, 403, 'message', { |
|
|
|
'title': 'Forbidden', |
|
|
|
'title': 'Forbidden', |
|
|
|
'message': `Your country "${res.locals.country.name}" is not allowed to post on this board`, |
|
|
|
'message': `Your country "${res.locals.country.name}" is not allowed to post on this board`, |
|
|
@ -71,7 +70,7 @@ module.exports = async (req, res, next) => { |
|
|
|
} |
|
|
|
} |
|
|
|
if ((lockMode === 2 || (lockMode === 1 && !req.body.thread)) //if board lock, or thread lock and its a new thread
|
|
|
|
if ((lockMode === 2 || (lockMode === 1 && !req.body.thread)) //if board lock, or thread lock and its a new thread
|
|
|
|
&& !isStaffOrGlobal) { //and not staff
|
|
|
|
&& !isStaffOrGlobal) { //and not staff
|
|
|
|
await deleteTempFiles(req).catch(e => console.error); |
|
|
|
await deleteTempFiles(req).catch(console.error); |
|
|
|
return dynamicResponse(req, res, 400, 'message', { |
|
|
|
return dynamicResponse(req, res, 400, 'message', { |
|
|
|
'title': 'Bad request', |
|
|
|
'title': 'Bad request', |
|
|
|
'message': lockMode === 1 ? 'Thread creation locked' : 'Board locked', |
|
|
|
'message': lockMode === 1 ? 'Thread creation locked' : 'Board locked', |
|
|
@ -81,7 +80,7 @@ module.exports = async (req, res, next) => { |
|
|
|
if (req.body.thread) { |
|
|
|
if (req.body.thread) { |
|
|
|
thread = await Posts.getPost(req.params.board, req.body.thread, true); |
|
|
|
thread = await Posts.getPost(req.params.board, req.body.thread, true); |
|
|
|
if (!thread || thread.thread != null) { |
|
|
|
if (!thread || thread.thread != null) { |
|
|
|
await deleteTempFiles(req).catch(e => console.error); |
|
|
|
await deleteTempFiles(req).catch(console.error); |
|
|
|
return dynamicResponse(req, res, 400, 'message', { |
|
|
|
return dynamicResponse(req, res, 400, 'message', { |
|
|
|
'title': 'Bad request', |
|
|
|
'title': 'Bad request', |
|
|
|
'message': 'Thread does not exist', |
|
|
|
'message': 'Thread does not exist', |
|
|
@ -89,9 +88,9 @@ module.exports = async (req, res, next) => { |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
salt = thread.salt; |
|
|
|
salt = thread.salt; |
|
|
|
redirect += `thread/${req.body.thread}.html` |
|
|
|
redirect += `thread/${req.body.thread}.html`; |
|
|
|
if (thread.locked && !isStaffOrGlobal) { |
|
|
|
if (thread.locked && !isStaffOrGlobal) { |
|
|
|
await deleteTempFiles(req).catch(e => console.error); |
|
|
|
await deleteTempFiles(req).catch(console.error); |
|
|
|
return dynamicResponse(req, res, 400, 'message', { |
|
|
|
return dynamicResponse(req, res, 400, 'message', { |
|
|
|
'title': 'Bad request', |
|
|
|
'title': 'Bad request', |
|
|
|
'message': 'Thread Locked', |
|
|
|
'message': 'Thread Locked', |
|
|
@ -99,7 +98,7 @@ module.exports = async (req, res, next) => { |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
if (thread.replyposts >= replyLimit && !thread.cyclic) { //reply limit
|
|
|
|
if (thread.replyposts >= replyLimit && !thread.cyclic) { //reply limit
|
|
|
|
await deleteTempFiles(req).catch(e => console.error); |
|
|
|
await deleteTempFiles(req).catch(console.error); |
|
|
|
return dynamicResponse(req, res, 400, 'message', { |
|
|
|
return dynamicResponse(req, res, 400, 'message', { |
|
|
|
'title': 'Bad request', |
|
|
|
'title': 'Bad request', |
|
|
|
'message': 'Thread reached reply limit', |
|
|
|
'message': 'Thread reached reply limit', |
|
|
@ -116,25 +115,24 @@ module.exports = async (req, res, next) => { |
|
|
|
filterBanDuration: globalFilterBanDuration } = config.get; |
|
|
|
filterBanDuration: globalFilterBanDuration } = config.get; |
|
|
|
|
|
|
|
|
|
|
|
let hitGlobalFilter = false |
|
|
|
let hitGlobalFilter = false |
|
|
|
, hitLocalFilter = false |
|
|
|
, hitLocalFilter = false; |
|
|
|
, ban; |
|
|
|
let { combinedString, strictCombinedString } = getFilterStrings(req, res, strictFiltering || res.locals.board.settings.strictFiltering); |
|
|
|
let [combinedString, strictCombinedString] = getFilterStrings(req, res, strictFiltering || res.locals.board.settings.strictFiltering); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//compare to global filters
|
|
|
|
//compare to global filters
|
|
|
|
if (globalFilters && globalFilters.length > 0 && globalFilterMode > 0) { |
|
|
|
if (globalFilters && globalFilters.length > 0 && globalFilterMode > 0) { |
|
|
|
hitGlobalFilter = globalFilters.some(filter => { return strictCombinedString.includes(filter.toLowerCase()) }); |
|
|
|
hitGlobalFilter = globalFilters.some(filter => { return strictCombinedString.includes(filter.toLowerCase()); }); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//compare to board filters
|
|
|
|
//compare to board filters
|
|
|
|
if (!hitGlobalFilter && !res.locals.permissions.get(Permissions.MANAGE_BOARD_GENERAL) |
|
|
|
if (!hitGlobalFilter && !res.locals.permissions.get(Permissions.MANAGE_BOARD_GENERAL) |
|
|
|
&& filterMode > 0 && filters && filters.length > 0) { |
|
|
|
&& filterMode > 0 && filters && filters.length > 0) { |
|
|
|
const localFilterContents = res.locals.board.settings.strictFiltering === true ? strictCombinedString : combinedString; |
|
|
|
const localFilterContents = res.locals.board.settings.strictFiltering === true ? strictCombinedString : combinedString; |
|
|
|
hitLocalFilter = filters.some(filter => { return localFilterContents.includes(filter.toLowerCase()) }); |
|
|
|
hitLocalFilter = filters.some(filter => { return localFilterContents.includes(filter.toLowerCase()); }); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//block post/apply bans if an active filter matched
|
|
|
|
//block post/apply bans if an active filter matched
|
|
|
|
if (hitGlobalFilter || hitLocalFilter) { |
|
|
|
if (hitGlobalFilter || hitLocalFilter) { |
|
|
|
await deleteTempFiles(req).catch(e => console.error); |
|
|
|
await deleteTempFiles(req).catch(console.error); |
|
|
|
return filterActions(req, res, hitGlobalFilter, filterMode, globalFilterMode, |
|
|
|
return filterActions(req, res, hitGlobalFilter, filterMode, globalFilterMode, |
|
|
|
filterBanDuration, globalFilterBanDuration, globalFilterBanDuration, |
|
|
|
filterBanDuration, globalFilterBanDuration, globalFilterBanDuration, |
|
|
|
filterBanAppealable, redirect); |
|
|
|
filterBanAppealable, redirect); |
|
|
@ -150,7 +148,7 @@ module.exports = async (req, res, next) => { |
|
|
|
if ((req.body.thread && messageR9KMode === 1) || messageR9KMode === 2) { |
|
|
|
if ((req.body.thread && messageR9KMode === 1) || messageR9KMode === 2) { |
|
|
|
const postWithExistingMessage = await Posts.checkExistingMessage(res.locals.board._id, (messageR9KMode === 2 ? null : req.body.thread), messageHash); |
|
|
|
const postWithExistingMessage = await Posts.checkExistingMessage(res.locals.board._id, (messageR9KMode === 2 ? null : req.body.thread), messageHash); |
|
|
|
if (postWithExistingMessage != null) { |
|
|
|
if (postWithExistingMessage != null) { |
|
|
|
await deleteTempFiles(req).catch(e => console.error); |
|
|
|
await deleteTempFiles(req).catch(console.error); |
|
|
|
return dynamicResponse(req, res, 409, 'message', { |
|
|
|
return dynamicResponse(req, res, 409, 'message', { |
|
|
|
'title': 'Conflict', |
|
|
|
'title': 'Conflict', |
|
|
|
'message': `Messages must be unique ${messageR9KMode === 1 ? 'in this thread' : 'on this board'}. Your message is not unique.`, |
|
|
|
'message': `Messages must be unique ${messageR9KMode === 1 ? 'in this thread' : 'on this board'}. Your message is not unique.`, |
|
|
@ -169,7 +167,7 @@ module.exports = async (req, res, next) => { |
|
|
|
const filesHashes = req.files.file.map(f => f.sha256); |
|
|
|
const filesHashes = req.files.file.map(f => f.sha256); |
|
|
|
const postWithExistingFiles = await Posts.checkExistingFiles(res.locals.board._id, (fileR9KMode === 2 ? null : req.body.thread), filesHashes); |
|
|
|
const postWithExistingFiles = await Posts.checkExistingFiles(res.locals.board._id, (fileR9KMode === 2 ? null : req.body.thread), filesHashes); |
|
|
|
if (postWithExistingFiles != null) { |
|
|
|
if (postWithExistingFiles != null) { |
|
|
|
await deleteTempFiles(req).catch(e => console.error); |
|
|
|
await deleteTempFiles(req).catch(console.error); |
|
|
|
const conflictingFiles = req.files.file |
|
|
|
const conflictingFiles = req.files.file |
|
|
|
.filter(f => postWithExistingFiles.files.some(fx => fx.hash === f.sha256)) |
|
|
|
.filter(f => postWithExistingFiles.files.some(fx => fx.hash === f.sha256)) |
|
|
|
.map(f => f.name) |
|
|
|
.map(f => f.name) |
|
|
@ -185,7 +183,7 @@ module.exports = async (req, res, next) => { |
|
|
|
//basic mime type check
|
|
|
|
//basic mime type check
|
|
|
|
for (let i = 0; i < res.locals.numFiles; i++) { |
|
|
|
for (let i = 0; i < res.locals.numFiles; i++) { |
|
|
|
if (!mimeTypes.allowed(req.files.file[i].mimetype, allowedFileTypes)) { |
|
|
|
if (!mimeTypes.allowed(req.files.file[i].mimetype, allowedFileTypes)) { |
|
|
|
await deleteTempFiles(req).catch(e => console.error); |
|
|
|
await deleteTempFiles(req).catch(console.error); |
|
|
|
return dynamicResponse(req, res, 400, 'message', { |
|
|
|
return dynamicResponse(req, res, 400, 'message', { |
|
|
|
'title': 'Bad request', |
|
|
|
'title': 'Bad request', |
|
|
|
'message': `Mime type "${req.files.file[i].mimetype}" for "${req.files.file[i].name}" not allowed`, |
|
|
|
'message': `Mime type "${req.files.file[i].mimetype}" for "${req.files.file[i].name}" not allowed`, |
|
|
@ -198,7 +196,7 @@ module.exports = async (req, res, next) => { |
|
|
|
if (checkRealMimeTypes) { |
|
|
|
if (checkRealMimeTypes) { |
|
|
|
for (let i = 0; i < res.locals.numFiles; i++) { |
|
|
|
for (let i = 0; i < res.locals.numFiles; i++) { |
|
|
|
if (!(await mimeTypes.realMimeCheck(req.files.file[i]))) { |
|
|
|
if (!(await mimeTypes.realMimeCheck(req.files.file[i]))) { |
|
|
|
deleteTempFiles(req).catch(e => console.error); |
|
|
|
deleteTempFiles(req).catch(console.error); |
|
|
|
return dynamicResponse(req, res, 400, 'message', { |
|
|
|
return dynamicResponse(req, res, 400, 'message', { |
|
|
|
'title': 'Bad request', |
|
|
|
'title': 'Bad request', |
|
|
|
'message': `Mime type mismatch for file "${req.files.file[i].name}"`, |
|
|
|
'message': `Mime type mismatch for file "${req.files.file[i].name}"`, |
|
|
@ -233,14 +231,14 @@ module.exports = async (req, res, next) => { |
|
|
|
let [type, subtype] = processedFile.mimetype.split('/'); |
|
|
|
let [type, subtype] = processedFile.mimetype.split('/'); |
|
|
|
//check if already exists
|
|
|
|
//check if already exists
|
|
|
|
const existsFull = await pathExists(`${uploadDirectory}/file/${processedFile.filename}`); |
|
|
|
const existsFull = await pathExists(`${uploadDirectory}/file/${processedFile.filename}`); |
|
|
|
processedFile.sizeString = formatSize(processedFile.size) |
|
|
|
processedFile.sizeString = formatSize(processedFile.size); |
|
|
|
const saveFull = async () => { |
|
|
|
const saveFull = async () => { |
|
|
|
await Files.increment(processedFile); |
|
|
|
await Files.increment(processedFile); |
|
|
|
req.files.file[i].inced = true; |
|
|
|
req.files.file[i].inced = true; |
|
|
|
if (!existsFull) { |
|
|
|
if (!existsFull) { |
|
|
|
await moveUpload(file, processedFile.filename, 'file'); |
|
|
|
await moveUpload(file, processedFile.filename, 'file'); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
if (mimeTypes.other.has(processedFile.mimetype)) { |
|
|
|
if (mimeTypes.other.has(processedFile.mimetype)) { |
|
|
|
//"other" mimes from config, overrides main type to avoid codec issues in browser or ffmpeg for unsupported filetypes
|
|
|
|
//"other" mimes from config, overrides main type to avoid codec issues in browser or ffmpeg for unsupported filetypes
|
|
|
|
processedFile.hasThumb = false; |
|
|
|
processedFile.hasThumb = false; |
|
|
@ -256,7 +254,7 @@ module.exports = async (req, res, next) => { |
|
|
|
try { |
|
|
|
try { |
|
|
|
imageData = await imageIdentify(req.files.file[i].tempFilePath, null, true); |
|
|
|
imageData = await imageIdentify(req.files.file[i].tempFilePath, null, true); |
|
|
|
} catch (e) { |
|
|
|
} catch (e) { |
|
|
|
await deleteTempFiles(req).catch(e => console.error); |
|
|
|
await deleteTempFiles(req).catch(console.error); |
|
|
|
return dynamicResponse(req, res, 400, 'message', { |
|
|
|
return dynamicResponse(req, res, 400, 'message', { |
|
|
|
'title': 'Bad request', |
|
|
|
'title': 'Bad request', |
|
|
|
'message': `The server failed to process "${req.files.file[i].name}". Possible unsupported or corrupt file.`, |
|
|
|
'message': `The server failed to process "${req.files.file[i].name}". Possible unsupported or corrupt file.`, |
|
|
@ -294,7 +292,7 @@ module.exports = async (req, res, next) => { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
case 'audio': |
|
|
|
case 'audio': |
|
|
|
case 'video': |
|
|
|
case 'video': { |
|
|
|
//video metadata
|
|
|
|
//video metadata
|
|
|
|
const audioVideoData = await ffprobe(req.files.file[i].tempFilePath, null, true); |
|
|
|
const audioVideoData = await ffprobe(req.files.file[i].tempFilePath, null, true); |
|
|
|
processedFile.duration = audioVideoData.format.duration; |
|
|
|
processedFile.duration = audioVideoData.format.duration; |
|
|
@ -303,7 +301,7 @@ module.exports = async (req, res, next) => { |
|
|
|
if (videoStreams.length > 0) { |
|
|
|
if (videoStreams.length > 0) { |
|
|
|
processedFile.thumbextension = thumbExtension; |
|
|
|
processedFile.thumbextension = thumbExtension; |
|
|
|
processedFile.geometry = {width: videoStreams[0].coded_width, height: videoStreams[0].coded_height}; |
|
|
|
processedFile.geometry = {width: videoStreams[0].coded_width, height: videoStreams[0].coded_height}; |
|
|
|
processedFile.geometryString = `${processedFile.geometry.width}x${processedFile.geometry.height}` |
|
|
|
processedFile.geometryString = `${processedFile.geometry.width}x${processedFile.geometry.height}`; |
|
|
|
processedFile.hasThumb = true; |
|
|
|
processedFile.hasThumb = true; |
|
|
|
await saveFull(); |
|
|
|
await saveFull(); |
|
|
|
if (!existsThumb) { |
|
|
|
if (!existsThumb) { |
|
|
@ -336,6 +334,7 @@ module.exports = async (req, res, next) => { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
default: |
|
|
|
default: |
|
|
|
throw new Error(`invalid file mime type: ${processedFile.mimetype}`); |
|
|
|
throw new Error(`invalid file mime type: ${processedFile.mimetype}`); |
|
|
|
} |
|
|
|
} |
|
|
@ -360,7 +359,7 @@ module.exports = async (req, res, next) => { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// because express middleware is autistic i need to do this
|
|
|
|
// because express middleware is autistic i need to do this
|
|
|
|
deleteTempFiles(req).catch(e => console.error); |
|
|
|
deleteTempFiles(req).catch(console.error); |
|
|
|
|
|
|
|
|
|
|
|
let userId = null; |
|
|
|
let userId = null; |
|
|
|
if (!salt) { |
|
|
|
if (!salt) { |
|
|
@ -407,7 +406,7 @@ module.exports = async (req, res, next) => { |
|
|
|
const { message, quotes, crossquotes } = await messageHandler(nomarkup, req.params.board, req.body.thread, res.locals.permissions); |
|
|
|
const { message, quotes, crossquotes } = await messageHandler(nomarkup, req.params.board, req.body.thread, res.locals.permissions); |
|
|
|
|
|
|
|
|
|
|
|
//build post data for db. for some reason all the property names are lower case :^)
|
|
|
|
//build post data for db. for some reason all the property names are lower case :^)
|
|
|
|
const now = Date.now() |
|
|
|
const now = Date.now(); |
|
|
|
const data = { |
|
|
|
const data = { |
|
|
|
'date': new Date(now), |
|
|
|
'date': new Date(now), |
|
|
|
'u': now, |
|
|
|
'u': now, |
|
|
@ -433,7 +432,7 @@ module.exports = async (req, res, next) => { |
|
|
|
quotes, //posts this post replies to
|
|
|
|
quotes, //posts this post replies to
|
|
|
|
crossquotes, //quotes to other threads in same board
|
|
|
|
crossquotes, //quotes to other threads in same board
|
|
|
|
'backlinks': [], //posts replying to this post
|
|
|
|
'backlinks': [], //posts replying to this post
|
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
if (!req.body.thread) { |
|
|
|
if (!req.body.thread) { |
|
|
|
//if this is a thread, add thread specific properties
|
|
|
|
//if this is a thread, add thread specific properties
|
|
|
@ -458,7 +457,6 @@ module.exports = async (req, res, next) => { |
|
|
|
const { postId, postMongoId } = await Posts.insertOne(res.locals.board, data, thread, res.locals.anonymizer); |
|
|
|
const { postId, postMongoId } = await Posts.insertOne(res.locals.board, data, thread, res.locals.anonymizer); |
|
|
|
|
|
|
|
|
|
|
|
let enableCaptcha = false; //make this returned from some function, refactor and move the next section to another file
|
|
|
|
let enableCaptcha = false; //make this returned from some function, refactor and move the next section to another file
|
|
|
|
const pphTriggerActive = (pphTriggerAction > 0 && pphTrigger > 0); |
|
|
|
|
|
|
|
const tphTriggerActive = (tphTriggerAction > 0 && tphTrigger > 0); |
|
|
|
const tphTriggerActive = (tphTriggerAction > 0 && tphTrigger > 0); |
|
|
|
if (pphTriggerAction || tphTriggerActive) { //if a trigger is enabled
|
|
|
|
if (pphTriggerAction || tphTriggerActive) { //if a trigger is enabled
|
|
|
|
const triggerUpdate = { |
|
|
|
const triggerUpdate = { |
|
|
@ -487,7 +485,7 @@ module.exports = async (req, res, next) => { |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
}; |
|
|
|
const updatedPphTrigger = pphTriggerUpdate && calcTriggerMode(triggerUpdate, pphTrigger, pphTriggerAction, hourPosts.pph); |
|
|
|
const updatedPphTrigger = pphTriggerUpdate && calcTriggerMode(triggerUpdate, pphTrigger, pphTriggerAction, hourPosts.pph); |
|
|
|
const updatedTphTrigger = tphTriggerUpdate && calcTriggerMode(triggerUpdate, tphTrigger, tphTriggerAction, hourPosts.tph); |
|
|
|
const updatedTphTrigger = tphTriggerUpdate && calcTriggerMode(triggerUpdate, tphTrigger, tphTriggerAction, hourPosts.tph); |
|
|
|
if (updatedPphTrigger || updatedTphTrigger) { |
|
|
|
if (updatedPphTrigger || updatedTphTrigger) { |
|
|
@ -586,7 +584,7 @@ module.exports = async (req, res, next) => { |
|
|
|
'locked': data.locked, |
|
|
|
'locked': data.locked, |
|
|
|
'bumplocked': data.bumplocked, |
|
|
|
'bumplocked': data.bumplocked, |
|
|
|
'cyclic': data.cyclic, |
|
|
|
'cyclic': data.cyclic, |
|
|
|
} |
|
|
|
}; |
|
|
|
if (data.thread) { |
|
|
|
if (data.thread) { |
|
|
|
//dont emit thread to this socket, because the room only exists when the thread is open
|
|
|
|
//dont emit thread to this socket, because the room only exists when the thread is open
|
|
|
|
Socketio.emitRoom(`${res.locals.board._id}-${data.thread}`, 'newPost', projectedPost); |
|
|
|
Socketio.emitRoom(`${res.locals.board._id}-${data.thread}`, 'newPost', projectedPost); |
|
|
@ -665,4 +663,4 @@ module.exports = async (req, res, next) => { |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
}; |
|
|
|