diff --git a/README.md b/README.md index 901f31b6..e2dd6a27 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Anonymous imageboard software. ##### Requirements - Linux - Debian used in this example -- Node.j - the application runtime +- Node.js - the application runtime - MongoDB - the database - Redis - session store, task queue, locks, caching, websocket message arbiter - Nginx - webserver/proxy, serve static files, handle https, GeoIP lookup diff --git a/helpers/posting/diceroll.js b/helpers/posting/diceroll.js index d134c28c..4872df14 100644 --- a/helpers/posting/diceroll.js +++ b/helpers/posting/diceroll.js @@ -1,17 +1,40 @@ 'use strict'; -module.exports = (match, numdice, numsides, operator, modifier) => { - numdice = parseInt(numdice); - numsides = parseInt(numsides); - let sum = (Math.floor(Math.random() * numsides) + 1) * numdice; - if (modifier && operator) { - modifier = parseInt(modifier); - //do i need to make sure it doesnt go negative or maybe give absolute value? - if (operator === '+') { - sum += modifier; - } else { - sum -= modifier; +module.exports = { + + regexPrepare: /##(?[1-9][0-9]{0,1})d(?1[0-9]{1,8}|[2-9][0-9]{0,8})(?:(?[+-])(?[1-9][0-9]{0,8}))?(?=[1-9][0-9]{0,8})?/gmi, + regexMarkdown: /##(?[1-9][0-9]{0,1})d(?1[0-9]{1,8}|[2-9][0-9]{0,8})(?:(?[+-])(?[1-9][0-9]{0,8}))?=(?[1-9][0-9]{0,8})/gmi, + + prepare: (force) => (match, numdice, numsides, operator, modifier, value) => { + if (!force && value) { + return match; } - } - return `(${match}) Rolled ${numdice} dice with ${numsides} sides${modifier ? ' and modifier '+operator+modifier : '' } = ${sum}`; + + numdice = parseInt(numdice); + numsides = parseInt(numsides); + let matchWithoutValue = match.replace(/=.*/, ''); + + let sum = 0; + for (let i = 0; i < numdice; ++i) { + sum += Math.floor(Math.random() * numsides) + 1; + } + if (modifier && operator) { + modifier = parseInt(modifier); + //do i need to make sure it doesnt go negative or maybe give absolute value? + if (operator === '+') { + sum += modifier; + } else { + sum -= modifier; + } + } + return `${matchWithoutValue}=${sum}${value ? value : ''}`; + }, + + markdown: (match, numdice, numsides, operator, modifier, value) => { + numdice = parseInt(numdice); + numsides = parseInt(numsides); + value = parseInt(value); + let matchWithoutValue = match.replace(/=.*/, ''); + return `(${matchWithoutValue}) Rolled ${numdice} dice with ${numsides} sides${modifier ? ' and modifier '+operator+modifier : '' } = ${value}`; + }, } diff --git a/helpers/posting/markdown.js b/helpers/posting/markdown.js index 18a82332..d371ac4c 100644 --- a/helpers/posting/markdown.js +++ b/helpers/posting/markdown.js @@ -14,11 +14,11 @@ const greentextRegex = /^>((?!>\d+|>>/\w+(/\d*)?).*)/gm , codeRegex = /(?:(?[a-z+]{1,10})\r?\n)?(?[\s\S]+)/i , splitRegex = /```([\s\S]+?)```/gm , trimNewlineRegex = /^\s*(\r?\n)*|(\r?\n)*$/g - , diceRegex = /##(?[1-9][0-9]{0,8})d(?1[0-9]{1,8}|[2-9][0-9]{0,8})(?:(?[+-])(?[1-9][0-9]{0,8}))?/gmi , getDomain = (string) => string.split(/\/\/|\//)[1] //unused atm , escape = require(__dirname+'/escape.js') , { highlight, highlightAuto } = require('highlight.js') , { highlightOptions } = require(__dirname+'/../../configs/main.js') + , diceroll = require(__dirname+'/diceroll.js') , replacements = [ { regex: pinktextRegex, cb: (match, pinktext) => `<${pinktext}` }, { regex: greentextRegex, cb: (match, greentext) => `>${greentext}` }, @@ -31,11 +31,26 @@ const greentextRegex = /^>((?!>\d+|>>/\w+(/\d*)?).*)/gm { regex: monoRegex, cb: (match, mono) => `${mono}` }, { regex: linkRegex, cb: require(__dirname+'/linkmatch.js') }, { regex: detectedRegex, cb: (match, detected) => `${detected}` }, - { regex: diceRegex, cb: require(__dirname+'/diceroll.js') }, + { regex: diceroll.regexMarkdown, cb: diceroll.markdown }, ]; module.exports = { + prepareMarkdown: (text, force) => { + if (!text || text.length === 0) { + return text; + } + const chunks = text.split(splitRegex); + for (let i = 0; i < chunks.length; i++) { + //every other chunk will be a code block + if (i % 2 === 0) { + chunks[i] = chunks[i].replace( + diceroll.regexPrepare, diceroll.prepare(force)); + } + } + return chunks.join(''); + }, + markdown: (text) => { const chunks = text.split(splitRegex); for (let i = 0; i < chunks.length; i++) { diff --git a/models/forms/addnews.js b/models/forms/addnews.js index a1f5d4b4..1ccfb156 100644 --- a/models/forms/addnews.js +++ b/models/forms/addnews.js @@ -3,16 +3,18 @@ const { News } = require(__dirname+'/../../db/') , dynamicResponse = require(__dirname+'/../../helpers/dynamic.js') , buildQueue = require(__dirname+'/../../queue.js') + , { prepareMarkdown } = require(__dirname+'/../../helpers/posting/markdown.js') , messageHandler = require(__dirname+'/../../helpers/posting/message.js'); module.exports = async (req, res, next) => { - const { message: markdownNews } = await messageHandler(req.body.message, null, null); + const message = prepareMarkdown(req.body.message, false); + const { message: markdownNews } = await messageHandler(message, null, null); const post = { 'title': req.body.title, 'message': { - 'raw': req.body.message, + 'raw': message, 'markdown': markdownNews }, 'date': new Date(), diff --git a/models/forms/changeboardsettings.js b/models/forms/changeboardsettings.js index 72b9704d..d0df96be 100644 --- a/models/forms/changeboardsettings.js +++ b/models/forms/changeboardsettings.js @@ -7,6 +7,7 @@ const { Boards, Posts, Accounts } = require(__dirname+'/../../db/') , buildQueue = require(__dirname+'/../../queue.js') , { remove } = require('fs-extra') , deletePosts = require(__dirname+'/deletepost.js') + , { prepareMarkdown } = require(__dirname+'/../../helpers/posting/markdown.js') , messageHandler = require(__dirname+'/../../helpers/posting/message.js') , countryCodes = new Set(['??', 'AD','AE','AF','AG','AI','AL','AM','AO','AQ','AR','AS','AT','AU','AW','AX','AZ','BA','BB','BD','BE','BF','BG','BH','BI','BJ','BL','BM','BN','BO','BQ','BR','BS','BT','BV','BW','BY','BZ','CA','CC','CD','CF','CG','CH','CI','CK','CL','CM','CN','CO','CR','CU','CV','CW','CX','CY','CZ','DE','DJ','DK','DM','DO','DZ','EC','EE','EG','EH','ER','ES','ET','FI','FJ','FK','FM','FO','FR','GA','GB','GD','GE','GF','GG','GH','GI','GL','GM','GN','GP','GQ','GR','GS','GT','GU','GW','GY','HK','HM','HN','HR','HT','HU','ID','IE','IL','IM','IN','IO','IQ','IR','IS','IT','JE','JM','JO','JP','KE','KG','KH','KI','KM','KN','KP','KR','KW','KY','KZ','LA','LB','LC','LI','LK','LR','LS','LT','LU','LV','LY','MA','MC','MD','ME','MF','MG','MH','MK','ML','MM','MN','MO','MP','MQ','MR','MS','MT','MU','MV','MW','MX','MY','MZ','NA','NC','NE','NF','NG','NI','NL','NO','NP','NR','NU','NZ','OM','PA','PE','PF','PG','PH','PK','PL','PM','PN','PR','PS','PT','PW','PY','QA','RE','RO','RS','RU','RW','SA','SB','SC','SD','SE','SG','SH','SI','SJ','SK','SL','SM','SN','SO','SR','SS','ST','SV','SX','SY','SZ','TC','TD','TF','TG','TH','TJ','TK','TL','TM','TN','TO','TR','TT','TV','TW','TZ','UA','UG','UM','US','UY','UZ','VA','VC','VE','VG','VI','VN','VU','WF','WS','XK','YE','YT','ZA','ZM','ZW']) , trimSetting = (setting, oldSetting) => { @@ -30,9 +31,10 @@ module.exports = async (req, res, next) => { //array of promises we might need const promises = []; + const announcement = req.body.announcement === null ? null : prepareMarkdown(req.body.announcement, false); let markdownAnnouncement = oldSettings.announcement.markdown; - if (req.body.announcement !== oldSettings.announcement.raw) { - const { message } = await messageHandler(req.body.announcement, req.params.board, null); + if (announcement !== oldSettings.announcement.raw) { + const { message } = await messageHandler(announcement, req.params.board, null); markdownAnnouncement = message; //is there a destructure syntax for this? } @@ -113,7 +115,7 @@ module.exports = async (req, res, next) => { 'strictFiltering': booleanSetting(req.body.strict_filtering), 'customCss': globalLimits.customCss.enabled ? (req.body.custom_css !== null ? req.body.custom_css : oldSettings.customCss) : null, 'announcement': { - 'raw': req.body.announcement !== null ? req.body.announcement : oldSettings.announcement.raw, + 'raw': announcement !== null ? announcement : oldSettings.announcement.raw, 'markdown': req.body.announcement !== null ? markdownAnnouncement : oldSettings.announcement.markdown, }, 'allowedFileTypes': { diff --git a/models/forms/editpost.js b/models/forms/editpost.js index 850430c0..a0ce23ea 100644 --- a/models/forms/editpost.js +++ b/models/forms/editpost.js @@ -3,6 +3,7 @@ const { Posts, Bans, Modlogs } = require(__dirname+'/../../db/') , Mongo = require(__dirname+'/../../db/db.js') , getTripCode = require(__dirname+'/../../helpers/posting/tripcode.js') + , { prepareMarkdown } = require(__dirname+'/../../helpers/posting/markdown.js') , messageHandler = require(__dirname+'/../../helpers/posting/message.js') , nameHandler = require(__dirname+'/../../helpers/posting/name.js') , { previewReplies, strictFiltering } = require(__dirname+'/../../configs/main.js') @@ -75,7 +76,8 @@ todo: handle some more situations //new name, trip and cap const { name, tripcode, capcode } = await nameHandler(req.body.name, res.locals.permLevel, board.settings); //new message and quotes - const { message, quotes, crossquotes } = await messageHandler(req.body.message, req.body.board, post.thread); + const nomarkup = prepareMarkdown(req.body.message, false); + const { message, quotes, crossquotes } = await messageHandler(nomarkup, req.body.board, post.thread); //todo: email and subject (probably dont need any transformation since staff bypass limits on forceanon, and it doesnt have to account for sage/etc //intersection/difference of quotes sets for linking and unlinking @@ -125,6 +127,7 @@ todo: handle some more situations username: req.body.hide_name ? 'Hidden User' : req.session.user, date: new Date(), }, + nomarkup, message, quotes, crossquotes, diff --git a/models/forms/makepost.js b/models/forms/makepost.js index 06c2ea2d..0a517782 100644 --- a/models/forms/makepost.js +++ b/models/forms/makepost.js @@ -10,6 +10,7 @@ const path = require('path') , { Stats, Posts, Boards, Files, Bans } = require(__dirname+'/../../db/') , cache = require(__dirname+'/../../redis.js') , nameHandler = require(__dirname+'/../../helpers/posting/name.js') + , { prepareMarkdown } = require(__dirname+'/../../helpers/posting/markdown.js') , messageHandler = require(__dirname+'/../../helpers/posting/message.js') , moveUpload = require(__dirname+'/../../helpers/files/moveupload.js') , mimeTypes = require(__dirname+'/../../helpers/files/mimetypes.js') @@ -335,7 +336,8 @@ module.exports = async (req, res, next) => { //get name, trip and cap const { name, tripcode, capcode } = await nameHandler(req.body.name, res.locals.permLevel, res.locals.board.settings); //get message, quotes and crossquote array - const { message, quotes, crossquotes } = await messageHandler(req.body.message, req.params.board, req.body.thread); + const nomarkup = prepareMarkdown(req.body.message, true); + const { message, quotes, crossquotes } = await messageHandler(nomarkup, req.params.board, req.body.thread); //build post data for db const data = { @@ -347,7 +349,7 @@ module.exports = async (req, res, next) => { capcode, subject, 'message': message || null, - 'nomarkup': req.body.message || null, + 'nomarkup': nomarkup || null, 'thread': req.body.thread || null, password, email,