diff --git a/package-lock.json b/package-lock.json index fa92175..7f6941a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,15 @@ { "name": "@openlearning/imscc-packager", - "version": "0.0.9", + "version": "0.0.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@openlearning/imscc-packager", - "version": "0.0.9", + "version": "0.0.10", "license": "ISC", "dependencies": { + "dompurify": "^3.2.3", "he": "^1.2.0", "jszip": "^3.10.1", "vite-plugin-dts": "^4.0.2" @@ -821,6 +822,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, "node_modules/@volar/language-core": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.3.4.tgz", @@ -1060,6 +1068,15 @@ } } }, + "node_modules/dompurify": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.3.tgz", + "integrity": "sha512-U1U5Hzc2MO0oW3DF+G9qYN0aT7atAou4AgI0XjWz061nyBPbdxkfdhfy5uMgGn6+oLFCfn44ZGbdDqCzVmlOWA==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, "node_modules/entities": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/entities/-/entities-5.0.0.tgz", @@ -1338,9 +1355,9 @@ "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==" }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "devOptional": true, "funding": [ { @@ -1803,4 +1820,4 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } -} \ No newline at end of file +} diff --git a/package.json b/package.json index 46f2707..a390400 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "vite": "^5.1.6" }, "dependencies": { + "dompurify": "^3.2.3", "he": "^1.2.0", "jszip": "^3.10.1", "vite-plugin-dts": "^4.0.2" diff --git a/src/imscc/resource/discussion.ts b/src/imscc/resource/discussion.ts index ef1316d..c2ef611 100644 --- a/src/imscc/resource/discussion.ts +++ b/src/imscc/resource/discussion.ts @@ -1,4 +1,5 @@ import { Page } from "../types"; +import DOMPurify from "dompurify"; const safeTags = (str: string) => str.replace(/&/g, "&").replace(//g, ">"); @@ -8,7 +9,7 @@ export const discussionDocument = (page: Page, _id: string) => ({ ${page.title} ${safeTags( - typeof page.content === "string" ? page.content : "" + typeof page.content === "string" ? DOMPurify.sanitize(page.content) : "" )} `, ext: "xml", diff --git a/src/imscc/resource/html.ts b/src/imscc/resource/html.ts index 5c44cbc..220cc20 100644 --- a/src/imscc/resource/html.ts +++ b/src/imscc/resource/html.ts @@ -1,5 +1,6 @@ import { FILEBASE_PLACEHOLDER } from "../constants"; import { Config, Page } from "../types"; +import DOMPurify from "dompurify"; export const cssFromConfig = (config?: Config) => { if (!config) { @@ -29,7 +30,11 @@ const templateHtml = (page: Page, id: string, options?: Config) => { ${styleTag} -${page.content} +${ + typeof page.content === "string" + ? DOMPurify.sanitize(page.content) + : page.content +} `; };