Stories: Only render text link if it's a valid URL
This commit is contained in:
parent
2ee7b18d33
commit
733c5b598f
3 changed files with 40 additions and 3 deletions
|
@ -12,7 +12,7 @@ import { Emojify } from './conversation/Emojify';
|
||||||
import { StoryLinkPreview } from './StoryLinkPreview';
|
import { StoryLinkPreview } from './StoryLinkPreview';
|
||||||
import { TextAttachmentStyleType } from '../types/Attachment';
|
import { TextAttachmentStyleType } from '../types/Attachment';
|
||||||
import { count } from '../util/grapheme';
|
import { count } from '../util/grapheme';
|
||||||
import { getSafeDomain } from '../types/LinkPreview';
|
import { isValidLink, getSafeDomain } from '../types/LinkPreview';
|
||||||
import { getFontNameByTextScript } from '../util/getFontNameByTextScript';
|
import { getFontNameByTextScript } from '../util/getFontNameByTextScript';
|
||||||
import {
|
import {
|
||||||
COLOR_WHITE_INT,
|
COLOR_WHITE_INT,
|
||||||
|
@ -197,7 +197,7 @@ export const TextAttachment = forwardRef<HTMLTextAreaElement, PropsType>(
|
||||||
the story, but it must be positioned using the scaled offset
|
the story, but it must be positioned using the scaled offset
|
||||||
*/}
|
*/}
|
||||||
{textAttachment.preview &&
|
{textAttachment.preview &&
|
||||||
textAttachment.preview.url &&
|
isValidLink(textAttachment.preview.url) &&
|
||||||
linkPreviewOffsetTop &&
|
linkPreviewOffsetTop &&
|
||||||
!isThumbnail && (
|
!isThumbnail && (
|
||||||
<a
|
<a
|
||||||
|
|
|
@ -5,12 +5,36 @@ import { assert } from 'chai';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
findLinks,
|
findLinks,
|
||||||
|
isLinkSneaky,
|
||||||
|
isValidLink,
|
||||||
shouldLinkifyMessage,
|
shouldLinkifyMessage,
|
||||||
shouldPreviewHref,
|
shouldPreviewHref,
|
||||||
isLinkSneaky,
|
|
||||||
} from '../../types/LinkPreview';
|
} from '../../types/LinkPreview';
|
||||||
|
|
||||||
describe('Link previews', () => {
|
describe('Link previews', () => {
|
||||||
|
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', () => {
|
describe('#shouldPreviewHref', () => {
|
||||||
it('returns false for invalid URLs', () => {
|
it('returns false for invalid URLs', () => {
|
||||||
assert.isFalse(shouldPreviewHref(''));
|
assert.isFalse(shouldPreviewHref(''));
|
||||||
|
|
|
@ -48,6 +48,19 @@ export type AddLinkPreviewOptionsType = Readonly<{
|
||||||
|
|
||||||
const linkify = LinkifyIt();
|
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 {
|
export function shouldPreviewHref(href: string): boolean {
|
||||||
const url = maybeParseUrl(href);
|
const url = maybeParseUrl(href);
|
||||||
return Boolean(
|
return Boolean(
|
||||||
|
|
Loading…
Reference in a new issue