From 24a338ced5f8d0af41dd5d7c5727c2fbdb5722c8 Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Thu, 27 May 2021 18:38:21 -0300 Subject: [PATCH 1/2] [FIX] Discussion names showing a random value (#22172) --- app/lib/server/functions/createRoom.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/server/functions/createRoom.js b/app/lib/server/functions/createRoom.js index 56f1676ad633..f97ef5195aa8 100644 --- a/app/lib/server/functions/createRoom.js +++ b/app/lib/server/functions/createRoom.js @@ -51,9 +51,9 @@ export const createRoom = function(type, name, owner, members = [], readOnly, { } let room = { + fname: name, ...extraData, name: getValidRoomName(name, null, validRoomNameOptions), - fname: name, t: type, msgs: 0, usersCount: 0, From 69dddb36ddbdb4033f1164c5b5aa231ee0613257 Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Thu, 27 May 2021 23:25:09 -0300 Subject: [PATCH 2/2] Bump version to 3.13.5 --- .docker/Dockerfile.rhel | 2 +- .github/history-manual.json | 7 +++ .github/history.json | 32 +++++++++++++ .snapcraft/resources/prepareRocketChat | 2 +- .snapcraft/snap/snapcraft.yaml | 2 +- HISTORY.md | 21 +++++++++ app/markdown/lib/parser/original/code.js | 38 ++++++--------- app/markdown/lib/parser/original/markdown.js | 31 ++++++------- app/markdown/lib/parser/original/token.ts | 49 ++++++++++++++++++++ app/markdown/tests/client.mocks.js | 2 +- app/utils/rocketchat.info | 2 +- package-lock.json | 2 +- package.json | 2 +- 13 files changed, 142 insertions(+), 50 deletions(-) create mode 100644 app/markdown/lib/parser/original/token.ts diff --git a/.docker/Dockerfile.rhel b/.docker/Dockerfile.rhel index 387f224c4159..5612289ac226 100644 --- a/.docker/Dockerfile.rhel +++ b/.docker/Dockerfile.rhel @@ -1,6 +1,6 @@ FROM registry.access.redhat.com/ubi8/nodejs-12 -ENV RC_VERSION 3.13.4 +ENV RC_VERSION 3.13.5 MAINTAINER buildmaster@rocket.chat diff --git a/.github/history-manual.json b/.github/history-manual.json index 7bde41a70d4e..aef53bd3b916 100644 --- a/.github/history-manual.json +++ b/.github/history-manual.json @@ -97,5 +97,12 @@ "KevLehman", "g-thome" ] + }], + "3.13.5": [{ + "title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)", + "userLogin": "ggazzo", + "contributors": [ + "ggazzo" + ] }] } diff --git a/.github/history.json b/.github/history.json index a14d732684c4..9ebc5f28eefe 100644 --- a/.github/history.json +++ b/.github/history.json @@ -58363,6 +58363,38 @@ ] } ] + }, + "3.12.6": { + "node_version": "12.18.4", + "npm_version": "6.14.8", + "apps_engine_version": "1.23.0", + "mongo_versions": [ + "3.4", + "3.6", + "4.0" + ], + "pull_requests": [] + }, + "3.13.5": { + "node_version": "12.21.0", + "npm_version": "6.14.8", + "apps_engine_version": "1.24.1", + "mongo_versions": [ + "3.4", + "3.6", + "4.0" + ], + "pull_requests": [ + { + "pr": "22172", + "title": "[FIX] Discussion names showing a random value", + "userLogin": "sampaiodiego", + "milestone": "3.14.4", + "contributors": [ + "sampaiodiego" + ] + } + ] } } } \ No newline at end of file diff --git a/.snapcraft/resources/prepareRocketChat b/.snapcraft/resources/prepareRocketChat index 68f42f30d8d5..b0cbc7eff930 100755 --- a/.snapcraft/resources/prepareRocketChat +++ b/.snapcraft/resources/prepareRocketChat @@ -1,6 +1,6 @@ #!/bin/bash -curl -SLf "https://releases.rocket.chat/3.13.4/download/" -o rocket.chat.tgz +curl -SLf "https://releases.rocket.chat/3.13.5/download/" -o rocket.chat.tgz tar xf rocket.chat.tgz --strip 1 diff --git a/.snapcraft/snap/snapcraft.yaml b/.snapcraft/snap/snapcraft.yaml index 37ca45bc8c95..2adaf565b37d 100644 --- a/.snapcraft/snap/snapcraft.yaml +++ b/.snapcraft/snap/snapcraft.yaml @@ -7,7 +7,7 @@ # 5. `snapcraft snap` name: rocketchat-server -version: 3.13.4 +version: 3.13.5 summary: Rocket.Chat server description: Have your own Slack like online chat, built with Meteor. https://rocket.chat/ confinement: strict diff --git a/HISTORY.md b/HISTORY.md index 1eaa5dcc8b99..abce936b0da8 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,4 +1,25 @@ +# 3.13.5 +`2021-05-27 ยท 2 ๐Ÿ› ยท 2 ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป` + +### Engine versions +- Node: `12.21.0` +- NPM: `6.14.8` +- MongoDB: `3.4, 3.6, 4.0` +- Apps-Engine: `1.24.1` + +### ๐Ÿ› Bug fixes + + +- Discussion names showing a random value ([#22172](https://github.com/RocketChat/Rocket.Chat/pull/22172)) + +- Security Hotfix (https://docs.rocket.chat/guides/security/security-updates) + +### ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป Core Team ๐Ÿค“ + +- [@ggazzo](https://github.com/ggazzo) +- [@sampaiodiego](https://github.com/sampaiodiego) + # 3.13.4 `2021-05-25 ยท 1 ๐Ÿ› ยท 1 ๐Ÿ” ยท 4 ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป` diff --git a/app/markdown/lib/parser/original/code.js b/app/markdown/lib/parser/original/code.js index 95068e045226..18607e7982b4 100644 --- a/app/markdown/lib/parser/original/code.js +++ b/app/markdown/lib/parser/original/code.js @@ -2,29 +2,21 @@ * code() is a named function that will parse `inline code` and ```codeblock``` syntaxes * @param {Object} message - The message object */ -import { Random } from 'meteor/random'; import { unescapeHTML } from '../../../../../lib/unescapeHTML'; import hljs from '../../hljs'; +import { addAsToken } from './token'; const inlinecode = (message) => { // Support `text` - message.html = message.html.replace(/\`([^`\r\n]+)\`([<_*~]|\B|\b|$)/gm, (match, p1, p2) => { - const token = `=!=${ Random.id() }=!=`; - - message.tokens.push({ - token, - text: `\`${ p1 }\`${ p2 }`, - noHtml: match, - }); - - return token; - }); + message.html = message.html.replace(/\`([^`\r\n]+)\`([<_*~]|\B|\b|$)/gm, (match, p1, p2) => + addAsToken(message, `\`${ p1 }\`${ p2 }`, 'inlinecode', { noHtml: match }), + ); }; const codeblocks = (message) => { // Count occurencies of ``` - const count = (message.html.match(/```/g) || []).length; + const count = (message.html.match(/```/gm) || []).length; if (count) { // Check if we need to add a final ``` @@ -49,14 +41,14 @@ const codeblocks = (message) => { const code = singleLine ? unescapeHTML(codeMatch[1]) : emptyLanguage; const result = lang === '' ? hljs.highlightAuto(lang + code) : hljs.highlight(lang, code); - const token = `=!=${ Random.id() }=!=`; - - message.tokens.push({ - highlight: true, - token, - text: `
\`\`\`
${ result.value }
\`\`\`
`, - noHtml: codeMatch[0], - }); + const token = addAsToken( + message, + `
\`\`\`
${ result.value }
\`\`\`
`, + 'code', + { + noHtml: codeMatch[0], + highlight: true, + }); msgParts[index] = token; } else { @@ -71,10 +63,6 @@ const codeblocks = (message) => { export const code = (message) => { if (message.html?.trim()) { - if (!message.tokens) { - message.tokens = []; - } - codeblocks(message); inlinecode(message); } diff --git a/app/markdown/lib/parser/original/markdown.js b/app/markdown/lib/parser/original/markdown.js index 637037ac57d6..f20f3211fda7 100644 --- a/app/markdown/lib/parser/original/markdown.js +++ b/app/markdown/lib/parser/original/markdown.js @@ -1,18 +1,4 @@ -/* - * Markdown is a named function that will parse markdown syntax - * @param {String} msg - The message html - */ -import { Random } from 'meteor/random'; - -const addAsToken = (message, html) => { - const token = `=!=${ Random.id() }=!=`; - message.tokens.push({ - token, - text: html, - }); - - return token; -}; +import { addAsToken, isToken, validateAllowedTokens } from './token'; const validateUrl = (url, message) => { // Don't render markdown inside links @@ -89,10 +75,13 @@ const parseNotEscaped = (message, { if (!validateUrl(url, message)) { return match; } + if (isToken(title) && !validateAllowedTokens(message, title, ['bold', 'italic', 'strike'])) { + return match; + } url = encodeURI(url); const target = url.indexOf(rootUrl) === 0 ? '' : '_blank'; - return addAsToken(message, `
`); + return addAsToken(message, `
`, 'link'); }); // Support [Text](http://link) @@ -100,12 +89,15 @@ const parseNotEscaped = (message, { if (!validateUrl(url, message)) { return match; } + if (isToken(title) && !validateAllowedTokens(message, title, ['bold', 'italic', 'strike'])) { + return match; + } const target = url.indexOf(rootUrl) === 0 ? '' : '_blank'; title = title.replace(/&/g, '&'); const escapedUrl = encodeURI(url); - return addAsToken(message, `${ title }`); + return addAsToken(message, `${ title }`, 'link'); }); // Support @@ -113,9 +105,12 @@ const parseNotEscaped = (message, { if (!validateUrl(url, message)) { return match; } + if (isToken(title) && !validateAllowedTokens(message, title, ['bold', 'italic', 'strike'])) { + return match; + } url = encodeURI(url); const target = url.indexOf(rootUrl) === 0 ? '' : '_blank'; - return addAsToken(message, `${ title }`); + return addAsToken(message, `${ title }`, 'link'); }); return msg; }; diff --git a/app/markdown/lib/parser/original/token.ts b/app/markdown/lib/parser/original/token.ts new file mode 100644 index 000000000000..fdc29ba7b830 --- /dev/null +++ b/app/markdown/lib/parser/original/token.ts @@ -0,0 +1,49 @@ +/* + * Markdown is a named function that will parse markdown syntax + * @param {String} msg - The message html + */ +import { Random } from 'meteor/random'; + +import { IMessage } from '../../../../../definition/IMessage'; + +type TokenType = 'code'| 'inlinecode' | 'bold' | 'italic' | 'strike' | 'link'; +type Token = { + token: string; + type: TokenType; + text: string; + noHtml?: string; +} & TokenExtra; + +type TokenExtra = { + highlight?: boolean; + noHtml?: string; +} + +export const addAsToken = (message: IMessage & { tokens: Token[] }, html: string, type: TokenType, extra?: TokenExtra): string => { + if (!message.tokens) { + message.tokens = []; + } + const token = `=!=${ Random.id() }=!=`; + message.tokens.push({ + token, + type, + text: html, + ...extra && { ...extra }, + }); + + return token; +}; + +export const isToken = (msg: string): boolean => /=!=[.a-z0-9]{17}=!=/igm.test(msg.trim()); + +export const validateAllowedTokens = (message: IMessage & { tokens: Token[] }, id: string, desiredTokens: TokenType[]): boolean => { + const tokens = id.match(/=!=[.a-z0-9]{17}=!=/igm) || []; + const tokensFound = message.tokens.filter(({ token }) => tokens.includes(token)); + return tokensFound.length === 0 || tokensFound.every((token) => desiredTokens.includes(token.type)); +}; + +export const validateForbiddenTokens = (message: IMessage & { tokens: Token[] }, id: string, desiredTokens: TokenType[]): boolean => { + const tokens = id.match(/=!=[.a-z0-9]{17}=!=/igm) || []; + const tokensFound = message.tokens.filter(({ token }) => tokens.includes(token)); + return tokensFound.length === 0 || !tokensFound.some((token) => desiredTokens.includes(token.type)); +}; diff --git a/app/markdown/tests/client.mocks.js b/app/markdown/tests/client.mocks.js index 8efae2090e44..21253de93915 100644 --- a/app/markdown/tests/client.mocks.js +++ b/app/markdown/tests/client.mocks.js @@ -55,7 +55,7 @@ mock('../../callbacks', { mock('meteor/random', { Random: { id() { - return Math.random(); + return Math.random().toString().replace('0.', 'A'); }, }, }); diff --git a/app/utils/rocketchat.info b/app/utils/rocketchat.info index 95d0a3ea11d3..6df3f900aa6b 100644 --- a/app/utils/rocketchat.info +++ b/app/utils/rocketchat.info @@ -1,3 +1,3 @@ { - "version": "3.13.4" + "version": "3.13.5" } diff --git a/package-lock.json b/package-lock.json index c7df69e28453..4e47f440628f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "Rocket.Chat", - "version": "3.13.4", + "version": "3.13.5", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index af6adf5eae96..6c838fdb57f0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "Rocket.Chat", "description": "The Ultimate Open Source WebChat Platform", - "version": "3.13.4", + "version": "3.13.5", "author": { "name": "Rocket.Chat", "url": "https://rocket.chat/"