Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX: Do not consider code-blocks when parsing mentions #23280

Merged

Conversation

AndrewPrigorshnev
Copy link
Contributor

@AndrewPrigorshnev AndrewPrigorshnev commented Aug 27, 2023

We have the max_mentions_per_chat_message site settings; when a user tries to mention more users than allowed, no one gets mentioned.

Chat messages may contain code-blocks with strings that look like mentions:

def foo
  @bar + @baz
end

The problem is that the parsing code considers these as real mentions and counts them when checking the limit. This PR fixes the problem.

I also made these simple refactorings along the way:

  1. Extract #resetMentionStats
  2. Use "#" as a private methods prefix
  3. Extract #ensureCookFunctionInitialized and #markdownOptions

@github-actions github-actions bot added the chat PRs which include a change to Chat plugin label Aug 27, 2023
@AndrewPrigorshnev AndrewPrigorshnev force-pushed the fix/do-not-consider-codeblocks-when-parsing-mentions branch 9 times, most recently from 9e92875 to 9f07381 Compare August 30, 2023 20:13
@@ -2125,15 +2125,15 @@ class PluginApi {
* Support for setting a Sidebar panel.
*/
setSidebarPanel(name) {
this._lookupContainer("service:sidebar-state").setPanel(name);
this._lookupContainer("service:sidebar-state")?.setPanel(name);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and following methods get called during the route's deactivation and at that moment service is null. That lead to errors in tests, so I've added safe navigation here.

Comment on lines 62 to 63
currentMessage.cook().then(() => {
const mentions = parseMentionedUsernames(currentMessage.cooked);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are only two changes in this method:

  1. Now we call currentMessage.cook() before parsing mentions
  2. We call parseMentionedUsernames(currentMessage.cooked) instead of this._extractMentions(currentMessage.message)

@AndrewPrigorshnev AndrewPrigorshnev changed the title fix/do not consider codeblocks when parsing mentions FIX: Do not consider code-blocks when parsing mentions Aug 30, 2023
@AndrewPrigorshnev AndrewPrigorshnev force-pushed the fix/do-not-consider-codeblocks-when-parsing-mentions branch from 9f07381 to 2df6952 Compare August 30, 2023 20:30
@AndrewPrigorshnev AndrewPrigorshnev marked this pull request as ready for review August 30, 2023 20:31
Copy link
Contributor

@jjaffeux jjaffeux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes while you address concerns of Sam

@AndrewPrigorshnev AndrewPrigorshnev force-pushed the fix/do-not-consider-codeblocks-when-parsing-mentions branch 2 times, most recently from 63ddfa4 to 4c9875a Compare September 5, 2023 15:04
@AndrewPrigorshnev
Copy link
Contributor Author

AndrewPrigorshnev commented Sep 5, 2023

Requesting changes while you address concerns of Sam

@jjaffeux I've pushed commits that address those concerns. With this commit, instead of parsing mentions from HTML we use the Markdown parser:

  1. We parse markdown into tokens (the parser respects code-blocks, so mention-like expressions in code-blocks don't get parsed)
  2. We traverse tokens and extract mentioned usernames and groups

if (this.mentionsCount > 0) {
this.tooManyMentions =
this.mentionsCount > this.siteSettings.max_mentions_per_chat_message;
currentMessage.parseMentions().then((mentions) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the last commits, this line is the only significant change to this function, we called this._extractMentions before, now we call currentMessage.parseMentions().

Copy link
Contributor

@jjaffeux jjaffeux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good 👍

@jjaffeux
Copy link
Contributor

jjaffeux commented Sep 5, 2023

@AndrewPrigorshnev is that expected that this will not consider the first (valid) @bar ?

test("doesn't consider code-blocks when counting mentions", async function (assert) {
  this.siteSettings.max_mentions_per_chat_message = 2;

  await visit(`/chat/c/-/${channelId}`);
  // since @bar is inside a code-block it shouldn't be considered a mention
  const message = `Hey @user1 @user2 @bar
  \`\`\`
    def foo
      @bar = true
    end
  \`\`\`
  `;
  await fillIn(".chat-composer__input", message);

  assert.dom(".chat-mention-warnings").doesNotExist();
});

@AndrewPrigorshnev
Copy link
Contributor Author

AndrewPrigorshnev commented Sep 5, 2023

@AndrewPrigorshnev is that expected that this will not consider the first (valid) @bar ?

test("doesn't consider code-blocks when counting mentions", async function (assert) {
  this.siteSettings.max_mentions_per_chat_message = 2;

  await visit(`/chat/c/-/${channelId}`);
  // since @bar is inside a code-block it shouldn't be considered a mention
  const message = `Hey @user1 @user2 @bar
  \`\`\`
    def foo
      @bar = true
    end
  \`\`\`
  `;
  await fillIn(".chat-composer__input", message);

  assert.dom(".chat-mention-warnings").doesNotExist();
});

That should consider it. I've just tried it locally, added @bar outside the code block as you did and the test failed. Do you see a passing test in this case?

In case you tested that not in tests, but in an actual chat channel, you may not see a warning because the default value for max_mentions_per_chat_message is bigger than 2, while I set it to 2 in the test:

this.siteSettings.max_mentions_per_chat_message = 2;

@jjaffeux
Copy link
Contributor

jjaffeux commented Sep 5, 2023

Yes I think it's fine indeed, I think I misunderstood the test at first, all good 👍

@AndrewPrigorshnev AndrewPrigorshnev force-pushed the fix/do-not-consider-codeblocks-when-parsing-mentions branch from 656e045 to e48a9a4 Compare September 6, 2023 15:16
@AndrewPrigorshnev AndrewPrigorshnev force-pushed the fix/do-not-consider-codeblocks-when-parsing-mentions branch from e48a9a4 to 80c105d Compare September 7, 2023 11:56
@AndrewPrigorshnev AndrewPrigorshnev merged commit 73781c8 into main Sep 7, 2023
13 checks passed
@AndrewPrigorshnev AndrewPrigorshnev deleted the fix/do-not-consider-codeblocks-when-parsing-mentions branch September 7, 2023 12:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chat PRs which include a change to Chat plugin
2 participants