diff --git a/__tests__/ExpensiMark-HTML-test.js b/__tests__/ExpensiMark-HTML-test.js
index 84036cb7..49280829 100644
--- a/__tests__/ExpensiMark-HTML-test.js
+++ b/__tests__/ExpensiMark-HTML-test.js
@@ -1063,3 +1063,63 @@ test('Skip rendering invalid markdown',() => {
testString = '> *This is multiline\nbold text*';
expect(parser.replace(testString)).toBe('
*This is multiline
bold text*');
});
+
+test('Test for email with test+1@gmail.com@gmail.com', () => {
+ const testString = 'test+1@gmail.com@gmail.com';
+ const resultString = 'test+1@gmail.com@gmail.com';
+ expect(parser.replace(testString)).toBe(resultString);
+});
+
+test('Test for email with test@gmail.com@gmail.com', () => {
+ const testString = 'test@gmail.com@gmail.com';
+ const resultString = 'test@gmail.com@gmail.com';
+ expect(parser.replace(testString)).toBe(resultString);
+});
+
+test('Test for email with test@here@gmail.com', () => {
+ const testString = 'test@here@gmail.com';
+ const resultString = 'test@here@gmail.com';
+ expect(parser.replace(testString)).toBe(resultString);
+});
+
+test('Test for email with test+1@here@gmail.com', () => {
+ const testString = 'test+1@here@gmail.com';
+ const resultString = 'test+1@here@gmail.com';
+ expect(parser.replace(testString)).toBe(resultString);
+});
+
+test('Test user mention with @here@here.com', () => {
+ const testString = '@here@here.com';
+ const resultString = '@here@here.com';
+ expect(parser.replace(testString)).toBe(resultString);
+});
+
+test('Test user mention with @abc_@here.com', () => {
+ const testString = '@abc_@here.com';
+ const resultString = '@abc_@here.com';
+ expect(parser.replace(testString)).toBe(resultString);
+});
+
+test('Test user mention with @here_@here.com', () => {
+ const testString = '@here_@here.com';
+ const resultString = '@here_@here.com';
+ expect(parser.replace(testString)).toBe(resultString);
+});
+
+test('Test here mention with @here_@here_.com', () => {
+ const testString = '@here_@here_.com';
+ const resultString = '@here@here.com';
+ expect(parser.replace(testString)).toBe(resultString);
+});
+
+test('Test here mention with @here@', () => {
+ const testString = '@here@';
+ const resultString = '@here@';
+ expect(parser.replace(testString)).toBe(resultString);
+});
+
+test('Test here mention with @here@here', () => {
+ const testString = '@here@here';
+ const resultString = '@here@here';
+ expect(parser.replace(testString)).toBe(resultString);
+});
\ No newline at end of file
diff --git a/__tests__/Str-test.js b/__tests__/Str-test.js
index a8d92a2a..c8d1a386 100644
--- a/__tests__/Str-test.js
+++ b/__tests__/Str-test.js
@@ -77,7 +77,6 @@ describe('Str.isValidMention', () => {
expect(Str.isValidMention('*@username@expensify.com*')).toBeTruthy();
expect(Str.isValidMention(' @username@expensify.com')).toBeTruthy();
expect(Str.isValidMention('~@username@expensify.com~')).toBeTruthy();
- expect(Str.isValidMention('#@username@expensify.com')).toBeTruthy();
expect(Str.isValidMention('_@username@expensify.com_')).toBeTruthy();
expect(Str.isValidMention('`@username@expensify.com`')).toBeFalsy();
expect(Str.isValidMention('\'@username@expensify.com\'')).toBeTruthy();
diff --git a/lib/ExpensiMark.js b/lib/ExpensiMark.js
index 418cc6d3..8d2186f7 100644
--- a/lib/ExpensiMark.js
+++ b/lib/ExpensiMark.js
@@ -92,12 +92,12 @@ export default class ExpensiMark {
*/
{
name: 'hereMentions',
- regex: /[`.a-zA-Z]?@here(?=_\b|\b)(?!((?:(?!|[^<]*(<\/pre>|<\/code>))/gm,
- replacement: (match) => {
+ regex: /([a-zA-Z0-9.!$%&+/=?^`{|}_-]?)(@here)([a-zA-Z0-9.!$%&+/=?^`{|}_-]?)(?=\b)(?!(@[a-zA-Z0-9-]+?(\.[a-zA-Z]+)+)|((?:(?!|[^<]*(<\/pre>|<\/code>))/gm,
+ replacement: (match, g1, g2, g3) => {
if (!Str.isValidMention(match)) {
return match;
}
- return `${match}`;
+ return `${g1}${g2}${g3}`;
},
},
@@ -110,7 +110,7 @@ export default class ExpensiMark {
*/
{
name: 'userMentions',
- regex: new RegExp(`[\`.a-zA-Z]?@+${CONST.REG_EXP.EMAIL_PART}(?!((?:(?!|[^<]*(<\\/pre>|<\\/code>))`, 'gm'),
+ regex: new RegExp(`[a-zA-Z0-9.!$%&+/=?^\`{|}-]?@+${CONST.REG_EXP.EMAIL_PART}(?!((?:(?!|[^<]*(<\\/pre>|<\\/code>))`, 'gm'),
replacement: (match) => {
if (!Str.isValidMention(match)) {
return match;
diff --git a/lib/str.js b/lib/str.js
index 14a582f0..ad48560e 100644
--- a/lib/str.js
+++ b/lib/str.js
@@ -943,8 +943,16 @@ const Str = {
* @returns {bool}
*/
isValidMention(mention) {
- // A valid mention starts with a space, *, _, #, ', ", or @ (with no preceding characters).
- return /[\s*~_#'"@]/g.test(mention.charAt(0));
+ // Mentions can start @ proceeded by a space, eg "ping @user@domain.tld"
+ if (/[\s@]/g.test(mention.charAt(0))) {
+ return true;
+ }
+
+ // Mentions can also start and end with a *, _, ~, ', or " (with no other preceding characters)
+ // eg "ping *@user@domain.tld*"
+ const firstChar = mention.charAt(0);
+ const lastChar = mention.charAt(mention.length - 1);
+ return /[*~_'"]/g.test(firstChar) && /[*~_'"]/g.test(lastChar) && firstChar === lastChar;
},
/**