mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 14:47:53 +01:00
Create links to users profile in chat messages
This commit is contained in:
420
package-lock.json
generated
420
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
57
test/api/unit/libs/highlightMentions.js
Normal file
57
test/api/unit/libs/highlightMentions.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import {
|
||||||
|
highlightMentions,
|
||||||
|
} from '../../../../website/server/libs/highlightMentions';
|
||||||
|
import mongoose from 'mongoose';
|
||||||
|
|
||||||
|
describe.only('highlightMentions', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
const mockFind = {
|
||||||
|
select () {
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
lean () {
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
exec () {
|
||||||
|
return Promise.resolve([{
|
||||||
|
auth: { local: { username: 'user' } }, _id: '111',
|
||||||
|
}, { auth: { local: { username: 'user2' } }, _id: '222',
|
||||||
|
}, { auth: { local: { username: 'user3' } }, _id: '333',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
sinon.stub(mongoose.Model, 'find').returns(mockFind);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
sinon.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('doesn\'t change text without mentions', async () => {
|
||||||
|
let text = 'some chat text';
|
||||||
|
let highlightedText = await highlightMentions(text);
|
||||||
|
expect(highlightedText).to.equal(text);
|
||||||
|
});
|
||||||
|
it('highlights existing users', async () => {
|
||||||
|
let text = '@user: message';
|
||||||
|
let highlightedText = await highlightMentions(text);
|
||||||
|
expect(highlightedText).to.equal('[@user](https://habitica.com/members/111): message');
|
||||||
|
});
|
||||||
|
it('doesn\'t highlight nonexisting users', async () => {
|
||||||
|
let text = '@nouser message';
|
||||||
|
let highlightedText = await highlightMentions(text);
|
||||||
|
expect(highlightedText).to.equal('@nouser message');
|
||||||
|
});
|
||||||
|
it('highlights multiple existing users', async () => {
|
||||||
|
let text = '@user message (@user2) @user3 @user';
|
||||||
|
let highlightedText = await highlightMentions(text);
|
||||||
|
expect(highlightedText).to.equal('[@user](https://habitica.com/members/111) message ([@user2](https://habitica.com/members/222)) [@user3](https://habitica.com/members/333) [@user](https://habitica.com/members/111)');
|
||||||
|
});
|
||||||
|
it('doesn\'t highlight more than 5 users', async () => {
|
||||||
|
let text = '@user @user2 @user3 @user4 @user5 @user6';
|
||||||
|
let highlightedText = await highlightMentions(text);
|
||||||
|
expect(highlightedText).to.equal(text);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -18,6 +18,7 @@ import guildsAllowingBannedWords from '../../libs/guildsAllowingBannedWords';
|
|||||||
import { getMatchesByWordArray } from '../../libs/stringUtils';
|
import { getMatchesByWordArray } from '../../libs/stringUtils';
|
||||||
import bannedSlurs from '../../libs/bannedSlurs';
|
import bannedSlurs from '../../libs/bannedSlurs';
|
||||||
import apiError from '../../libs/apiError';
|
import apiError from '../../libs/apiError';
|
||||||
|
import {highlightMentions} from '../../libs/highlightMentions';
|
||||||
|
|
||||||
const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL').split(',').map((email) => {
|
const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL').split(',').map((email) => {
|
||||||
return { email, canSend: true };
|
return { email, canSend: true };
|
||||||
@@ -175,7 +176,8 @@ api.postChat = {
|
|||||||
throw new NotAuthorized(res.t('messageGroupChatSpam'));
|
throw new NotAuthorized(res.t('messageGroupChatSpam'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const newChatMessage = group.sendChat(req.body.message, user);
|
const message = await highlightMentions(req.body.message);
|
||||||
|
const newChatMessage = group.sendChat(message, user);
|
||||||
let toSave = [newChatMessage.save()];
|
let toSave = [newChatMessage.save()];
|
||||||
|
|
||||||
if (group.type === 'party') {
|
if (group.type === 'party') {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import {
|
|||||||
} from '../../libs/email';
|
} from '../../libs/email';
|
||||||
import { sendNotification as sendPushNotification } from '../../libs/pushNotifications';
|
import { sendNotification as sendPushNotification } from '../../libs/pushNotifications';
|
||||||
import { achievements } from '../../../../website/common/';
|
import { achievements } from '../../../../website/common/';
|
||||||
|
import {highlightMentions} from '../../libs/highlightMentions';
|
||||||
|
|
||||||
let api = {};
|
let api = {};
|
||||||
|
|
||||||
@@ -632,7 +633,7 @@ api.sendPrivateMessage = {
|
|||||||
if (validationErrors) throw validationErrors;
|
if (validationErrors) throw validationErrors;
|
||||||
|
|
||||||
const sender = res.locals.user;
|
const sender = res.locals.user;
|
||||||
const message = req.body.message;
|
const message = await highlightMentions(req.body.message);
|
||||||
const receiver = await User.findById(req.body.toUserId).exec();
|
const receiver = await User.findById(req.body.toUserId).exec();
|
||||||
if (!receiver) throw new NotFound(res.t('userNotFound'));
|
if (!receiver) throw new NotFound(res.t('userNotFound'));
|
||||||
if (!receiver.flags.verifiedUsername) delete receiver.auth.local.username;
|
if (!receiver.flags.verifiedUsername) delete receiver.auth.local.username;
|
||||||
|
|||||||
22
website/server/libs/highlightMentions.js
Normal file
22
website/server/libs/highlightMentions.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import {model as User} from '../models/user';
|
||||||
|
|
||||||
|
const mentionRegex = new RegExp('\\B@[-\\w]+', 'g');
|
||||||
|
|
||||||
|
export async function highlightMentions (text) {
|
||||||
|
const mentions = text.match(mentionRegex);
|
||||||
|
if (mentions !== null && mentions.length <= 5) {
|
||||||
|
const usernames = mentions.map((mention) => {
|
||||||
|
return mention.substr(1);
|
||||||
|
});
|
||||||
|
let members = await User
|
||||||
|
.find({'auth.local.username': {$in: usernames}, 'flags.verifiedUsername': true})
|
||||||
|
.select(['auth.local.username', '_id'])
|
||||||
|
.lean()
|
||||||
|
.exec();
|
||||||
|
members.forEach((member) => {
|
||||||
|
const username = member.auth.local.username;
|
||||||
|
text = text.replace(new RegExp(`@${username}\\b`, 'g'), `[@${username}](https://habitica.com/members/${member._id})`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user