diff --git a/server/modules/rendering/html-security/renderer.js b/server/modules/rendering/html-security/renderer.js
index 3bf9b2dc..9d53433a 100644
--- a/server/modules/rendering/html-security/renderer.js
+++ b/server/modules/rendering/html-security/renderer.js
@@ -32,6 +32,59 @@ module.exports = {
allowedAttrs.push('allow')
}
+ //Changes to keep interactive plantuml object tag
+
+ //only allow specific attributes for plantuml object node
+ 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') {
+ //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
diff --git a/server/modules/rendering/markdown-plantuml/renderer.js b/server/modules/rendering/markdown-plantuml/renderer.js
index 40eedc04..59135382 100644
--- a/server/modules/rendering/markdown-plantuml/renderer.js
+++ b/server/modules/rendering/markdown-plantuml/renderer.js
@@ -114,14 +114,74 @@ module.exports = {
const zippedCode = encode64(zlib.deflateRawSync('@startuml\n' + contents + '\n@enduml').toString('binary'))
- token = state.push('uml_diagram', 'img', 0)
- // alt is constructed from children. No point in populating it here.
- token.attrs = [ [ 'src', `${server}/${imageFormat}/${zippedCode}` ], [ 'alt', '' ], ['class', 'uml-diagram prefetch-candidate'] ]
- token.block = true
- token.children = altToken
- token.info = params
- token.map = [ startLine, nextLine ]
- token.markup = markup
+ //Interactive plantuml changes start here
+
+ //Global variables that will be used in html-security
+ pumlImageFormat = imageFormat
+ pumlServer = server
+ pumlObjectType = 'image/svg+xml'
+ pumlObjectStyle = 'max-width:100%;height:auto'
+ pumlObjectClass = 'uml-diagram prefetch-candidate'
+
+ if (imageFormat === 'png') {
+ //non-interactive and not searchable - use the img tag
+ token = state.push('uml_diagram', 'img', 0)
+ // alt is constructed from children. No point in populating it here.
+ token.attrs = [ [ 'src' , `${server}/${imageFormat}/${zippedCode}` ],
+ [ 'alt' , '' ],
+ ['class', `${pumlObjectClass}` ]
+ ]
+ token.block = true
+ token.children = altToken
+ token.info = params
+ token.map = [ startLine, nextLine ]
+ token.markup = markup
+ }
+ else if (imageFormat === 'svg') {
+ // render svg interactively with object tag
+ /*
+ token = state.push('uml_diagram_close', 'object', -1)
+ }
+ //Interactive plantuml changes end here
state.line = nextLine + (autoClosed ? 1 : 0)