[FIX] Updating a message causing URLs to be parsed even within markdown code (#21489)

pull/21586/head
Kevin Aleman 4 years ago committed by GitHub
parent 7f2d924743
commit f05b07c720
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 22
      app/lib/server/functions/parseUrlsInMessage.js
  2. 17
      app/lib/server/functions/sendMessage.js
  3. 4
      app/lib/server/functions/updateMessage.js
  4. 198
      tests/end-to-end/api/24-methods.js

@ -0,0 +1,22 @@
import { Markdown } from '../../../markdown/server';
export const parseUrlsInMessage = (message) => {
if (message.parseUrls === false) {
return message;
}
message.html = message.msg;
message = Markdown.code(message);
const urls = message.html.match(/([A-Za-z]{3,9}):\/\/([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((\/[-\+=!:~%\/\.@\,\w]*)?\??([-\+=&!:;%@\/\.\,\w]+)?(?:#([^\s\)]+))?)?/g) || [];
if (urls) {
message.urls = urls.map((url) => ({ url }));
}
message = Markdown.mountTokensBack(message, false);
message.msg = message.html;
delete message.html;
delete message.tokens;
return message;
};

@ -4,9 +4,9 @@ import { settings } from '../../../settings';
import { callbacks } from '../../../callbacks';
import { Messages } from '../../../models';
import { Apps } from '../../../apps/server';
import { Markdown } from '../../../markdown/server';
import { isURL, isRelativeURL } from '../../../utils/lib/isURL';
import { FileUpload } from '../../../file-upload/server';
import { parseUrlsInMessage } from './parseUrlsInMessage';
/**
* IMPORTANT
@ -203,20 +203,7 @@ export const sendMessage = function(user, message, room, upsert = false) {
}
}
if (message.parseUrls !== false) {
message.html = message.msg;
message = Markdown.code(message);
const urls = message.html.match(/([A-Za-z]{3,9}):\/\/([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((\/[-\+=!:~%\/\.@\,\(\)\w]*)?\??([-\+=&!:;%@\/\.\,\w]+)?(?:#([^\s\)]+))?)?/g);
if (urls) {
message.urls = urls.map((url) => ({ url }));
}
message = Markdown.mountTokensBack(message, false);
message.msg = message.html;
delete message.html;
delete message.tokens;
}
parseUrlsInMessage(message);
message = callbacks.run('beforeSaveMessage', message, room);
if (message) {

@ -4,6 +4,7 @@ import { Messages, Rooms } from '../../../models';
import { settings } from '../../../settings';
import { callbacks } from '../../../callbacks';
import { Apps } from '../../../apps/server';
import { parseUrlsInMessage } from './parseUrlsInMessage';
export const updateMessage = function(message, user, originalMessage) {
if (!originalMessage) {
@ -39,8 +40,7 @@ export const updateMessage = function(message, user, originalMessage) {
username: user.username,
};
const urls = message.msg.match(/([A-Za-z]{3,9}):\/\/([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((\/[-\+=!:~%\/\.@\,\w]*)?\??([-\+=&!:;%@\/\.\,\w]+)?(?:#([^\s\)]+))?)?/g) || [];
message.urls = urls.map((url) => ({ url }));
parseUrlsInMessage(message);
message = callbacks.run('beforeSaveMessage', message);

@ -3,7 +3,6 @@ import { expect } from 'chai';
import { getCredentials, request, methodCall, api, credentials } from '../../data/api-data.js';
import { updatePermission } from '../../data/permissions.helper.js';
describe('Meteor.methods', function() {
this.retries(0);
@ -1283,4 +1282,201 @@ describe('Meteor.methods', function() {
.end(done);
});
});
describe('[@sendMessage]', () => {
let rid = false;
let channelName = false;
before('create room', (done) => {
channelName = `methods-test-channel-${ Date.now() }`;
request.post(api('groups.create'))
.set(credentials)
.send({
name: channelName,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.nested.property('group._id');
expect(res.body).to.have.nested.property('group.name', channelName);
expect(res.body).to.have.nested.property('group.t', 'p');
expect(res.body).to.have.nested.property('group.msgs', 0);
rid = res.body.group._id;
})
.end(done);
});
it('should send a message', (done) => {
request.post(methodCall('sendMessage'))
.set(credentials)
.send({
message: JSON.stringify({
method: 'sendMessage',
params: [{ _id: `${ Date.now() + Math.random() }`, rid, msg: 'test message' }],
id: 1000,
}),
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.a.property('success', true);
expect(res.body).to.have.a.property('message').that.is.a('string');
const data = JSON.parse(res.body.message);
expect(data).to.have.a.property('result').that.is.an('object');
expect(data.result.msg).to.equal('test message');
})
.end(done);
});
it('should parse correctly urls sent in message', (done) => {
request.post(methodCall('sendMessage'))
.set(credentials)
.send({
message: JSON.stringify({
method: 'sendMessage',
params: [{ _id: `${ Date.now() + Math.random() }`, rid, msg: 'test message with https://github.com' }],
}),
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.a.property('success', true);
expect(res.body).to.have.a.property('message').that.is.a('string');
const data = JSON.parse(res.body.message);
expect(data).to.have.a.property('result').that.is.an('object');
expect(data.result).to.have.a.property('urls').that.is.an('array');
expect(data.result.urls[0].url).to.equal('https://github.com');
})
.end(done);
});
});
describe('[@updateMessage]', () => {
let rid = false;
let messageId;
let messageWithMarkdownId;
let channelName = false;
before('create room', (done) => {
channelName = `methods-test-channel-${ Date.now() }`;
request.post(api('groups.create'))
.set(credentials)
.send({
name: channelName,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.nested.property('group._id');
expect(res.body).to.have.nested.property('group.name', channelName);
expect(res.body).to.have.nested.property('group.t', 'p');
expect(res.body).to.have.nested.property('group.msgs', 0);
rid = res.body.group._id;
})
.end(done);
});
before('send message with URL', (done) => {
request.post(methodCall('sendMessage'))
.set(credentials)
.send({
message: JSON.stringify({
method: 'sendMessage',
params: [{ _id: `${ Date.now() + Math.random() }`, rid, msg: 'test message with https://github.com' }],
}),
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.a.property('success', true);
expect(res.body).to.have.a.property('message').that.is.a('string');
const data = JSON.parse(res.body.message);
expect(data).to.have.a.property('result').that.is.an('object');
expect(data.result).to.have.a.property('urls').that.is.an('array');
expect(data.result.urls[0].url).to.equal('https://github.com');
messageId = data.result._id;
})
.end(done);
});
before('send message with URL inside markdown', (done) => {
request.post(methodCall('sendMessage'))
.set(credentials)
.send({
message: JSON.stringify({
method: 'sendMessage',
params: [{ _id: `${ Date.now() + Math.random() }`, rid, msg: 'test message with ```https://github.com```' }],
}),
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.a.property('success', true);
expect(res.body).to.have.a.property('message').that.is.a('string');
const data = JSON.parse(res.body.message);
expect(data).to.have.a.property('result').that.is.an('object');
messageWithMarkdownId = data.result._id;
})
.end(done);
});
it('should update a message with a URL', (done) => {
request.post(methodCall('updateMessage'))
.set(credentials)
.send({
message: JSON.stringify({
method: 'updateMessage',
params: [{ _id: messageId, rid, msg: 'https://github.com updated' }],
}),
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.a.property('success', true);
expect(res.body).to.have.a.property('message').that.is.a('string');
const data = JSON.parse(res.body.message);
expect(data).to.have.a.property('msg').that.is.an('string');
})
.end(done);
});
it('should not parse URLs inside markdown on update', (done) => {
request.post(methodCall('updateMessage'))
.set(credentials)
.send({
message: JSON.stringify({
method: 'updateMessage',
params: [{ _id: messageWithMarkdownId, rid, msg: 'test message with ```https://github.com``` updated' }],
}),
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.a.property('success', true);
expect(res.body).to.have.a.property('message').that.is.a('string');
const data = JSON.parse(res.body.message);
expect(data).to.have.a.property('msg').that.is.an('string');
})
.then(() => {
request.get(api(`chat.getMessage?msgId=${ messageWithMarkdownId }`))
.set(credentials)
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('message').that.is.an('object');
expect(res.body.message.msg).to.equal('test message with ```https://github.com``` updated');
expect(res.body.message).to.have.property('urls');
expect(res.body.message.urls.length).to.be.equal(0);
})
.end(done);
});
});
});
});

Loading…
Cancel
Save