diff --git a/app/services/sanitizer.js b/app/services/sanitizer.js index a7585849581..68065fa1bd1 100644 --- a/app/services/sanitizer.js +++ b/app/services/sanitizer.js @@ -1,35 +1,46 @@ import Service from '@ember/service'; -import sanitizeHtml from 'sanitize-html'; +import createDOMPurify from 'dompurify'; export default Service.extend({ sanitize: null, + _purify: null, + + async init() { + this._super(...arguments); + if (typeof window !== 'undefined') { + this._purify = createDOMPurify(self); + } else { + const { JSDOM } = await import('jsdom'); + + this._purify = createDOMPurify(new JSDOM('').window); + } + this._purify.addHook('beforeSanitizeElements', function(node) { + if ('href' in node) { + node.setAttribute('target', '_blank'); + node.setAttribute('rel', 'nofollow noopener'); + } + }); + }, + // Ensure any changes to the sanitizer rules are set in the rich text editor @ components/widgets/forms/rich-text-editor.js options: { allowedTags : ['b', 'strong', 'i', 'em', 'u', 'ol', 'ul', 'li', 'a', 'p'], - allowedAttributes : { - 'a': ['href', 'rel', 'target'] - }, - selfClosing : ['br'], - allowedSchemes : ['http', 'https', 'ftp', 'mailto'], - allowedSchemesByTag : {}, - allowProtocolRelative : false, - transformTags : { - 'i' : 'em', - 'b' : 'strong', - 'a' : sanitizeHtml.simpleTransform('a', { rel: 'nofollow', target: '_blank' }) - } + allowedAttributes : ['href', 'rel', 'target'] }, purify(string) { - return sanitizeHtml(string, this.options); + return this._purify.sanitize(string, { + ALLOWED_TAGS : this.options.allowedTags, + ALLOWED_ATTR : this.options.allowedAttributes + }); }, strip(string) { - return sanitizeHtml(string, { - allowedTags : [], - allowedAttributes : [] + return this._purify.sanitize(string, { + ALLOWED_TAGS : [], + ALLOWED_ATTR : [] }); } }); diff --git a/ember-cli-build.js b/ember-cli-build.js index cc8bac34f10..73acfe50771 100644 --- a/ember-cli-build.js +++ b/ember-cli-build.js @@ -53,11 +53,8 @@ module.exports = function(defaults) { }, autoImport: { webpack: { - node: { - path: true // TODO: Remove after https://github.com/fossasia/open-event-frontend/issues/3956 - }, externals : { jquery: 'jQuery' }, - plugins : env === 'production' ? [ + plugins : process.env.ANALYE_BUNDLE === 'true' ? [ new BundleAnalyzerPlugin({ analyzerMode : 'static', openAnalyzer : false, diff --git a/package.json b/package.json index a268bf5cd90..fe8e75e704c 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "broccoli-persistent-filter": "^3.0.0", "croppie": "^2.6.4", "css-loader": "^3.5.3", + "dompurify": "^2.0.11", "ember-ajax": "5.0.0", "ember-auto-import": "^1.5.3", "ember-classic-decorator": "^1.0.8", @@ -139,7 +140,6 @@ "pre-commit": "^1.2.2", "query-string": "^6.12.1", "qunit-dom": "^1.2.0", - "sanitize-html": "^1.23.0", "sass": "^1.26.5", "semantic-ui-calendar": "^0.0.8", "semantic-ui-ember": "3.0.4", diff --git a/tests/unit/services/sanitizer-test.js b/tests/unit/services/sanitizer-test.js index 7e02fc2e198..9991fb81f67 100644 --- a/tests/unit/services/sanitizer-test.js +++ b/tests/unit/services/sanitizer-test.js @@ -17,5 +17,13 @@ module('Unit | Service | sanitizer', function(hooks) { sanitizedString = service.purify('