mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-24 18:56:32 -05:00
enhancement(renderer): custom uri protocols in links except scripts
Signed-off-by: Erik Michelson <github@erik.michelson.eu>
This commit is contained in:
parent
9d55c5ee53
commit
4b8f6da78a
3 changed files with 63 additions and 2 deletions
|
@ -27,4 +27,40 @@ exports[`HTML to React will forward the parser options 1`] = `
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`HTML to React will render links with non-http protocols 1`] = `
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
href="tel:+1234567890"
|
||||||
|
>
|
||||||
|
tel
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="mailto:test@example.com"
|
||||||
|
>
|
||||||
|
mailto
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="geo:25.197,55.274"
|
||||||
|
>
|
||||||
|
geo
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="xmpp:test"
|
||||||
|
>
|
||||||
|
xmpp
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`HTML to React won't render script links 1`] = `
|
||||||
|
<div>
|
||||||
|
<a>
|
||||||
|
js
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
vbs
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`HTML to React won't render script tags 1`] = `<div />`;
|
exports[`HTML to React won't render script tags 1`] = `<div />`;
|
||||||
|
|
|
@ -17,6 +17,24 @@ describe('HTML to React', () => {
|
||||||
expect(view.container).toMatchSnapshot()
|
expect(view.container).toMatchSnapshot()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("won't render script links", () => {
|
||||||
|
const view = render(
|
||||||
|
<HtmlToReact htmlCode={'<a href="javascript:alert(true)">js</a><a href="vbscript:WScript.Evil">vbs</a>'} />
|
||||||
|
)
|
||||||
|
expect(view.container).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('will render links with non-http protocols', () => {
|
||||||
|
const view = render(
|
||||||
|
<HtmlToReact
|
||||||
|
htmlCode={
|
||||||
|
'<a href="tel:+1234567890">tel</a><a href="mailto:test@example.com">mailto</a><a href="geo:25.197,55.274">geo</a><a href="xmpp:test">xmpp</a>'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
expect(view.container).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
it('will forward the DomPurify settings', () => {
|
it('will forward the DomPurify settings', () => {
|
||||||
const view = render(
|
const view = render(
|
||||||
<HtmlToReact domPurifyConfig={{ ADD_TAGS: ['test-tag'] }} htmlCode={'<test-tag>Test!</test-tag>'} />
|
<HtmlToReact domPurifyConfig={{ ADD_TAGS: ['test-tag'] }} htmlCode={'<test-tag>Test!</test-tag>'} />
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2024 The HedgeDoc developers (see AUTHORS file)
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
@ -16,6 +16,8 @@ export interface HtmlToReactProps {
|
||||||
parserOptions?: ParserOptions
|
parserOptions?: ParserOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const REGEX_URI_SCHEME_NO_SCRIPTS = /^(?!.*script:).+:?/i
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders
|
* Renders
|
||||||
* @param htmlCode
|
* @param htmlCode
|
||||||
|
@ -26,7 +28,12 @@ export interface HtmlToReactProps {
|
||||||
export const HtmlToReact: React.FC<HtmlToReactProps> = ({ htmlCode, domPurifyConfig, parserOptions }) => {
|
export const HtmlToReact: React.FC<HtmlToReactProps> = ({ htmlCode, domPurifyConfig, parserOptions }) => {
|
||||||
const elements = useMemo(() => {
|
const elements = useMemo(() => {
|
||||||
const sanitizedHtmlCode = measurePerformance('html-to-react: sanitize', () => {
|
const sanitizedHtmlCode = measurePerformance('html-to-react: sanitize', () => {
|
||||||
return sanitize(htmlCode, { ...domPurifyConfig, RETURN_DOM_FRAGMENT: false, RETURN_DOM: false })
|
return sanitize(htmlCode, {
|
||||||
|
...domPurifyConfig,
|
||||||
|
RETURN_DOM_FRAGMENT: false,
|
||||||
|
RETURN_DOM: false,
|
||||||
|
ALLOWED_URI_REGEXP: REGEX_URI_SCHEME_NO_SCRIPTS
|
||||||
|
})
|
||||||
})
|
})
|
||||||
return measurePerformance('html-to-react: convertHtmlToReact', () => {
|
return measurePerformance('html-to-react: convertHtmlToReact', () => {
|
||||||
return convertHtmlToReact(sanitizedHtmlCode, parserOptions)
|
return convertHtmlToReact(sanitizedHtmlCode, parserOptions)
|
||||||
|
|
Loading…
Reference in a new issue