Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions js/bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"name": "gallery",
"homepage": "https://github.com/owncloud/gallery",
"authors": [
"Olivier Paroz <[email protected]>"
"Olivier Paroz <[email protected]>",
"Robin Appelman <[email protected]>"
],
"description": "Media gallery for ownCloud which includes previews for all media types supported by your ownCloud installation.",
"license": "AGPL",
Expand All @@ -16,7 +17,8 @@
],
"dependencies": {
"eventsource-polyfill": "~0.*",
"marked": "~0.*",
"github-markdown-css": "~2.*"
"github-markdown-css": "~2.*",
"dompurify": "~0.6.5",
"commonmark": "~0.22.0"
}
}
82 changes: 76 additions & 6 deletions js/galleryinfobox.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* global Gallery, marked */
/* global Gallery, commonmark, DOMPurify */
(function ($, t, Gallery) {
"use strict";
/**
Expand All @@ -10,13 +10,19 @@
this.infoContentContainer = $('.album-info-container');
this.infoContentSpinner = this.infoContentContainer.children('.album-info-loader');
this.infoContentElement = this.infoContentContainer.children('.album-info-content');
this.markdownReader = new commonmark.Parser();
this.htmlWriter = new commonmark.HtmlRenderer();
this._initCustomSanitizer();
};

InfoBox.prototype = {
infoContentContainer: null,
infoContentSpinner: null,
infoContentElement: null,
albumInfo: null,
markdownReader: null,
htmlWriter: null,
allowedTags: null,

/**
* Shows an information box to the user
Expand All @@ -41,9 +47,9 @@
thisInfoBox._addContent(data);
}
).fail(function () {
thisInfoBox._addContent(t('gallery',
'Could not load the description'));
});
thisInfoBox._addContent(t('gallery',
'Could not load the description'));
});
} else {
this._addContent(this.albumInfo.description);
}
Expand All @@ -63,7 +69,7 @@
*/
_addContent: function (content) {
try {
content = marked(content);
content = this._parseMarkdown(content);
} catch (exception) {
content = t('gallery',
'Could not load the description: ' + exception.message);
Expand All @@ -74,6 +80,21 @@
this._adjustHeight();
},

/**
* Parses markdown content and sanitizes the HTML
*
* @param {string} content
* @private
*/
_parseMarkdown: function (content) {
return DOMPurify.sanitize(this.htmlWriter.render(this.markdownReader.parse(content), {
smart: true,
safe: true
}), {
ALLOWED_TAGS: this.allowedTags
});
},

/**
* Adjusts the height of the element to match the content
* @private
Expand Down Expand Up @@ -101,7 +122,7 @@

if (!$.isEmptyObject(this.albumInfo.copyright)) {
try {
copyright = marked(this.albumInfo.copyright);
copyright = this._parseMarkdown(this.albumInfo.copyright);
} catch (exception) {
copyright =
t('gallery',
Expand All @@ -115,6 +136,7 @@
this._addCopyrightLink(copyright);
} else {
this.infoContentElement.append(copyright);
this.infoContentElement.find('a').attr("target", "_blank");
}
}
},
Expand All @@ -139,6 +161,54 @@
target: "_blank"
});
this.infoContentElement.append(copyrightLink);
},

/**
* Adds custom tags and rules to DomPurify
*
* @link https://github.com/cure53/DOMPurify/blob/master/demos/hooks-scheme-whitelist.html
* @private
*/
_initCustomSanitizer: function () {
this.allowedTags =
['p', 'b', 'em', 'i', 'pre', 'sup', 'sub', 'strong', 'strike', 'br', 'hr',
'h1', 'h2', 'h3', 'li', 'ul', 'ol', 'a', 'img', 'blockquote', 'code'
];

// allowed URI schemes
var whitelist = ['http', 'https'];

// build fitting regex
var regex = new RegExp('^(' + whitelist.join('|') + '):', 'gim');

// Add a hook to enforce URI scheme whitelist
DOMPurify.addHook('afterSanitizeAttributes', function (node) {

// build an anchor to map URLs to
var anchor = document.createElement('a');

// check all href attributes for validity
if (node.hasAttribute('href')) {
anchor.href = node.getAttribute('href');
if (anchor.protocol && !anchor.protocol.match(regex)) {
node.removeAttribute('href');
}
}
// check all action attributes for validity
if (node.hasAttribute('action')) {
anchor.href = node.getAttribute('action');
if (anchor.protocol && !anchor.protocol.match(regex)) {
node.removeAttribute('action');
}
}
// check all xlink:href attributes for validity
if (node.hasAttribute('xlink:href')) {
anchor.href = node.getAttribute('xlink:href');
if (anchor.protocol && !anchor.protocol.match(regex)) {
node.removeAttribute('xlink:href');
}
}
});
}
};

Expand Down
Binary file removed js/vendor/bigshot/bigshot-2.0.zip
Binary file not shown.
Loading