Skip to content

Commit

Permalink
Allow story to embedded video sources from Youtube only.
Browse files Browse the repository at this point in the history
  • Loading branch information
mwu2018 committed Sep 6, 2023
1 parent ca067f9 commit d43e572
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 14 deletions.
65 changes: 57 additions & 8 deletions lib/ReactViews/Story/StoryPanel/StoryBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import parseCustomHtmlToReact from "../../Custom/parseCustomHtmlToReact";
import styled from "styled-components";
import Box from "../../../Styled/Box";
import Text from "../../../Styled/Text";
import URI from "urijs";

const StoryContainer = styled(Box).attrs((props: { isCollapsed: boolean }) => ({
paddedVertically: props.isCollapsed ? 0 : 2,
Expand Down Expand Up @@ -45,6 +46,61 @@ const StoryContainer = styled(Box).attrs((props: { isCollapsed: boolean }) => ({
}
`;

const allowedStoryBodyIframeSources = ["https://www.youtube.com"];

function extractIframeSources(text: string): string[] {
const startString = '<iframe src="';
const endString = " ";
const regexPattern = new RegExp(`${startString}(.*?)${endString}`, "g");
const matches = text.match(regexPattern);
const sources = [];

if (matches) {
for (const match of matches) {
const substring = match.substring(
startString.length,
match.length - endString.length
);
const uri = new URI(substring);
sources.push(uri.protocol() + "://" + uri.hostname());
}
}

return sources;
}

function areSourcesAllowed(story: Story) {
const text = story.text;
const sources = extractIframeSources(text);
let result = true;
for (let source of sources) {
if (!allowedStoryBodyIframeSources.includes(source)) result = false;
break;
}

return result;
}

function sourceBasedParse(story: Story) {
if (areSourcesAllowed(story)) {
return parseCustomHtmlToReact(
story.text,
{ showExternalLinkWarning: true },
false,
{
ADD_TAGS: ["iframe"]
}
);
} else {
return parseCustomHtmlToReact(
story.text,
{ showExternalLinkWarning: true },
false,
{}
);
}
}

const StoryBody = ({
isCollapsed,
story
Expand All @@ -63,14 +119,7 @@ const StoryBody = ({
`}
medium
>
{parseCustomHtmlToReact(
story.text,
{ showExternalLinkWarning: true },
false,
{
ADD_TAGS: ["iframe"]
}
)}
{sourceBasedParse(story)}
</Text>
</StoryContainer>
) : null}
Expand Down
14 changes: 8 additions & 6 deletions test/ReactViews/Story/StoryPanel/StoryBodySpec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ import {
describe("StoryBody", function () {
let testRenderer: ReactTestRenderer;

it("should include embedded media using iframe tag", function () {
it("should include embedded media using iframe tag with allowed source", function () {
// Story editor will only save embedded video with source, width and height.
const theStory = {
id: "some id",
title: "test",
text: 'Story with video. <iframe title="My Title" width="560" height="315" src="https://some.video.link"></iframe>'
text: 'Story with video. <iframe src="https://www.youtube.com/embed/1234" width="560" height="315"></iframe>'
};

act(() => {
Expand All @@ -37,17 +38,18 @@ describe("StoryBody", function () {

const theIframeInstance = theInstance.children[1] as ReactTestInstance;
expect(theIframeInstance.type).toBe("iframe");
expect(theIframeInstance.props.title).toBe("My Title");
expect(theIframeInstance.props.src).toBe("https://some.video.link");
expect(theIframeInstance.props.src).toBe(
"https://www.youtube.com/embed/1234"
);
expect(theIframeInstance.props.width).toBe("560");
expect(theIframeInstance.props.height).toBe("315");
});

it("should exclude embedded media using unsafe tag", function () {
it("should exclude embedded media using iframe tag with any forbidden sources", function () {
const theStory = {
id: "some id",
title: "test",
text: 'Story with video. <iframe2 width="560" height="315" src="https://some.video.link"></iframe2>'
text: 'Story with video. <iframe src="https://www.youtube.com/embed/ title="My Title" width="560" height="315""></iframe> <iframe src="https://some.video.link" width="560" height="315" "></iframe>'
};

act(() => {
Expand Down

0 comments on commit d43e572

Please sign in to comment.