diff --git a/webapp/channels/package.json b/webapp/channels/package.json index 487644d613..d60b98f44d 100644 --- a/webapp/channels/package.json +++ b/webapp/channels/package.json @@ -51,7 +51,7 @@ "lodash": "4.17.21", "luxon": "3.6.1", "mark.js": "8.11.1", - "marked": "github:mattermost/marked#3b13ba8ddf725327ddf0298361d6d304a021f2d1", + "marked": "github:mattermost/marked#08f3638e37e17738fafcaf749683ce6fee1d8edc", "memoize-one": "6.0.0", "moment-timezone": "0.5.38", "monaco-editor": "0.52.2", diff --git a/webapp/channels/src/components/drafts/panel/__snapshots__/panel_body.test.tsx.snap b/webapp/channels/src/components/drafts/panel/__snapshots__/panel_body.test.tsx.snap index b3acbd9ab1..6361d83cc7 100644 --- a/webapp/channels/src/components/drafts/panel/__snapshots__/panel_body.test.tsx.snap +++ b/webapp/channels/src/components/drafts/panel/__snapshots__/panel_body.test.tsx.snap @@ -173,16 +173,6 @@ exports[`components/drafts/panel/panel_body should have called handleFormattedTe } > { options={{ mentionHighlight: false, markdown: false, - autolinkedUrlSchemes: [], }} /> diff --git a/webapp/channels/src/components/post_view/embedded_bindings/embedded_binding/__snapshots__/embedded_binding.test.tsx.snap b/webapp/channels/src/components/post_view/embedded_bindings/embedded_binding/__snapshots__/embedded_binding.test.tsx.snap index c8219ffe04..2d0a43087e 100644 --- a/webapp/channels/src/components/post_view/embedded_bindings/embedded_binding/__snapshots__/embedded_binding.test.tsx.snap +++ b/webapp/channels/src/components/post_view/embedded_bindings/embedded_binding/__snapshots__/embedded_binding.test.tsx.snap @@ -18,7 +18,6 @@ exports[`components/post_view/embedded_bindings/embedded_binding should match sn message="some text" options={ Object { - "autolinkedUrlSchemes": Array [], "mentionHighlight": false, "renderer": LinkOnlyRenderer { "options": Object {}, @@ -80,7 +79,6 @@ exports[`components/post_view/embedded_bindings/embedded_binding should match sn message="some text" options={ Object { - "autolinkedUrlSchemes": Array [], "mentionHighlight": false, "renderer": LinkOnlyRenderer { "options": Object {}, @@ -142,7 +140,6 @@ exports[`components/post_view/embedded_bindings/embedded_binding should match sn message="some text" options={ Object { - "autolinkedUrlSchemes": Array [], "mentionHighlight": false, "renderer": LinkOnlyRenderer { "options": Object {}, @@ -204,7 +201,6 @@ exports[`components/post_view/embedded_bindings/embedded_binding should match sn message="some text" options={ Object { - "autolinkedUrlSchemes": Array [], "mentionHighlight": false, "renderer": LinkOnlyRenderer { "options": Object {}, diff --git a/webapp/channels/src/components/post_view/embedded_bindings/embedded_binding/embedded_binding.tsx b/webapp/channels/src/components/post_view/embedded_bindings/embedded_binding/embedded_binding.tsx index 6bfcd21052..4777f1fd7b 100644 --- a/webapp/channels/src/components/post_view/embedded_bindings/embedded_binding/embedded_binding.tsx +++ b/webapp/channels/src/components/post_view/embedded_bindings/embedded_binding/embedded_binding.tsx @@ -161,7 +161,6 @@ export default class EmbeddedBinding extends React.PureComponent { options={{ mentionHighlight: false, renderer: new LinkOnlyRenderer(), - autolinkedUrlSchemes: [], }} postId={this.props.post.id} /> diff --git a/webapp/channels/src/components/post_view/message_attachments/action_button/action_button.tsx b/webapp/channels/src/components/post_view/message_attachments/action_button/action_button.tsx index 1d811c0d8f..48db65c43a 100644 --- a/webapp/channels/src/components/post_view/message_attachments/action_button/action_button.tsx +++ b/webapp/channels/src/components/post_view/message_attachments/action_button/action_button.tsx @@ -26,7 +26,6 @@ const getStatusColors = (theme: Theme) => { const markdownOptions = { mentionHighlight: false, markdown: false, - autolinkedUrlSchemes: [], }; type Props = { diff --git a/webapp/channels/src/components/post_view/message_attachments/message_attachment/__snapshots__/message_attachment.test.tsx.snap b/webapp/channels/src/components/post_view/message_attachments/message_attachment/__snapshots__/message_attachment.test.tsx.snap index 2c5e8e5566..e3ff2fddd3 100644 --- a/webapp/channels/src/components/post_view/message_attachments/message_attachment/__snapshots__/message_attachment.test.tsx.snap +++ b/webapp/channels/src/components/post_view/message_attachments/message_attachment/__snapshots__/message_attachment.test.tsx.snap @@ -425,7 +425,6 @@ exports[`components/post_view/MessageAttachment should match snapshot when the a options={ Object { "atMentions": false, - "autolinkedUrlSchemes": Array [], "mentionHighlight": false, "renderer": LinkOnlyRenderer { "options": Object {}, @@ -471,7 +470,6 @@ exports[`components/post_view/MessageAttachment should match snapshot when the a options={ Object { "atMentions": false, - "autolinkedUrlSchemes": Array [], "mentionHighlight": false, "renderer": LinkOnlyRenderer { "options": Object {}, @@ -517,7 +515,6 @@ exports[`components/post_view/MessageAttachment should match snapshot when the a options={ Object { "atMentions": false, - "autolinkedUrlSchemes": Array [], "mentionHighlight": false, "renderer": LinkOnlyRenderer { "options": Object {}, @@ -563,7 +560,6 @@ exports[`components/post_view/MessageAttachment should match snapshot when the f options={ Object { "atMentions": false, - "autolinkedUrlSchemes": Array [], "mentionHighlight": false, "renderer": LinkOnlyRenderer { "options": Object {}, diff --git a/webapp/channels/src/components/post_view/message_attachments/message_attachment/message_attachment.tsx b/webapp/channels/src/components/post_view/message_attachments/message_attachment/message_attachment.tsx index 8d7e51927a..cec6e10456 100644 --- a/webapp/channels/src/components/post_view/message_attachments/message_attachment/message_attachment.tsx +++ b/webapp/channels/src/components/post_view/message_attachments/message_attachment/message_attachment.tsx @@ -430,7 +430,6 @@ export default class MessageAttachment extends React.PureComponent atMentions: false, mentionHighlight: false, renderer: new LinkOnlyRenderer(), - autolinkedUrlSchemes: [], }} postId={this.props.postId} /> diff --git a/webapp/channels/src/packages/mattermost-redux/src/actions/posts.test.ts b/webapp/channels/src/packages/mattermost-redux/src/actions/posts.test.ts index aa66c004c8..2423f49cd1 100644 --- a/webapp/channels/src/packages/mattermost-redux/src/actions/posts.test.ts +++ b/webapp/channels/src/packages/mattermost-redux/src/actions/posts.test.ts @@ -673,6 +673,13 @@ describe('Actions.Posts', () => { }), expected: new Set(['ccc', 'ddd', 'fff', 'ggg']), }, + { + name: 'should return potential remote mentions', + input: TestHelper.getPostMock({ + message: '@user1:org1 @user2:org2/@user3:org3/@user4:org4 (@user5:org5) @user6:org6', + }), + expected: new Set(['user1:org1', 'user2:org2', 'user3:org3', 'user4:org4', 'user5:org5', 'user6:org6']), + }, ]; for (const specialMention of [ diff --git a/webapp/channels/src/packages/mattermost-redux/src/actions/posts.ts b/webapp/channels/src/packages/mattermost-redux/src/actions/posts.ts index c5df41d790..a3a8d7ce33 100644 --- a/webapp/channels/src/packages/mattermost-redux/src/actions/posts.ts +++ b/webapp/channels/src/packages/mattermost-redux/src/actions/posts.ts @@ -1098,7 +1098,7 @@ export function getNeededAtMentionedUsernamesAndGroups(state: GlobalState, posts groupsByName = getAllGroupsByName(state); } - const pattern = /\B@(([a-z0-9_.-]*[a-z0-9_])[.-]*)/gi; + const pattern = /\B@(([a-z0-9.\-_:]*[a-z0-9_])[.\-:]*)/gi; let match; while ((match = pattern.exec(text)) !== null) { diff --git a/webapp/channels/src/utils/__snapshots__/message_html_to_component.test.tsx.snap b/webapp/channels/src/utils/__snapshots__/message_html_to_component.test.tsx.snap index b83bf4a2f1..1a46e3c825 100644 --- a/webapp/channels/src/utils/__snapshots__/message_html_to_component.test.tsx.snap +++ b/webapp/channels/src/utils/__snapshots__/message_html_to_component.test.tsx.snap @@ -114,6 +114,42 @@ exports[`messageHtmlToComponent Inline markdown image where image is link 1`] = `; +exports[`messageHtmlToComponent Remote at mention 1`] = ` +

+ + + + @joram + + + +

+`; + +exports[`messageHtmlToComponent Remote at mention 2`] = ` +

+ + + @joram + + +

+`; + exports[`messageHtmlToComponent html 1`] = ` { + return (url: string) => { + const scheme = getScheme(url); + + return !scheme || autolinkedUrlSchemes.includes(scheme); + }; + }, +); + export function stripMarkdown(text: string) { if (typeof text === 'string' && text.length > 0) { return convertEntityToCharacter( diff --git a/webapp/channels/src/utils/markdown/renderer.tsx b/webapp/channels/src/utils/markdown/renderer.tsx index fe7de72037..ae642fb6d2 100644 --- a/webapp/channels/src/utils/markdown/renderer.tsx +++ b/webapp/channels/src/utils/markdown/renderer.tsx @@ -133,7 +133,7 @@ export default class Renderer extends marked.Renderer { return `${text}`; } - public link(href: string, title: string, text: string, isUrl = false) { + public link(href: string, title: string, text: string) { let outHref = href; if (this.formattingOptions.unsafeLinks && mightTriggerExternalRequest(href, this.formattingOptions.siteURL)) { @@ -147,15 +147,6 @@ export default class Renderer extends marked.Renderer { const scheme = getScheme(href); if (!scheme) { outHref = `http://${outHref}`; - } else if (isUrl && this.formattingOptions.autolinkedUrlSchemes) { - const isValidUrl = - this.formattingOptions.autolinkedUrlSchemes.indexOf( - scheme.toLowerCase(), - ) !== -1; - - if (!isValidUrl) { - return text; - } } } diff --git a/webapp/channels/src/utils/message_html_to_component.test.tsx b/webapp/channels/src/utils/message_html_to_component.test.tsx index c461fb5f2f..ce9b20ac5c 100644 --- a/webapp/channels/src/utils/message_html_to_component.test.tsx +++ b/webapp/channels/src/utils/message_html_to_component.test.tsx @@ -135,6 +135,23 @@ const myFunction = () => { expect(shallow(component).find(AtMention).prop('disableGroupHighlight')).toBe(true); }); + test('Remote at mention', () => { + const options = {mentionHighlight: true, atMentions: true, mentionKeys: [{key: '@joram'}]}; + let html = TextFormatting.formatText('@joram', options, emptyEmojiMap); + + let component = messageHtmlToComponent(html, {mentionHighlight: true}); + expect(component).toMatchSnapshot(); + expect(shallow(component).find(AtMention).prop('disableHighlight')).toBe(false); + + options.mentionHighlight = false; + + html = TextFormatting.formatText('@joram', options, emptyEmojiMap); + + component = messageHtmlToComponent(html, {mentionHighlight: false}); + expect(component).toMatchSnapshot(); + expect(shallow(component).find(AtMention).prop('disableHighlight')).toBe(true); + }); + test('typescript', () => { const input = `Text before typescript codeblock \`\`\`typescript diff --git a/webapp/channels/src/utils/post_utils.test.tsx b/webapp/channels/src/utils/post_utils.test.tsx index 769b8e8685..a6da7c2f0d 100644 --- a/webapp/channels/src/utils/post_utils.test.tsx +++ b/webapp/channels/src/utils/post_utils.test.tsx @@ -6,6 +6,7 @@ import {createIntl} from 'react-intl'; import {Preferences} from 'mattermost-redux/constants'; import enMessages from 'i18n/en.json'; +import {makeInitialState} from 'packages/mattermost-redux/test/test_store'; import {PostListRowListIds, Constants} from 'utils/constants'; import EmojiMap from 'utils/emoji_map'; import * as PostUtils from 'utils/post_utils'; @@ -1354,6 +1355,49 @@ describe('makeGetIsReactionAlreadyAddedToPost', () => { }); }); +describe('makeGetUserOrGroupMentionCountFromMessage', () => { + const baseState = makeInitialState({ + entities: { + groups: { + groups: { + group1: TestHelper.getGroupMock({id: 'group1', name: 'group.one', member_count: 4}), + }, + }, + users: { + profiles: { + remoteUser: TestHelper.getUserMock({id: 'remoteUser', username: 'remote.user:org1'}), + user1: TestHelper.getUserMock({id: 'user1', username: 'user.one'}), + user2: TestHelper.getUserMock({id: 'user2', username: 'user.two'}), + }, + }, + }, + }); + + test('should count mentioned users', () => { + const getUserOrGroupMentionCountFromMessage = PostUtils.makeGetUserOrGroupMentionCountFromMessage(); + + expect(getUserOrGroupMentionCountFromMessage(baseState, '@user.one @user.two Hello!')).toEqual(2); + }); + + test('should count mentioned groups', () => { + const getUserOrGroupMentionCountFromMessage = PostUtils.makeGetUserOrGroupMentionCountFromMessage(); + + expect(getUserOrGroupMentionCountFromMessage(baseState, '@group.one @user.one Hello!')).toEqual(5); + }); + + test('should count remote user mentions', () => { + const getUserOrGroupMentionCountFromMessage = PostUtils.makeGetUserOrGroupMentionCountFromMessage(); + + expect(getUserOrGroupMentionCountFromMessage(baseState, '@user.one @user.two @remote.user:org1 Hello!')).toEqual(3); + }); + + test('should not count non-existant users/groups', () => { + const getUserOrGroupMentionCountFromMessage = PostUtils.makeGetUserOrGroupMentionCountFromMessage(); + + expect(getUserOrGroupMentionCountFromMessage(baseState, '@not.user.three @fake.group @not.user:fake Hello!')).toEqual(0); + }); +}); + describe('makeGetUniqueEmojiNameReactionsForPost', () => { const baseState = { entities: { diff --git a/webapp/channels/src/utils/text_formatting.tsx b/webapp/channels/src/utils/text_formatting.tsx index 02e7c827fd..e78e0f909e 100644 --- a/webapp/channels/src/utils/text_formatting.tsx +++ b/webapp/channels/src/utils/text_formatting.tsx @@ -17,7 +17,6 @@ import * as Emoticons from './emoticons'; import * as Markdown from './markdown'; const punctuationRegex = /[^\p{L}\d]/u; -const AT_MENTION_PATTERN = /(?:\B|\b_+)@([a-z0-9.\-_]+)/gi; const UNICODE_EMOJI_REGEX = emojiRegex(); const htmlEmojiPattern = /^

\s*(?:]*>|]*>[^<]*<\/span>\s*|[^<]*<\/span>\s*)+<\/p>$/; @@ -175,13 +174,6 @@ export interface TextFormattingOptionsBase { */ proxyImages: boolean; - /** - * An array of url schemes that will be allowed for autolinking. - * - * Defaults to autolinking with any url scheme. - */ - autolinkedUrlSchemes: string[]; - /** * An array of paths on the server that are managed by another server. Any path provided will be treated as an * external link that will not by handled by react-router. @@ -551,17 +543,17 @@ export function autolinkAtMentions(text: string, tokens: Tokens): string { ); // handle all other mentions (supports trailing punctuation) - let match = output.match(AT_MENTION_PATTERN); + let match = output.match(Constants.MENTIONS_REGEX); while (match && match.length > 0) { - output = output.replace(AT_MENTION_PATTERN, replaceAtMentionWithToken); - match = output.match(AT_MENTION_PATTERN); + output = output.replace(Constants.MENTIONS_REGEX, replaceAtMentionWithToken); + match = output.match(Constants.MENTIONS_REGEX); } return output; } export function allAtMentions(text: string): string[] { - return text.match(Constants.SPECIAL_MENTIONS_REGEX && AT_MENTION_PATTERN) || []; + return text.match(Constants.SPECIAL_MENTIONS_REGEX && Constants.MENTIONS_REGEX) || []; } export function autolinkChannelMentions( diff --git a/webapp/channels/src/utils/text_formatting_at_mentions.test.ts b/webapp/channels/src/utils/text_formatting_at_mentions.test.ts index d22cae8db4..81e262e5c2 100644 --- a/webapp/channels/src/utils/text_formatting_at_mentions.test.ts +++ b/webapp/channels/src/utils/text_formatting_at_mentions.test.ts @@ -147,4 +147,17 @@ describe('TextFormatting.AtMentions', () => { it(test.label, () => expect(test.actual).toBe(test.expected)); }); }); + + test('MM-62744 should recognize remote mentions', () => { + expect(TextFormatting.formatText( + '@user1:org1 @user2:org2/@user3:org3/@user4:org4 (@user5:org5) @user6:org6', + {atMentions: true}, + emptyEmojiMap, + )).toEqual( + '

@user1:org1 ' + + '@user2:org2/@user3:org3/@user4:org4 ' + + '(@user5:org5) ' + + '@user6:org6

', + ); + }); }); diff --git a/webapp/channels/src/utils/text_formatting_links.test.ts b/webapp/channels/src/utils/text_formatting_links.test.ts index 0051b64ba6..e51fa81b00 100644 --- a/webapp/channels/src/utils/text_formatting_links.test.ts +++ b/webapp/channels/src/utils/text_formatting_links.test.ts @@ -1,6 +1,9 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +import store from 'stores/redux_store'; + +import {makeInitialState} from 'packages/mattermost-redux/test/test_store'; import EmojiMap from 'utils/emoji_map'; import * as Markdown from 'utils/markdown'; import * as TextFormatting from 'utils/text_formatting'; @@ -41,10 +44,6 @@ describe('Markdown.Links', () => { }); it('External links', () => { - expect(Markdown.format('test.:test').trim()).toBe( - '

test.:test

', - ); - expect(Markdown.format('http://example.com').trim()).toBe( '

http://example.com

', ); @@ -402,7 +401,18 @@ describe('Markdown.Links', () => { }); describe('autolinkedUrlSchemes', () => { - test('all links are rendered when not provided', () => { + test('only some types of links are rendered when there are custom URL schemes defined', () => { + jest.spyOn(store, 'getState').mockReturnValue(makeInitialState({ + entities: { + general: { + config: { + CustomUrlSchemes: '', + }, + }, + }, + })); + + // These are always linked expect(Markdown.format('http://example.com').trim()).toBe(`

${link('http://example.com')}

`); expect(Markdown.format('https://example.com').trim()).toBe(`

${link('https://example.com')}

`); @@ -413,67 +423,68 @@ describe('Markdown.Links', () => { expect(Markdown.format('mailto:test@example.com').trim()).toBe(`

${link('mailto:test@example.com')}

`); + // These aren't linked since they're not configured on the server + expect(Markdown.format('git://git.example.com').trim()).toBe('

git://git.example.com

'); + + expect(Markdown.format('test:test').trim()).toBe('

test:test

'); + + expect(Markdown.format('test.:test').trim()).toBe('

test.:test

'); + + expect(Markdown.format('taco+what://example.com').trim()).toBe('

taco+what://example.com

'); + + expect(Markdown.format('taco.what://example.com').trim()).toBe('

taco.what://example.com

'); + }); + + test('matching links are rendered when schemes are provided', () => { + jest.spyOn(store, 'getState').mockReturnValue(makeInitialState({ + entities: { + general: { + config: { + CustomUrlSchemes: 'git,test,test.,taco+what,taco.what', + }, + }, + }, + })); + + // These are always linked + expect(Markdown.format('http://example.com').trim()).toBe(`

${link('http://example.com')}

`); + + expect(Markdown.format('https://example.com').trim()).toBe(`

${link('https://example.com')}

`); + + expect(Markdown.format('ftp://ftp.example.com').trim()).toBe(`

${link('ftp://ftp.example.com')}

`); + + expect(Markdown.format('tel:1-555-123-4567').trim()).toBe(`

${link('tel:1-555-123-4567')}

`); + + expect(Markdown.format('mailto:test@example.com').trim()).toBe(`

${link('mailto:test@example.com')}

`); + + // These are linked since they're configured on the server expect(Markdown.format('git://git.example.com').trim()).toBe(`

${link('git://git.example.com')}

`); expect(Markdown.format('test:test').trim()).toBe(`

${link('test:test')}

`); - }); - test('no links are rendered when no schemes are provided', () => { - const options = { - autolinkedUrlSchemes: [], - }; + expect(Markdown.format('test.:test').trim()).toBe(`

${link('test.:test')}

`); - expect(Markdown.format('http://example.com', options).trim()).toBe('

http://example.com

'); + expect(Markdown.format('taco+what://example.com').trim()).toBe(`

${link('taco+what://example.com')}

`); - expect(Markdown.format('https://example.com', options).trim()).toBe('

https://example.com

'); - - expect(Markdown.format('ftp://ftp.example.com', options).trim()).toBe('

ftp://ftp.example.com

'); - - expect(Markdown.format('tel:1-555-123-4567', options).trim()).toBe('

tel:1-555-123-4567

'); - - expect(Markdown.format('mailto:test@example.com', options).trim()).toBe('

mailto:test@example.com

'); - - expect(Markdown.format('git://git.example.com', options).trim()).toBe('

git://git.example.com

'); - - expect(Markdown.format('test:test', options).trim()).toBe('

test:test

'); - }); - - test('only matching links are rendered when schemes are provided', () => { - const options = { - autolinkedUrlSchemes: ['https', 'git', 'test', 'test.', 'taco+what', 'taco.what'], - }; - - expect(Markdown.format('http://example.com', options).trim()).toBe('

http://example.com

'); - - expect(Markdown.format('https://example.com', options).trim()).toBe(`

${link('https://example.com')}

`); - - expect(Markdown.format('ftp://ftp.example.com', options).trim()).toBe('

ftp://ftp.example.com

'); - - expect(Markdown.format('tel:1-555-123-4567', options).trim()).toBe('

tel:1-555-123-4567

'); - - expect(Markdown.format('mailto:test@example.com', options).trim()).toBe('

mailto:test@example.com

'); - - expect(Markdown.format('git://git.example.com', options).trim()).toBe(`

${link('git://git.example.com')}

`); - - expect(Markdown.format('test:test', options).trim()).toBe(`

${link('test:test')}

`); - - expect(Markdown.format('test.:test', options).trim()).toBe(`

${link('test.:test')}

`); - - expect(Markdown.format('taco+what://example.com', options).trim()).toBe(`

${link('taco+what://example.com')}

`); - - expect(Markdown.format('taco.what://example.com', options).trim()).toBe(`

${link('taco.what://example.com')}

`); + expect(Markdown.format('taco.what://example.com').trim()).toBe(`

${link('taco.what://example.com')}

`); }); test('explicit links are not affected by this setting', () => { - const options = { - autolinkedUrlSchemes: [], - }; + jest.spyOn(store, 'getState').mockReturnValue(makeInitialState({ + entities: { + general: { + config: { + CustomUrlSchemes: '', + }, + }, + }, + })); - expect(Markdown.format('www.example.com', options).trim()).toBe(`

${link('http://www.example.com', 'www.example.com')}

`); + expect(Markdown.format('www.example.com').trim()).toBe(`

${link('http://www.example.com', 'www.example.com')}

`); - expect(Markdown.format('[link](git://git.example.com)', options).trim()).toBe(`

${link('git://git.example.com', 'link')}

`); + expect(Markdown.format('[link](git://git.example.com)').trim()).toBe(`

${link('git://git.example.com', 'link')}

`); - expect(Markdown.format('', options).trim()).toBe(`

${link('http://example.com')}

`); + expect(Markdown.format('').trim()).toBe(`

${link('git://git.example.com')}

`); }); }); }); diff --git a/webapp/package-lock.json b/webapp/package-lock.json index 30335c62dc..4e6e30c49d 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -105,7 +105,7 @@ "lodash": "4.17.21", "luxon": "3.6.1", "mark.js": "8.11.1", - "marked": "github:mattermost/marked#3b13ba8ddf725327ddf0298361d6d304a021f2d1", + "marked": "github:mattermost/marked#08f3638e37e17738fafcaf749683ce6fee1d8edc", "memoize-one": "6.0.0", "moment-timezone": "0.5.38", "monaco-editor": "0.52.2", @@ -20662,8 +20662,8 @@ }, "node_modules/marked": { "version": "0.3.6", - "resolved": "git+ssh://git@github.com/mattermost/marked.git#3b13ba8ddf725327ddf0298361d6d304a021f2d1", - "integrity": "sha512-/G1/szBhwdamaCQQjdk+eKQKw4Xkmk8aQYxEQvIjfbcFHEaIgUbpH6RBSC+b0pDzlhm7mxHAaGnzfH3WqUks1Q==", + "resolved": "git+ssh://git@github.com/mattermost/marked.git#08f3638e37e17738fafcaf749683ce6fee1d8edc", + "integrity": "sha512-zaU3iMz9BuvdYUjAF4zL0ioAstBgFI+xUgO5BNaEDGI+cXoXcRa5X2Bq0uA7Xn6NSQi0X04Xn5EuH+pxhvIllQ==", "license": "MIT", "bin": { "marked": "bin/marked"