Skip to content

Commit

Permalink
fix: user highlights matching just part of words (#33776)
Browse files Browse the repository at this point in the history
  • Loading branch information
sampaiodiego authored Oct 28, 2024
1 parent 4c4c145 commit f79f3cc
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 30 deletions.
5 changes: 5 additions & 0 deletions .changeset/clean-flies-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fix user highlights not matching only whole words
19 changes: 0 additions & 19 deletions apps/meteor/app/lib/server/functions/notifications/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,3 @@ export function replaceMentionedUsernamesWithFullNames(message: string, mentions
});
return message;
}

/**
* Checks if a message contains a user highlight
*
* @param {string} message
* @param {array|undefined} highlights
*
* @returns {boolean}
*/
export function messageContainsHighlight(message: Pick<IMessage, 'msg'>, highlights: string[] | undefined): boolean {
if (!highlights || highlights.length === 0) {
return false;
}

return highlights.some((highlight: string) => {
const regexp = new RegExp(escapeRegExp(highlight), 'i');
return regexp.test(message.msg);
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { IMessage } from '@rocket.chat/core-typings';
import { escapeRegExp } from '@rocket.chat/string-helpers';

/**
* Checks if a message contains a user highlight
*
* @param {string} message
* @param {array|undefined} highlights
*
* @returns {boolean}
*/
export function messageContainsHighlight(message: Pick<IMessage, 'msg'>, highlights: string[] | undefined): boolean {
if (!highlights || highlights.length === 0) {
return false;
}

return highlights.some((highlight: string) => {
const hl = escapeRegExp(highlight);
const regexp = new RegExp(`(?<!:)\\b${hl}\\b:|:\\b${hl}(?!:)\\b|\\b(?<!:)${hl}(?!:)\\b`, 'i');
return regexp.test(message.msg);
});
}
11 changes: 1 addition & 10 deletions apps/meteor/app/lib/server/lib/notifyUsersOnMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,17 @@ import type { IMessage, IRoom, IUser, RoomType } from '@rocket.chat/core-typings
import { isEditedMessage } from '@rocket.chat/core-typings';
import type { Updater } from '@rocket.chat/models';
import { Subscriptions, Rooms } from '@rocket.chat/models';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import moment from 'moment';

import { callbacks } from '../../../../lib/callbacks';
import { settings } from '../../../settings/server';
import { messageContainsHighlight } from '../functions/notifications/messageContainsHighlight';
import {
notifyOnSubscriptionChanged,
notifyOnSubscriptionChangedByRoomIdAndUserId,
notifyOnSubscriptionChangedByRoomIdAndUserIds,
} from './notifyListener';

function messageContainsHighlight(message: IMessage, highlights: string[]): boolean {
if (!highlights || highlights.length === 0) return false;

return highlights.some((highlight: string) => {
const regexp = new RegExp(escapeRegExp(highlight), 'i');
return regexp.test(message.msg);
});
}

export async function getMentions(message: IMessage): Promise<{ toAll: boolean; toHere: boolean; mentionIds: string[] }> {
const {
mentions,
Expand Down
3 changes: 2 additions & 1 deletion apps/meteor/app/lib/server/lib/sendNotificationsOnMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ import { roomCoordinator } from '../../../../server/lib/rooms/roomCoordinator';
import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
import { Notification } from '../../../notification-queue/server/NotificationQueue';
import { settings } from '../../../settings/server';
import { messageContainsHighlight, parseMessageTextPerUser, replaceMentionedUsernamesWithFullNames } from '../functions/notifications';
import { parseMessageTextPerUser, replaceMentionedUsernamesWithFullNames } from '../functions/notifications';
import { notifyDesktopUser, shouldNotifyDesktop } from '../functions/notifications/desktop';
import { getEmailData, shouldNotifyEmail } from '../functions/notifications/email';
import { messageContainsHighlight } from '../functions/notifications/messageContainsHighlight';
import { getPushData, shouldNotifyMobile } from '../functions/notifications/mobile';
import { getMentions } from './notifyUsersOnMessage';

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { expect } from 'chai';
import { describe, it } from 'mocha';

import { messageContainsHighlight } from '../../../../../../../app/lib/server/functions/notifications/messageContainsHighlight';

describe('messageContainsHighlight', () => {
it('should return false for no highlights', async () => {
const message = {
msg: 'regular message',
};
expect(messageContainsHighlight(message, [])).to.be.false;
});

it('should return true when find a highlight in the beggining of the message', async () => {
const message = {
msg: 'highlighted regular message',
};
expect(messageContainsHighlight(message, ['highlighted'])).to.be.true;
});

it('should return true when find a highlight in the end of the message', async () => {
const message = {
msg: 'highlighted regular message',
};
expect(messageContainsHighlight(message, ['message'])).to.be.true;
});

it('should return false if the highlight is just part of the word', async () => {
const message = {
msg: 'highlighted regular message',
};
expect(messageContainsHighlight(message, ['light'])).to.be.false;
});

it('should return true if find one of the multiple highlights', async () => {
const message = {
msg: 'highlighted regular message',
};
expect(messageContainsHighlight(message, ['high', 'ssage', 'regular', 'light'])).to.be.true;
});

it('should return true if highlight case not match', async () => {
const message = {
msg: 'highlighted regular message',
};
expect(messageContainsHighlight(message, ['ReGuLaR'])).to.be.true;
});

it('should return false if the highlight word is an emoji', async () => {
const message = {
msg: 'highlighted :thumbsup: message',
};
expect(messageContainsHighlight(message, ['thumbsup'])).to.be.false;
});

it('should return true for a highlight word beggining with :', async () => {
const message = {
msg: 'highlighted :thumbsup message',
};
expect(messageContainsHighlight(message, ['thumbsup'])).to.be.true;
});

it('should return true for a highlight word ending with :', async () => {
const message = {
msg: 'highlighted thumbsup: message',
};
expect(messageContainsHighlight(message, ['thumbsup'])).to.be.true;
});
});

0 comments on commit f79f3cc

Please sign in to comment.