XSS and Reduced Markdown for Admin (#355)
This commit is contained in:
parent
1ae519e251
commit
a043c2dfa6
|
@ -106,7 +106,7 @@
|
|||
"webpack-cli": "^3.1.0",
|
||||
"webpack-dev-server": "3.2.1",
|
||||
"webpack-hot-middleware": "^2.24.0",
|
||||
"xss": "1.0.3"
|
||||
"xss": "^1.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bn.js": "4.11.1",
|
||||
|
|
|
@ -5,12 +5,13 @@ import './index.less';
|
|||
|
||||
interface Props extends React.HTMLAttributes<HTMLDivElement> {
|
||||
source: string;
|
||||
reduced?: boolean;
|
||||
}
|
||||
|
||||
export default class Markdown extends React.PureComponent<Props> {
|
||||
render() {
|
||||
const { source, ...rest } = this.props;
|
||||
const html = mdToHtml(source);
|
||||
const { source, reduced, ...rest } = this.props;
|
||||
const html = mdToHtml(source, reduced);
|
||||
// TS types seem to be fighting over react prop defs for div
|
||||
const divProps = rest as any;
|
||||
return (
|
||||
|
|
|
@ -54,7 +54,7 @@ class ModerationItem extends React.Component<Comment> {
|
|||
}
|
||||
description={
|
||||
<ShowMore height={100}>
|
||||
<Markdown source={p.content} />
|
||||
<Markdown source={p.content} reduced />
|
||||
</ShowMore>
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -270,7 +270,11 @@ class UserDetailNaked extends React.Component<Props, State> {
|
|||
</Link>{' '}
|
||||
at {formatDateMs(c.dateCreated)}
|
||||
</div>
|
||||
<Markdown source={c.content} className="UserDetail-comment" />
|
||||
<Markdown
|
||||
source={c.content}
|
||||
reduced
|
||||
className="UserDetail-comment"
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Showdown from 'showdown';
|
||||
import xss from 'xss';
|
||||
|
||||
const showdownConverter = new Showdown.Converter({
|
||||
simplifiedAutoLink: true,
|
||||
|
@ -9,6 +10,41 @@ const showdownConverter = new Showdown.Converter({
|
|||
excludeTrailingPunctuationFromURLs: true,
|
||||
});
|
||||
|
||||
export const mdToHtml = (text: string) => {
|
||||
return showdownConverter.makeHtml(text);
|
||||
export const mdToHtml = (text: string, reduced: boolean = false) => {
|
||||
const html = showdownConverter.makeHtml(text);
|
||||
return reduced ? xss(html, reducedXssOpts) : xss(html);
|
||||
};
|
||||
|
||||
const reducedXssOpts = {
|
||||
stripIgnoreTag: true,
|
||||
whiteList: {
|
||||
a: ['target', 'href', 'title'],
|
||||
b: [],
|
||||
blockquote: [],
|
||||
br: [],
|
||||
code: [],
|
||||
del: [],
|
||||
em: [],
|
||||
h4: [],
|
||||
h5: [],
|
||||
h6: [],
|
||||
hr: [],
|
||||
i: [],
|
||||
li: [],
|
||||
ol: [],
|
||||
p: [],
|
||||
pre: [],
|
||||
small: [],
|
||||
sub: [],
|
||||
sup: [],
|
||||
strong: [],
|
||||
table: ['width', 'border', 'align', 'valign'],
|
||||
tbody: ['align', 'valign'],
|
||||
td: ['width', 'rowspan', 'colspan', 'align', 'valign'],
|
||||
tfoot: ['align', 'valign'],
|
||||
th: ['width', 'rowspan', 'colspan', 'align', 'valign'],
|
||||
thead: ['align', 'valign'],
|
||||
tr: ['rowspan', 'align', 'valign'],
|
||||
ul: [],
|
||||
},
|
||||
};
|
||||
|
|
|
@ -8477,9 +8477,10 @@ xregexp@4.0.0:
|
|||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020"
|
||||
|
||||
xss@1.0.3:
|
||||
xss@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/xss/-/xss-1.0.3.tgz#d04bd2558fd6c29c46113824d5e8b2a910054e23"
|
||||
integrity sha512-LTpz3jXPLUphMMmyufoZRSKnqMj41OVypZ8uYGzvjkMV9C1EdACrhQl/EM8Qfh5htSAuMIQFOejmKAZGkJfaCg==
|
||||
dependencies:
|
||||
commander "^2.9.0"
|
||||
cssfilter "0.0.10"
|
||||
|
|
|
@ -385,6 +385,8 @@ def make_envelope(to, type, email_args):
|
|||
|
||||
|
||||
def sendgrid_send(mail):
|
||||
to = mail.___to
|
||||
type = mail.___type
|
||||
try:
|
||||
sg = sendgrid.SendGridAPIClient(apikey=SENDGRID_API_KEY)
|
||||
res = sg.client.mail.send.post(request_body=mail.get())
|
||||
|
|
Loading…
Reference in New Issue