diff --git a/README.md b/README.md index 7c78b46..0d44081 100644 --- a/README.md +++ b/README.md @@ -186,6 +186,8 @@ To add a footnote to the footer, create a public folder in your application and } ``` +> The footnote information may include HTML like `My Link` which will be sanitized. + ### Add a help page with explanations To add a help page, create a public folder in your application and put a `messages.json` in it. ```json @@ -252,6 +254,8 @@ To add a help page, create a public folder in your application and put a `messag } ``` +> The information in `description`s for `rings` and `quadrants` as well as the `values` for `paragraphs` may include HTML like `My Link` which will be sanitized. + > For more information see the source code of the [Messages Context](./src/context/MessagesContext/index.tsx). ## Development diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx index 6ca1fdb..243319a 100644 --- a/src/components/Footer/Footer.tsx +++ b/src/components/Footer/Footer.tsx @@ -6,6 +6,7 @@ import { assetUrl, getItemPageNames, isMobileViewport } from "../../config"; import { Item } from "../../model"; import "./footer.scss"; import { useMessages } from "../../context/MessagesContext"; +import { sanitize } from "../../sanitize"; interface Props { items: Item[]; @@ -34,7 +35,7 @@ const Footer: React.FC = ({ items, pageName }) => { /> } > - {footerFootnote} +
)} diff --git a/src/components/PageHelp/PageHelp.tsx b/src/components/PageHelp/PageHelp.tsx index f967000..50e4294 100644 --- a/src/components/PageHelp/PageHelp.tsx +++ b/src/components/PageHelp/PageHelp.tsx @@ -1,23 +1,16 @@ import React from "react"; -import sanitizeHtml from 'sanitize-html'; import HeroHeadline from "../HeroHeadline/HeroHeadline"; import Fadeable from "../Fadeable/Fadeable"; import SetTitle from "../SetTitle"; import { radarName } from "../../config"; import { useMessages } from "../../context/MessagesContext"; +import { sanitize } from "../../sanitize"; interface Props { leaving: boolean; onLeave: () => void; } -const sanitize = (dirty: string, options: sanitizeHtml.IOptions = {}) => ({ - __html: sanitizeHtml( - dirty, - options - ) -}); - const PageHelp: React.FC = ({ leaving, onLeave }) => { const { pageHelp } = useMessages(); @@ -34,12 +27,7 @@ const PageHelp: React.FC = ({ leaving, onLeave }) => {

{headline}

{values.map((element, index) => { return ( -

+

) }) } @@ -50,7 +38,7 @@ const PageHelp: React.FC = ({ leaving, onLeave }) => {
    {quadrants.map(({ name, description }) => (
  • - {name}: + {name}:
  • ))}
@@ -59,7 +47,7 @@ const PageHelp: React.FC = ({ leaving, onLeave }) => {
    {rings.map(({ name, description }) => (
  • - {name}: + {name}:
  • ))}
diff --git a/src/sanitize.test.tsx b/src/sanitize.test.tsx new file mode 100644 index 0000000..51a0fb9 --- /dev/null +++ b/src/sanitize.test.tsx @@ -0,0 +1,20 @@ +import { sanitize } from "./sanitize"; + +describe("sanitize", () => { + it("should sanitize the string input to HTML output", () => { + let res = sanitize('foo'); + expect(res.__html).toEqual("foo"); + res = sanitize('Example.org'); + expect(res.__html).toEqual("Example.org"); + }); + it("should not sanitize not allowed tags", () => { + let res = sanitize('Before After'); + expect(res.__html).toEqual("Before After"); + }); + it("should accept options for rendering", () => { + let res = sanitize('Example.org', { allowedAttributes: { a: ['href']}}); + expect(res.__html).toEqual("Example.org"); + }); +}); + + diff --git a/src/sanitize.ts b/src/sanitize.ts new file mode 100644 index 0000000..6c01e77 --- /dev/null +++ b/src/sanitize.ts @@ -0,0 +1,15 @@ +import sanitizeHtml from 'sanitize-html'; + +const defaultSanitizeOptions = { + allowedTags: ['b', 'i', 'em', 'strong', 'a', 'ul', 'ol', 'li'], + allowedAttributes: { + 'a': ['href', 'target'] + } +} + +export const sanitize = (dirty: string, options: sanitizeHtml.IOptions = defaultSanitizeOptions) => ({ + __html: sanitizeHtml( + dirty, + options + ) +});