[FIX] mention-links not being always resolved (#11745)

pull/12952/head^2
Oliver Jägle 6 years ago committed by Guilherme Gazzo
parent b16fe93334
commit 8f40051d9b
  1. 13
      client/routes/roomRoute.js
  2. 4
      packages/rocketchat-mentions/lib/Mentions.js
  3. 2
      packages/rocketchat-mentions/server/server.js
  4. 18
      packages/rocketchat-mentions/tests/client.tests.js
  5. 10
      packages/rocketchat-ui/client/views/app/room.js
  6. 40
      server/methods/getRoomById.js

@ -1,10 +1,17 @@
import { FlowRouter } from 'meteor/kadira:flow-router';
import { ChatSubscription } from 'meteor/rocketchat:models';
import { roomTypes } from 'meteor/rocketchat:utils';
import { call } from 'meteor/rocketchat:ui-utils';
FlowRouter.goToRoomById = (roomId) => {
const subscription = ChatSubscription.findOne({ rid: roomId });
FlowRouter.goToRoomById = async(rid) => {
if (!rid) {
return;
}
const subscription = ChatSubscription.findOne({ rid });
if (subscription) {
roomTypes.openRouteLink(subscription.t, subscription, FlowRouter.current().queryParams);
return roomTypes.openRouteLink(subscription.t, subscription, FlowRouter.current().queryParams);
}
const room = await call('getRoomById', rid);
return roomTypes.openRouteLink(room.t, room, FlowRouter.current().queryParams);
};

@ -55,7 +55,9 @@ export default class {
return match;
}
return `${ prefix }<a class="mention-link" data-channel="${ name }">${ `#${ name }` }</a>`;
const channel = message.channels && message.channels.find((c) => c.name === name);
const roomNameorId = channel ? channel._id : name;
return `${ prefix }<a class="mention-link" data-channel="${ roomNameorId }">${ `#${ name }` }</a>`;
});
}
getUserMentions(str) {

@ -14,7 +14,7 @@ const mention = new MentionsServer({
getUsers: (usernames) => Meteor.users.find({ username: { $in: _.unique(usernames) } }, { fields: { _id: true, username: true, name: 1 } }).fetch(),
getUser: (userId) => Users.findOneById(userId),
getTotalChannelMembers: (rid) => Subscriptions.findByRoomId(rid).count(),
getChannels: (channels) => Rooms.find({ name: { $in: _.unique(channels) }, t: 'c' }, { fields: { _id: 1, name: 1 } }).fetch(),
getChannels: (channels) => Rooms.find({ name: { $in: _.unique(channels) }, t: { $in: ['c', 'p'] } }, { fields: { _id: 1, name: 1 } }).fetch(),
onMaxRoomMembersExceeded({ sender, rid }) {
// Get the language of the user for the error notification.
const { language } = this.getUser(sender._id);

@ -183,8 +183,8 @@ describe('Mention', function() {
});
const message = {
mentions:[{ username:'rocket.cat', name: 'Rocket.Cat' }, { username:'admin', name: 'Admin' }, { username: 'me', name: 'Me' }, { username: 'specialchars', name:'<img onerror=alert(hello)>' }],
channels: [{ name: 'general' }, { name: 'rocket.cat' }],
mentions: [{ username: 'rocket.cat', name: 'Rocket.Cat' }, { username: 'admin', name: 'Admin' }, { username: 'me', name: 'Me' }, { username: 'specialchars', name: '<img onerror=alert(hello)>' }],
channels: [{ name: 'general', _id: '42' }, { name: 'rocket.cat', _id: '169' }],
};
describe('replace methods', function() {
describe('replaceUsers', () => {
@ -260,16 +260,16 @@ describe('replace methods', function() {
describe('replaceChannels', () => {
it('should render for #general', () => {
const result = mention.replaceChannels('#general', message);
assert.equal('<a class="mention-link" data-channel="general">#general</a>', result);
assert.equal('<a class="mention-link" data-channel="42">#general</a>', result);
});
const str2 = '#rocket.cat';
it(`should render for ${ str2 }`, () => {
const result = mention.replaceChannels(str2, message);
assert.equal(result, `<a class="mention-link" data-channel="${ str2.replace('#', '') }">${ str2 }</a>`);
assert.equal(result, `<a class="mention-link" data-channel="169">${ str2 }</a>`);
});
it(`should render for "hello ${ str2 }"`, () => {
const result = mention.replaceChannels(`hello ${ str2 }`, message);
assert.equal(result, `hello <a class="mention-link" data-channel="${ str2.replace('#', '') }">${ str2 }</a>`);
assert.equal(result, `hello <a class="mention-link" data-channel="169">${ str2 }</a>`);
});
it('should render for unknow/private channel "hello #unknow"', () => {
const result = mention.replaceChannels('hello #unknow', message);
@ -281,12 +281,12 @@ describe('replace methods', function() {
it('should render for #general', () => {
message.html = '#general';
const result = mention.parse(message, 'me');
assert.equal('<a class="mention-link" data-channel="general">#general</a>', result.html);
assert.equal('<a class="mention-link" data-channel="42">#general</a>', result.html);
});
it('should render for "#general and @rocket.cat', () => {
message.html = '#general and @rocket.cat';
const result = mention.parse(message, 'me');
assert.equal('<a class="mention-link" data-channel="general">#general</a> and <a class="mention-link " data-username="rocket.cat" title="">@rocket.cat</a>', result.html);
assert.equal('<a class="mention-link" data-channel="42">#general</a> and <a class="mention-link " data-username="rocket.cat" title="">@rocket.cat</a>', result.html);
});
it('should render for "', () => {
message.html = '';
@ -307,12 +307,12 @@ describe('replace methods', function() {
it('should render for #general', () => {
message.html = '#general';
const result = mention.parse(message, 'me');
assert.equal('<a class="mention-link" data-channel="general">#general</a>', result.html);
assert.equal('<a class="mention-link" data-channel="42">#general</a>', result.html);
});
it('should render for "#general and @rocket.cat', () => {
message.html = '#general and @rocket.cat';
const result = mention.parse(message, 'me');
assert.equal('<a class="mention-link" data-channel="general">#general</a> and <a class="mention-link " data-username="rocket.cat" title="rocket.cat">Rocket.Cat</a>', result.html);
assert.equal('<a class="mention-link" data-channel="42">#general</a> and <a class="mention-link " data-username="rocket.cat" title="rocket.cat">Rocket.Cat</a>', result.html);
});
it('should render for "', () => {
message.html = '';

@ -713,16 +713,14 @@ Template.room.events({
if (!Meteor.userId()) {
return;
}
const channel = $(e.currentTarget).data('channel');
if (channel != null) {
const roomNameOrId = $(e.currentTarget).data('channel');
if (roomNameOrId) {
if (Layout.isEmbedded()) {
fireGlobalEvent('click-mention-link', { path: FlowRouter.path('channel', { name: channel }), channel });
fireGlobalEvent('click-mention-link', { path: FlowRouter.path('channel', { name: roomNameOrId }), channel: roomNameOrId });
}
FlowRouter.go('channel', { name: channel }, FlowRouter.current().queryParams);
FlowRouter.goToRoomById(roomNameOrId);
return;
}
const username = $(e.currentTarget).data('username');
openProfileTabOrOpenDM(e, instance, username);

@ -0,0 +1,40 @@
import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';
import { DDPRateLimiter } from 'meteor/ddp-rate-limiter';
import { Rooms } from 'meteor/rocketchat:models';
import { canAccessRoom } from 'meteor/rocketchat:authorization';
Meteor.methods({
getRoomById(rid) {
check(rid, String);
const userId = Meteor.userId();
if (!userId) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', {
method: 'getRoomNameById',
});
}
const room = Rooms.findOneById(rid);
if (room == null) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', {
method: 'getRoomNameById',
});
}
if (!canAccessRoom(room, Meteor.user())) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', {
method: 'getRoomById',
});
}
return room;
},
});
DDPRateLimiter.addRule({
type: 'method',
name: 'getRoomById',
userId() {
return true;
},
}, 1, 60000);
Loading…
Cancel
Save