Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
if (!defined(markdownString) || markdownString.length === 0) {
return markdownString;
}
// If the text looks like html, don't try to interpret it as Markdown because
// we'll probably break it in the process.
var unsafeHtml;
if (htmlRegex.test(markdownString)) {
unsafeHtml = markdownString;
} else {
// Note this would wrap non-standard tags such as hi in a <p></p>, which is bad.
unsafeHtml = md.render(markdownString);
}
if (allowUnsafeHtml) {
return unsafeHtml;
} else {
return DOMPurify.sanitize(unsafeHtml, options);
}
}
let suffixText = option[this.labelSuffixName] || '';
let optionLabel = option[this.optionLabel] || '';
optionLabel = optionLabel.toString().replace(/\"/g, '\''); // replace double quotes by single quotes to avoid interfering with regular html
// also translate prefix/suffix if enableTranslateLabel is true and text is a string
prefixText = (this.enableTranslateLabel && prefixText && typeof prefixText === 'string') ? this.i18n.tr(prefixText || ' ') : prefixText;
suffixText = (this.enableTranslateLabel && suffixText && typeof suffixText === 'string') ? this.i18n.tr(suffixText || ' ') : suffixText;
optionLabel = (this.enableTranslateLabel && optionLabel && typeof optionLabel === 'string') ? this.i18n.tr(optionLabel || ' ') : optionLabel;
// add to a temp array for joining purpose and filter out empty text
const tmpOptionArray = [prefixText, labelText, suffixText].filter((text) => text);
let optionText = tmpOptionArray.join(separatorBetweenLabels);
// if user specifically wants to render html text, he needs to opt-in else it will stripped out by default
// also, the 3rd party lib will saninitze any html code unless it's encoded, so we'll do that
if (isRenderHtmlEnabled) {
// sanitize any unauthorized html tags like script and others
// for the remaining allowed tags we'll permit all attributes
const sanitizedText = DOMPurify.sanitize(optionText, sanitizedOptions);
optionText = htmlEncode(sanitizedText);
}
// html text of each select option
options += `<option label="${optionLabel}" value="${option[this.valueName]}">${optionText}</option>`;
// if there's a search term, we will add the "filled" class for styling purposes
if (selected) {
this.isFilled = true;
}
});
}
// test api keys, will be replaced with environment vars when time comes to productionise
this.contentfulClient = contentful.createClient({
space: process.env.CONTENTFUL_SPACE,
accessToken: process.env.CONTENTFUL_TOKEN,
});
marked.setOptions({
highlight: (code) => { return highlightjs.highlightAuto(code).value; },
});
const window = jsdom.jsdom('', {
features: {
FetchExternalResources: false,
ProcessExternalResources: false,
},
}).defaultView;
this.DOMPurify = createDOMPurify(window);
this.preloadedState = {
activePage: {
page: {
fields: {
name: null,
route: null,
},
},
route: null,
title: null,
isLoading: true,
hasErrored: false,
},
utils: {
drawerOpen: false,
export const countHandler = ({ mongo, i18n }: CountOptions): RequestHandler => {
const window = new JSDOM("").window;
const DOMPurify = createDOMPurify(window);
return async (req, res, next) => {
try {
// Tenant is guaranteed at this point.
const coral = req.coral!;
const tenant = coral.tenant!;
const story = await find(mongo, tenant, {
id: req.query.id,
url: req.query.url,
});
if (!story) {
throw new Error("Story not found");
}
const count = calculateTotalPublishedCommentCount(
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @flow
* @format
*/
import invariant from 'assert';
import * as React from 'react';
import {shell} from 'electron';
import createDOMPurify from 'dompurify';
const domPurify = createDOMPurify();
type DiagnosticsMessageTextProps = {
preserveNewlines?: boolean, // defaults to true
message: {
html?: string,
text?: string,
},
};
type UrlOrText =
| {
isUrl: true,
url: string,
}
| {
isUrl: false,
import Autolinker from 'autolinker';
import createDOMPurify from 'dompurify';
import Twemoji from 'twemoji';
import { NOTIF_TYPES } from '../consts/types';
import EmojiData from './emojis.json';
const DOMPurify = createDOMPurify(window);
export const getRandomInt = () => Math.floor(Math.random() * ((3000 - 0) + 1));
export const getUID = () => 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
let r = Math.random() * 16 | 0, //eslint-disable-line
v = c == 'x' ? r : (r & 0x3 | 0x8); //eslint-disable-line
return v.toString(16);
});
// eslint-disable-next-line
export const escapeRegExp = str => str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
export const getNotifText = (type, username, isCollab = false) => {
switch (type) {
case NOTIF_TYPES.COMMENT.MENTION:
import styled from 'styled-components';
import tw from 'tailwind.macro';
import { createFragmentContainer, graphql } from 'react-relay';
import Head from 'next/head';
import Link from 'next/link';
import format from 'date-fns/format';
import { Value } from 'slate';
import Html from 'slate-html-serializer';
import DOMPurify from 'dompurify';
import { TiSocialFacebook, TiSocialTwitter } from 'react-icons/ti';
import { config } from '../../config';
import { PublicStory_story } from './__generated__/PublicStory_story.graphql';
import { getProfileRoute } from '../../utils/routes';
import { Container } from '../../components';
let dompurify = DOMPurify();
// During ssr we need jsdom to make dompurify work
if (typeof window === 'undefined') {
/* eslint-disable @typescript-eslint/no-var-requires */
const { JSDOM } = require('jsdom');
const { window } = new JSDOM('');
dompurify = DOMPurify(window);
}
const StoryContainer = styled(Container)`
${tw`py-8`};
max-width: 768px;
@media (min-width: ${config.breakpoints.sm}px) {
${tw`py-16`};
}
import createDOMPurify from 'dompurify';
import ActionPipelineManager from './action-pipeline';
import {GitError} from './git-shell-out-strategy';
import {deleteFileOrFolder, getCommitMessagePath, getCommitMessageEditors, destroyFilePatchPaneItems} from './helpers';
const DOMPurify = createDOMPurify();
// Note: Middleware that catches errors should re-throw the errors so that they propogate
// and other middleware in the pipeline can be made aware of the errors.
// Ultimately, the views are responsible for catching the errors and handling them accordingly
export default function({confirm, notificationManager, workspace}) {
const pipelineManager = new ActionPipelineManager({
actionNames: ['PUSH', 'PULL', 'FETCH', 'COMMIT', 'CHECKOUT'],
});
const pushPipeline = pipelineManager.getPipeline(pipelineManager.actionKeys.PUSH);
pushPipeline.addMiddleware('confirm-force-push', async (next, repository, branchName, options) => {
if (options.force) {
const choice = confirm({
message: 'Are you sure you want to force push?',
detailedMessage: 'This operation could result in losing data on the remote.',
}
});
const ISOTOPE_WHITELISTED_URL = '#IsotopeEmbedded';
// 1/2 Replaces "insecure" blob: uris before sanitation for controlled ones
sanitize.addHook('uponSanitizeAttribute', (node, hookEvent) => {
if (node.nodeName === 'IMG' && hookEvent.attrName === 'src' && hookEvent.attrValue.indexOf('blob:') === 0) {
node.src = `${node.src.substring(5)}${ISOTOPE_WHITELISTED_URL}`;
hookEvent.attrValue = node.src;
}
});
// 2/2 Replaces previously parsed "insecure" urls to original ones -> Whitelist effect
// Hides cid: images that are being loaded
sanitize.addHook('afterSanitizeAttributes', node => {
if (node.nodeName === 'IMG' && node.src && node.src.indexOf(ISOTOPE_WHITELISTED_URL) > -1) {
node.src = `blob:${node.src.replace(ISOTOPE_WHITELISTED_URL, '')}`;
}
if (node.nodeName === 'IMG' && node.src && node.src.indexOf('cid:') === 0) {
const spinner = document.createElement('div');
spinner.innerHTML = ReactDOMServer.renderToStaticMarkup(renderSpinner());
spinner.getElementsByClassName('canvas')[0].style.height = node.height ? node.height : '22px';
node.parentElement.replaceChild(spinner, node);
}
});
export default sanitize;
export function domPurifyOpenLinksInNewWindow() {
// Add a hook to make all DOMPurify'd links open a new window
// See: https://github.com/cure53/DOMPurify/tree/master/demos#hook-to-open-all-links-in-a-new-window-link
DOMPurify.addHook('afterSanitizeAttributes', function(node: any) {
// set all elements owning target to target=_blank
if ('target' in node) {
node.setAttribute('target', '_blank');
// prevent https://www.owasp.org/index.php/Reverse_Tabnabbing
node.setAttribute('rel', 'noopener noreferrer');
}
// set non-HTML/MathML links to xlink:show=new
if (!node.hasAttribute('target') && (node.hasAttribute('xlink:href') || node.hasAttribute('href'))) {
node.setAttribute('xlink:show', 'new');
}
return node;
});
}