Merge pull request #2720 from whowillcare/master

if username contains space, @ functions will fail at certain point
This commit is contained in:
Lauri Ojansivu 2019-09-25 20:51:51 +03:00 committed by GitHub
commit 814e264521
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 27 deletions

View file

@ -94,7 +94,13 @@ Template.editor.onRendered(() => {
currentBoard currentBoard
.activeMembers() .activeMembers()
.map(member => { .map(member => {
const username = Users.findOne(member.userId).username; const user = Users.findOne(member.userId);
if (user._id === Meteor.userId()) {
return null;
}
const value = user.username;
const username =
value && value.match(/\s+/) ? `"${value}"` : value;
return username.includes(term) ? username : null; return username.includes(term) ? username : null;
}) })
.filter(Boolean), .filter(Boolean),
@ -120,9 +126,10 @@ Template.editor.onRendered(() => {
? [ ? [
['view', ['fullscreen']], ['view', ['fullscreen']],
['table', ['table']], ['table', ['table']],
['font', ['bold', 'underline']], ['font', ['bold']],
//['fontsize', ['fontsize']],
['color', ['color']], ['color', ['color']],
['insert', ['video']], // iframe tag will be sanitized TODO if iframe[class=note-video-clip] can be added into safe list, insert video can be enabled
//['fontsize', ['fontsize']],
] ]
: [ : [
['style', ['style']], ['style', ['style']],
@ -345,11 +352,12 @@ Blaze.Template.registerHelper(
} }
return member; return member;
}); });
const mentionRegex = /\B@([\w.]*)/gi; const mentionRegex = /\B@(?:(?:"([\w.\s]*)")|([\w.]+))/gi; // including space in username
let currentMention; let currentMention;
while ((currentMention = mentionRegex.exec(content)) !== null) { while ((currentMention = mentionRegex.exec(content)) !== null) {
const [fullMention, username] = currentMention; const [fullMention, quoteduser, simple] = currentMention;
const username = quoteduser || simple;
const knowedUser = _.findWhere(knowedUsers, { username }); const knowedUser = _.findWhere(knowedUsers, { username });
if (!knowedUser) { if (!knowedUser) {
continue; continue;

View file

@ -731,6 +731,7 @@
"almostdue": "current due time %s is approaching", "almostdue": "current due time %s is approaching",
"pastdue": "current due time %s is past", "pastdue": "current due time %s is past",
"duenow": "current due time %s is today", "duenow": "current due time %s is today",
"act-newDue": "__card__ has 1st due reminder [__board__]",
"act-withDue": "__card__ due reminders [__board__]", "act-withDue": "__card__ due reminders [__board__]",
"act-almostdue": "was reminding the current due (__timeValue__) of __card__ is approaching", "act-almostdue": "was reminding the current due (__timeValue__) of __card__ is approaching",
"act-pastdue": "was reminding the current due (__timeValue__) of __card__ is past", "act-pastdue": "was reminding the current due (__timeValue__) of __card__ is past",

View file

@ -180,28 +180,34 @@ if (Meteor.isServer) {
const comment = activity.comment(); const comment = activity.comment();
params.comment = comment.text; params.comment = comment.text;
if (board) { if (board) {
const atUser = /(?:^|>|\b|\s)@(\S+?)(?:\s|$|<|\b)/g;
const comment = params.comment; const comment = params.comment;
if (comment.match(atUser)) { const knownUsers = board.members.map(member => {
const commenter = params.user; const u = Users.findOne(member.userId);
while (atUser.exec(comment)) { if (u) {
const username = RegExp.$1; member.username = u.username;
if (commenter === username) { member.emails = u.emails;
// it's person at himself, ignore it?
continue;
}
const atUser =
Users.findOne(username) || Users.findOne({ username });
if (atUser && atUser._id) {
const uid = atUser._id;
params.atUsername = username;
params.atEmails = atUser.emails;
if (board.hasMember(uid)) {
title = 'act-atUserComment';
watchers = _.union(watchers, [uid]);
}
}
} }
return member;
});
const mentionRegex = /\B@(?:(?:"([\w.\s]*)")|([\w.]+))/gi; // including space in username
let currentMention;
while ((currentMention = mentionRegex.exec(comment)) !== null) {
/*eslint no-unused-vars: ["error", { "varsIgnorePattern": "[iI]gnored" }]*/
const [ignored, quoteduser, simple] = currentMention;
const username = quoteduser || simple;
if (username === params.user) {
// ignore commenter mention himself?
continue;
}
const atUser = _.findWhere(knownUsers, { username });
if (!atUser) {
continue;
}
const uid = atUser.userId;
params.atUsername = username;
params.atEmails = atUser.emails;
title = 'act-atUserComment';
watchers = _.union(watchers, [uid]);
} }
} }
params.commentId = comment._id; params.commentId = comment._id;
@ -236,8 +242,8 @@ if (Meteor.isServer) {
(!activity.timeKey || activity.timeKey === 'dueAt') && (!activity.timeKey || activity.timeKey === 'dueAt') &&
activity.timeValue activity.timeValue
) { ) {
// due time reminder // due time reminder, if it doesn't have old value, it's a brand new set, need some differentiation
title = 'act-withDue'; title = activity.timeOldValue ? 'act-withDue' : 'act-newDue';
} }
['timeValue', 'timeOldValue'].forEach(key => { ['timeValue', 'timeOldValue'].forEach(key => {
// copy time related keys & values to params // copy time related keys & values to params

View file

@ -1558,6 +1558,7 @@ function cardRemover(userId, doc) {
const findDueCards = days => { const findDueCards = days => {
const seekDue = ($from, $to, activityType) => { const seekDue = ($from, $to, activityType) => {
Cards.find({ Cards.find({
archived: false,
dueAt: { $gte: $from, $lt: $to }, dueAt: { $gte: $from, $lt: $to },
}).forEach(card => { }).forEach(card => {
const username = Users.findOne(card.userId).username; const username = Users.findOne(card.userId).username;

View file

@ -561,6 +561,7 @@ Users.mutations({
Meteor.methods({ Meteor.methods({
setUsername(username, userId) { setUsername(username, userId) {
check(username, String); check(username, String);
check(userId, String);
const nUsersWithUsername = Users.find({ username }).count(); const nUsersWithUsername = Users.find({ username }).count();
if (nUsersWithUsername > 0) { if (nUsersWithUsername > 0) {
throw new Meteor.Error('username-already-taken'); throw new Meteor.Error('username-already-taken');