diff --git a/.gitignore b/.gitignore index f68d665bf8e..8d5cc726ac8 100644 --- a/.gitignore +++ b/.gitignore @@ -79,4 +79,6 @@ tests/end-to-end/temporary_staged_test .screenshots /private/livechat /storybook-static -/tests/cypress/screenshots \ No newline at end of file +/tests/cypress/screenshots +coverage +.nyc_output diff --git a/.meteorignore b/.meteorignore index 35dd55fee16..6453c2f01e3 100644 --- a/.meteorignore +++ b/.meteorignore @@ -1 +1,2 @@ ee/server/services +coverage diff --git a/app/oembed/server/jumpToMessage.js b/app/oembed/server/jumpToMessage.js index 4c14414f339..961fbb656aa 100644 --- a/app/oembed/server/jumpToMessage.js +++ b/app/oembed/server/jumpToMessage.js @@ -4,10 +4,11 @@ import QueryString from 'querystring'; import { Meteor } from 'meteor/meteor'; import _ from 'underscore'; -import { Messages } from '../../models'; -import { settings } from '../../settings'; -import { callbacks } from '../../callbacks'; +import { Messages, Rooms, Users } from '../../models/server'; +import { settings } from '../../settings/server'; +import { callbacks } from '../../callbacks/server'; import { getUserAvatarURL } from '../../utils/lib/getUserAvatarURL'; +import { canAccessRoom } from '../../authorization/server/functions/canAccessRoom'; const recursiveRemove = (message, deep = 1) => { if (message) { @@ -21,37 +22,62 @@ const recursiveRemove = (message, deep = 1) => { }; callbacks.add('beforeSaveMessage', (msg) => { - if (msg && msg.urls) { - msg.urls.forEach((item) => { - if (item.url.indexOf(Meteor.absoluteUrl()) === 0) { - const urlObj = URL.parse(item.url); - if (urlObj.query) { - const queryString = QueryString.parse(urlObj.query); - if (_.isString(queryString.msg)) { // Jump-to query param - const jumpToMessage = recursiveRemove(Messages.findOneById(queryString.msg)); - if (jumpToMessage) { - msg.attachments = msg.attachments || []; - - const index = msg.attachments.findIndex((a) => a.message_link === item.url); - if (index > -1) { - msg.attachments.splice(index, 1); - } - - msg.attachments.push({ - text: jumpToMessage.msg, - translations: jumpToMessage.translations, - author_name: jumpToMessage.alias || jumpToMessage.u.username, - author_icon: getUserAvatarURL(jumpToMessage.u.username), - message_link: item.url, - attachments: jumpToMessage.attachments || [], - ts: jumpToMessage.ts, - }); - item.ignoreParse = true; - } - } - } - } - }); + // if no message is present, or the message doesn't have any URL, skip + if (!msg || (!msg.urls || !msg.urls.length)) { + return msg; } + + const currentUser = Users.findOneById(msg.u._id); + + msg.urls.forEach((item) => { + // if the URL is not internal, skip + if (!item.url.includes(Meteor.absoluteUrl())) { + return; + } + + const urlObj = URL.parse(item.url); + + // if the URL doesn't have query params (doesn't reference message) skip + if (!urlObj.query) { + return; + } + + const { msg: msgId } = QueryString.parse(urlObj.query); + + if (!_.isString(msgId)) { + return; + } + + const jumpToMessage = recursiveRemove(Messages.findOneById(msgId)); + if (!jumpToMessage) { + return; + } + + // validates if user can see the message + // user has to belong to the room the message was first wrote in + const room = Rooms.findOneById(jumpToMessage.rid); + const canAccessRoomForUser = canAccessRoom(room, currentUser); + if (!canAccessRoomForUser) { + return; + } + + msg.attachments = msg.attachments || []; + const index = msg.attachments.findIndex((a) => a.message_link === item.url); + if (index > -1) { + msg.attachments.splice(index, 1); + } + + msg.attachments.push({ + text: jumpToMessage.msg, + translations: jumpToMessage.translations, + author_name: jumpToMessage.alias || jumpToMessage.u.username, + author_icon: getUserAvatarURL(jumpToMessage.u.username), + message_link: item.url, + attachments: jumpToMessage.attachments || [], + ts: jumpToMessage.ts, + }); + item.ignoreParse = true; + }); + return msg; }, callbacks.priority.LOW, 'jumpToMessage');