Skip to content
Snippets Groups Projects
Commit 0eb3c3d7 authored by Damian Janus's avatar Damian Janus
Browse files

fix: add needed atribute to a tag attributes array allowed to sanitize

parent b06c3650
No related branches found
No related tags found
1 merge request!557Move hive renderer to internal packages
import react = require("react");
import _ = require("lodash");
/**
* Regular expressions for detecting and validating provider URLs
* @type {{htmlReplacement: RegExp, main: RegExp, sanitize: RegExp}}
*/
//<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Calling parents struggling with juggling act of kids &lt; 3yrs + additional needs, + shielding risk parent + demanding jobs? How are you coping? What changes have you made? Advice appreciated! Hubs &amp; I are beyond exhausted!</p>&mdash; Kuldeep Bahia (@missybahia) <a href="https://twitter.com/missybahia/status/1281295770298318849?ref_src=twsrc%5Etfw">July 9, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
const regex = {
main: /(?:https?:\/\/(?:(?:twitter\.com\/(.*?)\/status\/(.*))))/i,
sanitize: /(?:https?:\/\/(?:(?:twitter\.com\/(.*?)\/status\/(.*))))/i,
htmlReplacement:
/<blockquote[^>]*?><p[^>]*?>(.*?)<\/p>.*?mdash; (.*)<a href="(https:\/\/twitter\.com\/.*?(.*?\/status\/(.*?))\?.*?)">(.*?)<\/a><\/blockquote>/i,
};
export default regex;
/**
* Configuration for HTML iframe's `sandbox` attribute
* @type {useSandbox: boolean, sandboxAttributes: string[]}
*/
export const sandboxConfig = {
useSandbox: false,
sandboxAttributes: [],
};
/**
* Extract the content ID and other metadata from the URL
* @param data
* @returns {null|{id: *, canonical: string, url: *}}
*/
export function extractMetadataFromEmbedCode(data: string) {
if (!data) return null;
const match = data.match(regex.htmlReplacement);
if (match) {
const description = match[1];
const author = match[2];
const url = match[3];
const fullId = match[4];
const id = match[5];
const date = match[5];
return {
id,
fullId,
url,
canonical: url,
thumbnail: null,
date,
author,
description,
};
}
return null;
}
/**
* Extract the content ID and other metadata from the URL
* @param data
* @returns {null|{id: *, canonical: string, url: *}}
*/
export function extractMetadata(data: string) {
if (!data) return null;
const match = data.match(regex.main);
if (match) {
const url = match[0];
const author = match[1];
const id = match[2];
return {
id,
fullId: id,
url,
canonical: null,
thumbnail: null,
date: "",
author,
description: "",
};
}
return null;
}
/**
* Check if the iframe code in the post editor is to an allowed URL
* @param url
* @returns {boolean|*}
*/
export function validateIframeUrl(url: string) {
const match = url.match(regex.sanitize);
if (match) {
return url;
}
return false;
}
/**
* Rewrites the embedded URL to a normalized format
* @param url
* @returns {string|boolean}
*/
export function normalizeEmbedUrl(url: string) {
const match = url.match(regex.main);
if (match && match.length >= 2) {
const tweetId = match[2].split("?").shift();
return `https://twitter.com/${match[1]}/status/${tweetId}`;
}
return false;
}
function generateTwitterCode(
metadata: WithImplicitCoercion<string> | { [Symbol.toPrimitive](hint: "string"): string },
) {
let twitterCode =
'<blockquote className="twitter-tweet"><p lang="en" dir="ltr"></p>&mdash; <a href=""></a></blockquote>';
if (metadata) {
let [author, date, url, description] = Buffer.from(metadata, "base64").toString().split("|");
// Sanitizing input
author = author.replace(/(<([^>]+)>)/gi, "");
date = date.replace(/(<([^>]+)>)/gi, "");
url = url.replace(/(<([^>]+)>)/gi, "");
description = description.replace(/(<([^>]+)>)/gi, "");
if (description === "") {
description = url;
}
twitterCode =
'<blockquote class="twitter-tweet">' +
`<p lang="en" dir="ltr">${description}</p>` +
`&mdash; ${author} <a href="${url}">${date}</a>` +
"</blockquote>";
const twttr = _.get(window, "twttr");
if (twttr && twttr.widgets) {
twttr.widgets.load();
}
}
return {
__html: twitterCode,
};
}
/**
* Generates the Markdown/HTML code to override the detected URL with an iFrame
* @param idx
* @param threespeakId
* @param w
* @param h
* @returns {*}
*/
export function genIframeMd(idx: any, twitterId: any, w: any, h: any, metadata: any) {
if (typeof window !== "undefined") {
return (
<div
key={`twitter-${twitterId}-${idx}`}
className="tweetWrapper"
dangerouslySetInnerHTML={generateTwitterCode(metadata)}
/>
);
}
return null;
}
/**
* Replaces the URL with a custom Markdown for embedded players
* @param child
* @param links
* @returns {*}
*/
export function embedNode(child: { data: any }) {
try {
const { data } = child;
const twitter = extractMetadata(data);
if (twitter) {
const metadata = `${twitter.author}|${twitter.date}|${twitter.url}|${twitter.description}`;
child.data = data.replace(
regex.main,
`~~~ embed:${twitter.id} twitter metadata:${Buffer.from(metadata).toString("base64")} ~~~`,
);
}
} catch (error) {
console.log(error);
}
return child;
}
/**
* Pre-process HTML codes from the Markdown before it gets transformed
* @param child
* @returns {string}
*/
export function preprocessHtml(child: string) {
try {
if (typeof child === "string") {
// If typeof child is a string, this means we are trying to process the HTML
// to replace the image/anchor tag created by 3Speak dApp
const twitter = extractMetadataFromEmbedCode(child);
if (twitter) {
const metadata = `${twitter.author}|${twitter.date}|${twitter.url}|${twitter.description}`;
child = child.replace(
regex.htmlReplacement,
`~~~ embed:${twitter.id} twitter metadata:${Buffer.from(metadata).toString("base64")} ~~~`,
);
}
}
} catch (error) {
console.log(error);
}
return child;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment