Add DOMPurify
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import * as DOMPurify from 'dompurify';
|
||||
import React from 'react';
|
||||
|
||||
import Markup from 'soapbox/components/markup';
|
||||
@@ -9,7 +10,7 @@ import { LogoText } from './logo-text';
|
||||
|
||||
const SiteBanner: React.FC = () => {
|
||||
const instance = useInstance();
|
||||
const description = instance.description;
|
||||
const description = DOMPurify.sanitize(instance.description);
|
||||
|
||||
return (
|
||||
<Stack space={3}>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/**
|
||||
* Status edit normalizer
|
||||
*/
|
||||
*/
|
||||
import * as DOMPurify from 'dompurify';
|
||||
import escapeTextContentForBrowser from 'escape-html';
|
||||
import {
|
||||
Map as ImmutableMap,
|
||||
@@ -60,8 +61,8 @@ const normalizeStatusPoll = (statusEdit: ImmutableMap<string, any>) => {
|
||||
|
||||
const normalizeContent = (statusEdit: ImmutableMap<string, any>) => {
|
||||
const emojiMap = makeEmojiMap(statusEdit.get('emojis'));
|
||||
const contentHtml = stripCompatibilityFeatures(emojify(statusEdit.get('content'), emojiMap));
|
||||
const spoilerHtml = emojify(escapeTextContentForBrowser(statusEdit.get('spoiler_text')), emojiMap);
|
||||
const contentHtml = DOMPurify.sanitize(stripCompatibilityFeatures(emojify(statusEdit.get('content'), emojiMap)), { ADD_ATTR: ['target'] });
|
||||
const spoilerHtml = DOMPurify.sanitize(emojify(escapeTextContentForBrowser(statusEdit.get('spoiler_text')), emojiMap), { ADD_ATTR: ['target'] });
|
||||
|
||||
return statusEdit
|
||||
.set('contentHtml', contentHtml)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import * as DOMPurify from 'dompurify';
|
||||
import escapeTextContentForBrowser from 'escape-html';
|
||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
||||
|
||||
@@ -117,8 +118,8 @@ export const calculateStatus = (
|
||||
|
||||
return status.merge({
|
||||
search_index: domParser.parseFromString(searchContent, 'text/html').documentElement.textContent || '',
|
||||
contentHtml: stripCompatibilityFeatures(emojify(status.content, emojiMap)),
|
||||
spoilerHtml: emojify(escapeTextContentForBrowser(spoilerText), emojiMap),
|
||||
contentHtml: DOMPurify.sanitize(stripCompatibilityFeatures(emojify(status.content, emojiMap)), { USE_PROFILES: { html: true } }),
|
||||
spoilerHtml: DOMPurify.sanitize(emojify(escapeTextContentForBrowser(spoilerText), emojiMap), { USE_PROFILES: { html: true } }),
|
||||
hidden: expandSpoilers ? false : spoilerText.length > 0 || status.sensitive,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import * as DOMPurify from 'dompurify';
|
||||
import escapeTextContentForBrowser from 'escape-html';
|
||||
import z from 'zod';
|
||||
|
||||
@@ -112,7 +113,7 @@ const transformAccount = <T extends TransformableAccount>({ pleroma, other_setti
|
||||
|
||||
const newFields = fields.map((field) => ({
|
||||
...field,
|
||||
name_emojified: emojify(escapeTextContentForBrowser(field.name), customEmojiMap),
|
||||
name_emojified: DOMPurify.sanitize(emojify(escapeTextContentForBrowser(field.name), customEmojiMap), { USE_PROFILES: { html: true } }),
|
||||
value_emojified: emojify(field.value, customEmojiMap),
|
||||
value_plain: unescapeHTML(field.value),
|
||||
}));
|
||||
@@ -130,7 +131,7 @@ const transformAccount = <T extends TransformableAccount>({ pleroma, other_setti
|
||||
avatar_static: account.avatar_static || account.avatar,
|
||||
discoverable: account.discoverable || account.source?.pleroma?.discoverable || false,
|
||||
display_name: displayName,
|
||||
display_name_html: emojify(escapeTextContentForBrowser(displayName), customEmojiMap),
|
||||
display_name_html: DOMPurify.sanitize(emojify(escapeTextContentForBrowser(displayName), customEmojiMap), { USE_PROFILES: { html: true } }),
|
||||
domain,
|
||||
fields: newFields,
|
||||
fqn: account.fqn || (account.acct.includes('@') ? account.acct : `${account.acct}@${domain}`),
|
||||
@@ -138,7 +139,7 @@ const transformAccount = <T extends TransformableAccount>({ pleroma, other_setti
|
||||
moderator: pleroma?.is_moderator || false,
|
||||
local: pleroma?.is_local !== undefined ? pleroma.is_local : account.acct.split('@')[1] === undefined,
|
||||
location: account.location || pleroma?.location || other_settings?.location || '',
|
||||
note_emojified: emojify(account.note, customEmojiMap),
|
||||
note_emojified: DOMPurify.sanitize(emojify(account.note, customEmojiMap), { USE_PROFILES: { html: true } }),
|
||||
pleroma: (() => {
|
||||
if (!pleroma) return undefined;
|
||||
const { relationship, ...rest } = pleroma;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import * as DOMPurify from 'dompurify';
|
||||
import escapeTextContentForBrowser from 'escape-html';
|
||||
import { z } from 'zod';
|
||||
|
||||
@@ -30,7 +31,7 @@ const pollSchema = z.object({
|
||||
|
||||
const emojifiedOptions = poll.options.map((option) => ({
|
||||
...option,
|
||||
title_emojified: emojify(escapeTextContentForBrowser(option.title), emojiMap),
|
||||
title_emojified: DOMPurify.sanitize(emojify(escapeTextContentForBrowser(option.title), emojiMap), { ALLOWED_TAGS: [] }),
|
||||
}));
|
||||
|
||||
// If the user has votes, they have certainly voted.
|
||||
|
||||
Reference in New Issue
Block a user