68 lines
1.6 KiB
JavaScript
68 lines
1.6 KiB
JavaScript
const {ejs} = require("../basic")
|
|
const DOMPurify = require("dompurify")
|
|
const {resolveMxc} = require("../functions")
|
|
const {Event} = require("./event")
|
|
|
|
const purifier = DOMPurify()
|
|
purifier.addHook("afterSanitizeAttributes", (node, hookevent, config) => {
|
|
if (node.tagName == "img") {
|
|
let src = node.getAttribute("src")
|
|
if (src) src = resolveMxc(src)
|
|
|
|
node.setAttribute("src", src)
|
|
|
|
}
|
|
if (node.tagName = "a") {
|
|
node.setAttribute("rel", "noopener")
|
|
}
|
|
return node
|
|
|
|
})
|
|
|
|
function sanitize(html) {
|
|
return purifier.sanitize(html, DOMPURIFY_CONFIG)
|
|
}
|
|
const DOMPURIFY_CONFIG = {
|
|
ALLOWED_URI_REGEXP: /^mxc:\/\/[a-zA-Z0-9\.]+\/[a-zA-Z0-9]+$/, // As per the spec we only allow mxc uris
|
|
ALLOWED_TAGS: ['font', 'del', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'p', 'a', 'ul', 'ol', 'sup', 'sub', 'li', 'b', 'i', 'u', 'strong', 'em', 'strike', 'code', 'hr', 'br', 'div', 'table', 'thead', 'tbody', 'tr', 'th', 'td', 'caption', 'pre', 'span', 'img'],
|
|
};
|
|
|
|
class HTMLMessage extends Event {
|
|
render() {
|
|
super.render()
|
|
let html = this.data.content.formatted_body
|
|
const content = ejs("div")
|
|
html = sanitize(html)
|
|
content.html(html)
|
|
this.child(content)
|
|
}
|
|
|
|
static canRender(event) {
|
|
const content = event.content
|
|
return event.type == "m.room.message" && content.msgtype == "m.text" && content.format == "org.matrix.custom.html" && content.formatted_body
|
|
|
|
}
|
|
|
|
canGroup() {
|
|
return true
|
|
}
|
|
|
|
}
|
|
|
|
class TextMessage extends Event {
|
|
render() {
|
|
super.render()
|
|
return this.text(this.data.content.body)
|
|
}
|
|
|
|
static canRender(event) {
|
|
return event.type == "m.room.message"
|
|
}
|
|
|
|
canGroup() {
|
|
return true
|
|
}
|
|
}
|
|
|
|
module.exports = [HTMLMessage, TextMessage]
|