mirror of https://github.com/requarks/wiki
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.7 KiB
106 lines
3.7 KiB
const { JSDOM } = require('jsdom')
|
|
const createDOMPurify = require('dompurify')
|
|
|
|
module.exports = {
|
|
async init(input, config) {
|
|
if (config.safeHTML) {
|
|
const window = new JSDOM('').window
|
|
const DOMPurify = createDOMPurify(window)
|
|
|
|
const allowedAttrs = ['v-pre', 'v-slot:tabs', 'v-slot:content', 'target']
|
|
const allowedTags = ['tabset', 'template']
|
|
|
|
if (config.allowDrawIoUnsafe) {
|
|
allowedTags.push('foreignObject')
|
|
DOMPurify.addHook('uponSanitizeElement', (elm) => {
|
|
if (elm.querySelectorAll) {
|
|
const breaks = elm.querySelectorAll('foreignObject br, foreignObject p')
|
|
if (breaks && breaks.length) {
|
|
for (let i = 0; i < breaks.length; i++) {
|
|
breaks[i].parentNode.replaceChild(
|
|
window.document.createElement('div'),
|
|
breaks[i]
|
|
)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
if (config.allowIFrames) {
|
|
allowedTags.push('iframe')
|
|
allowedAttrs.push('allow')
|
|
}
|
|
|
|
//Changes to keep interactive plantuml object tag
|
|
|
|
//only allow specific attributes for plantuml object node
|
|
if (typeof pumlImageFormat !== 'undefined' &&
|
|
pumlImageFormat &&
|
|
pumlImageFormat == 'svg') {
|
|
allowedTags.push('object')
|
|
allowedAttrs.push('data')
|
|
allowedAttrs.push('type')
|
|
allowedAttrs.push('style')
|
|
allowedAttrs.push('class')
|
|
allowedAttrs.push('alt')
|
|
}
|
|
|
|
DOMPurify.addHook('uponSanitizeElement', (node, data) => {
|
|
// keep object node only if it is
|
|
// authorised plantuml using the configured plantuml server
|
|
// force attribute values to configured params
|
|
// insert the plantuml inside the object as text for search
|
|
let isPumlNode=false
|
|
|
|
if (data.tagName === 'object' &&
|
|
typeof pumlServer !== 'undefined' && pumlServer &&
|
|
typeof pumlObjectStyle !== 'undefined' && pumlObjectStyle &&
|
|
typeof pumlObjectType !== 'undefined' && pumlObjectType &&
|
|
typeof pumlObjectClass !== 'undefined' && pumlObjectClass
|
|
) {
|
|
//console.log ("Found object node - validating")
|
|
//remove node if it doesn't conform to plantuml structure
|
|
if (!( 'data' in node.attributes
|
|
&& 'class' in node.attributes
|
|
&& 'style' in node.attributes
|
|
&& 'type' in node.attributes
|
|
&& 'alt' in node.attributes)
|
|
) {
|
|
//console.log ("Attribute mismatch - removing object node")
|
|
return node.parentNode.removeChild(node)
|
|
}
|
|
|
|
dataAttribute = node.getAttribute ('data')
|
|
|
|
//only allow configured plantuml server and image format in url
|
|
if (dataAttribute
|
|
&& dataAttribute.startsWith(`${pumlServer}/${pumlImageFormat}`)
|
|
) {
|
|
//console.log ("Plantuml node found - setting atribute values")
|
|
isPumlNode=true
|
|
node.setAttribute ('type', pumlObjectType)
|
|
node.setAttribute ('style', pumlObjectStyle)
|
|
node.setAttribute ('class', pumlObjectClass)
|
|
node.setAttribute ('alt', '')
|
|
}
|
|
|
|
//if not a plantuml node, then sanitise it
|
|
if (!isPumlNode) {
|
|
console.log ("Removing unknown object node")
|
|
return node.parentNode.removeChild(node)
|
|
}
|
|
}
|
|
})
|
|
//End changes to keep interactive plantuml object tag
|
|
|
|
input = DOMPurify.sanitize(input, {
|
|
ADD_ATTR: allowedAttrs,
|
|
ADD_TAGS: allowedTags,
|
|
HTML_INTEGRATION_POINTS: { foreignobject: true }
|
|
})
|
|
}
|
|
return input
|
|
}
|
|
}
|