diff --git a/ts/components/TextAttachment.tsx b/ts/components/TextAttachment.tsx index 286b9581fe2a..0fb90ae9cb3b 100644 --- a/ts/components/TextAttachment.tsx +++ b/ts/components/TextAttachment.tsx @@ -12,7 +12,7 @@ import { Emojify } from './conversation/Emojify'; import { StoryLinkPreview } from './StoryLinkPreview'; import { TextAttachmentStyleType } from '../types/Attachment'; import { count } from '../util/grapheme'; -import { getSafeDomain } from '../types/LinkPreview'; +import { isValidLink, getSafeDomain } from '../types/LinkPreview'; import { getFontNameByTextScript } from '../util/getFontNameByTextScript'; import { COLOR_WHITE_INT, @@ -197,7 +197,7 @@ export const TextAttachment = forwardRef( the story, but it must be positioned using the scaled offset */} {textAttachment.preview && - textAttachment.preview.url && + isValidLink(textAttachment.preview.url) && linkPreviewOffsetTop && !isThumbnail && ( { + describe('#isValidLink', () => { + it('returns false for random, non-https URLs', () => { + assert.isFalse(isValidLink('')); + assert.isFalse(isValidLink('signal.com')); + assert.isFalse(isValidLink('signal.org')); + assert.isFalse(isValidLink('https')); + assert.isFalse(isValidLink('https://')); + assert.isFalse(isValidLink('https://bad url')); + assert.isFalse(isValidLink('http://signal.org')); + }); + + it('returns true for https:// URLs', () => { + assert.isTrue(isValidLink('https://signal.org')); + assert.isTrue(isValidLink('https://somewhere.someplace.signal.org/')); + assert.isTrue(isValidLink('https://signal.org/something/another/#thing')); + assert.isTrue( + isValidLink( + 'https://signal.org/something/another/?one=two&three=four#thing' + ) + ); + }); + }); + describe('#shouldPreviewHref', () => { it('returns false for invalid URLs', () => { assert.isFalse(shouldPreviewHref('')); diff --git a/ts/types/LinkPreview.ts b/ts/types/LinkPreview.ts index d8c93d9be642..f5765d1c08d1 100644 --- a/ts/types/LinkPreview.ts +++ b/ts/types/LinkPreview.ts @@ -48,6 +48,19 @@ export type AddLinkPreviewOptionsType = Readonly<{ const linkify = LinkifyIt(); +export function isValidLink(maybeUrl: string | undefined): boolean { + if (maybeUrl == null) { + return false; + } + + try { + const url = new URL(maybeUrl); + return url.protocol === 'https:'; + } catch (_error) { + return false; + } +} + export function shouldPreviewHref(href: string): boolean { const url = maybeParseUrl(href); return Boolean(