markdown: Require double-asterisk around all mentions.

This enforces `**` around all the mentions including "at-all" and
"at-everyone" mentions. Hence this makes `@all` and `@everyone`
invalid mentions, resulting into proper syntax for these mentions as
`@**all**` and `@**everyone**` respectively.

Note from tabbott: This removes an old feature/syntax, which made
sense back when @Tim was also a way to mention a user with Tim as
their first name.  Given how nice typeahead is now, the user part of
the feature was removed a while ago; this should have gone at the same
time.

Fixes: #8143.
This commit is contained in:
Shubham Dhama 2018-01-24 21:48:07 +05:30 committed by Tim Abbott
parent 55feafb513
commit a32e1eb913
8 changed files with 80 additions and 39 deletions

View File

@ -13,7 +13,7 @@ casper.then(function () {
subject: 'Test mention all', subject: 'Test mention all',
}); });
}); });
common.select_item_via_typeahead('#compose-textarea', '@all', 'all'); common.select_item_via_typeahead('#compose-textarea', '@**all**', 'all');
casper.then(function () { casper.then(function () {
common.turn_off_press_enter_to_send(); common.turn_off_press_enter_to_send();
@ -33,7 +33,7 @@ casper.then(function () {
casper.then(function () { casper.then(function () {
casper.waitForSelectorText(".compose-all-everyone-msg", "Are you sure you want to mention all", function () { casper.waitForSelectorText(".compose-all-everyone-msg", "Are you sure you want to mention all", function () {
casper.test.info('Warning message appears when mentioning @all'); casper.test.info('Warning message appears when mentioning @**all**');
casper.test.assertSelectorHasText('.compose-all-everyone-msg', 'Are you sure you want to mention all'); casper.test.assertSelectorHasText('.compose-all-everyone-msg', 'Are you sure you want to mention all');
casper.click('.compose-all-everyone-confirm'); casper.click('.compose-all-everyone-confirm');
}); });

View File

@ -253,7 +253,7 @@ people.add(bob);
$('#compose-all-everyone').append = function (data) { $('#compose-all-everyone').append = function (data) {
compose_content = data; compose_content = data;
}; };
compose_state.message_content('Hey @all'); compose_state.message_content('Hey @**all**');
assert(!compose.validate()); assert(!compose.validate());
assert.equal($("#compose-send-button").prop('disabled'), false); assert.equal($("#compose-send-button").prop('disabled'), false);
assert(!$("#compose-send-status").visible()); assert(!$("#compose-send-status").visible());

View File

@ -368,13 +368,23 @@ var bugdown_data = JSON.parse(fs.readFileSync(path.join(__dirname, '../../zerver
input = "test @all"; input = "test @all";
message = {subject: "No links here", raw_content: input}; message = {subject: "No links here", raw_content: input};
markdown.apply_markdown(message); markdown.apply_markdown(message);
assert.equal(message.mentioned, true); assert.equal(message.mentioned, false);
input = "test @everyone";
message = {subject: "No links here", raw_content: input};
markdown.apply_markdown(message);
assert.equal(message.mentioned, false);
input = "test @any"; input = "test @any";
message = {subject: "No links here", raw_content: input}; message = {subject: "No links here", raw_content: input};
markdown.apply_markdown(message); markdown.apply_markdown(message);
assert.equal(message.mentioned, false); assert.equal(message.mentioned, false);
input = "test @alleycat.com";
message = {subject: "No links here", raw_content: input};
markdown.apply_markdown(message);
assert.equal(message.mentioned, false);
input = "test @*hamletcharacters*"; input = "test @*hamletcharacters*";
message = {subject: "No links here", raw_content: input}; message = {subject: "No links here", raw_content: input};
markdown.apply_markdown(message); markdown.apply_markdown(message);
@ -384,6 +394,11 @@ var bugdown_data = JSON.parse(fs.readFileSync(path.join(__dirname, '../../zerver
message = {subject: "No links here", raw_content: input}; message = {subject: "No links here", raw_content: input};
markdown.apply_markdown(message); markdown.apply_markdown(message);
assert.equal(message.mentioned, false); assert.equal(message.mentioned, false);
input = "test @**invalid_user**";
message = {subject: "No links here", raw_content: input};
markdown.apply_markdown(message);
assert.equal(message.mentioned, false);
}()); }());
(function test_backend_only_realm_filters() { (function test_backend_only_realm_filters() {

View File

@ -153,39 +153,35 @@ zrequire('util');
(function test_all_and_everyone_mentions_regexp() { (function test_all_and_everyone_mentions_regexp() {
var messages_with_all_mentions = [ var messages_with_all_mentions = [
'@all', '@**all**',
'some text before @all some text after', 'some text before @**all** some text after',
'@all some text after only', '@**all** some text after only',
'some text before only @all', 'some text before only @**all**',
'@**all**',
'some text before @**all** some text after',
'@**all** some text after only',
'some text before only @**all**',
]; ];
var messages_with_everyone_mentions = [ var messages_with_everyone_mentions = [
'@everyone', '@**everyone**',
'some text before @everyone some text after', 'some text before @**everyone** some text after',
'@everyone some text after only', '@**everyone** some text after only',
'some text before only @everyone', 'some text before only @**everyone**',
'@**everyone**',
'some text before @**everyone** some text after',
'@**everyone** some text after only',
'some text before only @**everyone**',
]; ];
var messages_without_all_mentions = [ var messages_without_all_mentions = [
'`@everyone`', '@all',
'some_email@everyone.com', 'some text before @all some text after',
'`@**everyone**`', '`@everyone`',
'some_email@**everyone**.com', 'some_email@everyone.com',
'`@**everyone**`',
'some_email@**everyone**.com',
]; ];
var messages_without_everyone_mentions = [ var messages_without_everyone_mentions = [
'`@everyone`', 'some text before @everyone some text after',
'some_email@everyone.com', '@everyone',
'`@**everyone**`', '`@everyone`',
'some_email@**everyone**.com', 'some_email@everyone.com',
'`@**everyone**`',
'some_email@**everyone**.com',
]; ];
var i; var i;
for (i=0; i<messages_with_all_mentions.length; i += 1) { for (i=0; i<messages_with_all_mentions.length; i += 1) {

View File

@ -198,7 +198,7 @@ exports.CachedValue.prototype = {
}; };
exports.is_all_or_everyone_mentioned = function (message_content) { exports.is_all_or_everyone_mentioned = function (message_content) {
var all_everyone_re = /(^|\s)(@\*{2}(all|everyone)\*{2})|(@(all|everyone))($|\s)/; var all_everyone_re = /(^|\s)(@\*{2}(all|everyone)\*{2})($|\s)/;
return all_everyone_re.test(message_content); return all_everyone_re.test(message_content);
}; };

View File

@ -516,7 +516,7 @@ inline.zulip = merge({}, inline.breaks, {
'\ud83d[\ude80-\udeff]|\ud83e[\udd00-\uddff]|' + '\ud83d[\ude80-\udeff]|\ud83e[\udd00-\uddff]|' +
'[\u2000-\u206F]|[\u2300-\u27BF]|[\u2B00-\u2BFF]|' + '[\u2000-\u206F]|[\u2300-\u27BF]|[\u2B00-\u2BFF]|' +
'[\u3000-\u303F]|[\u3200-\u32FF])'), '[\u3000-\u303F]|[\u3200-\u32FF])'),
usermention: /^(@(?:\*\*([^\*]+)\*\*|(\w+)))/, // Match multi-word string between @** ** or match any one-word usermention: /^(@(?:\*\*([^\*]+)\*\*))/, // Match potentially multi-word string between @** **
groupmention: /^@\*([^\*]+)\*/, // Match multi-word string between @* * groupmention: /^@\*([^\*]+)\*/, // Match multi-word string between @* *
stream: /^#\*\*([^\*]+)\*\*/, stream: /^#\*\*([^\*]+)\*\*/,
avatar: /^!avatar\(([^)]+)\)/, avatar: /^!avatar\(([^)]+)\)/,

View File

@ -1362,9 +1362,7 @@ class UserMentionPattern(markdown.inlinepatterns.Pattern):
if match.startswith("**") and match.endswith("**"): if match.startswith("**") and match.endswith("**"):
name = match[2:-2] name = match[2:-2]
else: else:
if not mention.user_mention_matches_wildcard(match): return None
return None
name = match
wildcard = mention.user_mention_matches_wildcard(name) wildcard = mention.user_mention_matches_wildcard(name)
user = db_data['mention_data'].get_user(name) user = db_data['mention_data'].get_user(name)

View File

@ -772,7 +772,7 @@ class BugdownTest(ZulipTestCase):
user_profile = self.example_user('othello') user_profile = self.example_user('othello')
msg = Message(sender=user_profile, sending_client=get_client("test")) msg = Message(sender=user_profile, sending_client=get_client("test"))
content = "@all test" content = "@**all** test"
self.assertEqual(render_markdown(msg, content), self.assertEqual(render_markdown(msg, content),
'<p><span class="user-mention" data-user-email="*" data-user-id="*">' '<p><span class="user-mention" data-user-email="*" data-user-id="*">'
'@all' '@all'
@ -783,12 +783,44 @@ class BugdownTest(ZulipTestCase):
user_profile = self.example_user('othello') user_profile = self.example_user('othello')
msg = Message(sender=user_profile, sending_client=get_client("test")) msg = Message(sender=user_profile, sending_client=get_client("test"))
content = "@everyone test" content = "@**everyone** test"
self.assertEqual(render_markdown(msg, content), self.assertEqual(render_markdown(msg, content),
'<p><span class="user-mention" data-user-email="*" data-user-id="*">@everyone</span> test</p>') '<p><span class="user-mention" data-user-email="*" data-user-id="*">'
'@everyone'
'</span> test</p>')
self.assertTrue(msg.mentions_wildcard) self.assertTrue(msg.mentions_wildcard)
def test_mention_everyone_style_normal_user(self) -> None: def test_mention_at_wildcard(self) -> None:
user_profile = self.example_user('othello')
msg = Message(sender=user_profile, sending_client=get_client("test"))
content = "@all test"
self.assertEqual(render_markdown(msg, content),
'<p>@all test</p>')
self.assertFalse(msg.mentions_wildcard)
self.assertEqual(msg.mentions_user_ids, set([]))
def test_mention_at_everyone(self) -> None:
user_profile = self.example_user('othello')
msg = Message(sender=user_profile, sending_client=get_client("test"))
content = "@everyone test"
self.assertEqual(render_markdown(msg, content),
'<p>@everyone test</p>')
self.assertFalse(msg.mentions_wildcard)
self.assertEqual(msg.mentions_user_ids, set([]))
def test_mention_word_starting_with_at_wildcard(self) -> None:
user_profile = self.example_user('othello')
msg = Message(sender=user_profile, sending_client=get_client("test"))
content = "test @alleycat.com test"
self.assertEqual(render_markdown(msg, content),
'<p>test @alleycat.com test</p>')
self.assertFalse(msg.mentions_wildcard)
self.assertEqual(msg.mentions_user_ids, set([]))
def test_mention_at_normal_user(self) -> None:
user_profile = self.example_user('othello') user_profile = self.example_user('othello')
msg = Message(sender=user_profile, sending_client=get_client("test")) msg = Message(sender=user_profile, sending_client=get_client("test"))
@ -818,7 +850,7 @@ class BugdownTest(ZulipTestCase):
assert_mentions('', set()) assert_mentions('', set())
assert_mentions('boring', set()) assert_mentions('boring', set())
assert_mentions('@all', set()) assert_mentions('@**all**', set())
assert_mentions('smush@**steve**smush', set()) assert_mentions('smush@**steve**smush', set())
assert_mentions( assert_mentions(
@ -885,7 +917,7 @@ class BugdownTest(ZulipTestCase):
assert_mentions('', set()) assert_mentions('', set())
assert_mentions('boring', set()) assert_mentions('boring', set())
assert_mentions('@all', set()) assert_mentions('@**all**', set())
assert_mentions('smush@*steve*smush', set()) assert_mentions('smush@*steve*smush', set())
assert_mentions( assert_mentions(