Compare commits
No commits in common. "e08b8956943e08f96b1f40a0b663814b895bfdfe" and "098ea88f5d9736a45d9d0cba5ad786a5af824060" have entirely different histories.
e08b895694
...
098ea88f5d
5 changed files with 48 additions and 76 deletions
|
@ -1,6 +1,6 @@
|
|||
const {MatrixEvent} = require("./event")
|
||||
const {Event} = require("./event")
|
||||
|
||||
class EncryptedMessage extends MatrixEvent {
|
||||
class EncryptedMessage extends Event {
|
||||
render() {
|
||||
super.render()
|
||||
return this.text("Carbon cannot render encrypted messages yet")
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const {ElemJS, ejs} = require("../basic")
|
||||
const {dateFormatter} = require("../dateFormatter")
|
||||
|
||||
class MatrixEvent extends ElemJS {
|
||||
class Event extends ElemJS {
|
||||
constructor(data) {
|
||||
super("div")
|
||||
this.class("c-message")
|
||||
|
@ -50,17 +50,10 @@ class MatrixEvent extends ElemJS {
|
|||
}
|
||||
}
|
||||
|
||||
function simpleEvent(filter, render) {
|
||||
return class extends MatrixEvent {
|
||||
render() {
|
||||
super.render()
|
||||
return this.text(render(this.data))
|
||||
}
|
||||
|
||||
static canRender(event) {
|
||||
return filter(event)
|
||||
}
|
||||
}
|
||||
|
||||
function renderEvent(event) {
|
||||
return new events.find(e => e.canRender(event))(event)
|
||||
}
|
||||
|
||||
module.exports = {MatrixEvent, simpleEvent}
|
||||
module.exports = {renderEvent, Event}
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
const {simpleEvent} = require("./event")
|
||||
const {Event} = require("./event")
|
||||
|
||||
const UnknownMembership = simpleEvent((e) => e.type == "m.room.member", (e) => "unknown membership event")
|
||||
function createMembershipEvent(membership, text) {
|
||||
return class extends Event {
|
||||
render() {
|
||||
super.render()
|
||||
return this.text(text(this.data))
|
||||
}
|
||||
|
||||
function createMembershipEvent(membership, message) {
|
||||
return simpleEvent((e) => e.type == "m.room.member" && e.content.membership === membership, message)
|
||||
static canRender(event) {
|
||||
return event.type == "m.room.member" && event.content.membership == membership
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const JoinedEvent = createMembershipEvent("join", (e) => {console.log(e); return "joined the room"})
|
||||
const JoinedEvent = createMembershipEvent("join", () => "joined the room")
|
||||
const InvitedEvent = createMembershipEvent("invite", (e) => `invited ${e.content.displayname} the room`)
|
||||
const LeaveEvent = createMembershipEvent("leave", () => "left the room")
|
||||
|
||||
module.exports = [JoinedEvent, InvitedEvent, LeaveEvent, UnknownMembership]
|
||||
module.exports = [JoinedEvent, InvitedEvent, LeaveEvent]
|
||||
|
|
|
@ -1,73 +1,33 @@
|
|||
const {ejs} = require("../basic")
|
||||
const DOMPurify = require("dompurify")
|
||||
const {resolveMxc} = require("../functions")
|
||||
const {MatrixEvent} = require("./event")
|
||||
const {Event} = require("./event")
|
||||
|
||||
const purifier = DOMPurify()
|
||||
|
||||
purifier.setConfig({
|
||||
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'],
|
||||
|
||||
// In case we mess up none of those attributes should read to XSS
|
||||
ALLOWED_ATTR: ["data-mx-bg-color", "data-mx-color", "color",
|
||||
"name", "target", "href",
|
||||
"width", "height", "alt", "title", "src", "data-mx-emoticon",
|
||||
"start", "class"],
|
||||
//Custom config option that allows the array of attributes for a given tag
|
||||
ALLOWED_ATTR_CUSTOM: {
|
||||
"FONT": ["data-mx-bg-color", "data-mx-color", "color"],
|
||||
"SPAN": ["data-mx-bg-color", "data-mx-color", "color"],
|
||||
"A": ["name", "target", "href"],
|
||||
"IMG": ["width", "height", "alt", "title", "src", "data-mx-emoticon"],
|
||||
"OL": ["start"],
|
||||
"CODE": ["class"],
|
||||
}
|
||||
})
|
||||
|
||||
//Handle our custom tag
|
||||
purifier.addHook("uponSanitizeAttribute", (node, hookevent, config) => {
|
||||
//If purifier already rejected an attribute there is no point in checking it
|
||||
if (hookevent.keepAttr === false) return;
|
||||
|
||||
const allowed_attributes = config.ALLOWED_ATTR_CUSTOM[node.tagName] || []
|
||||
hookevent.keepAttr = allowed_attributes.indexOf(hookevent.attrName) > -1;
|
||||
})
|
||||
|
||||
//Remove bad classes from our code element
|
||||
purifier.addHook("uponSanitizeElement", (node, hookevent, config) => {
|
||||
if (node.tagName != "CODE") return
|
||||
node.classList.forEach(c => {
|
||||
if (!c.startsWith("language-")) {
|
||||
node.classList.remove(c)
|
||||
}
|
||||
})
|
||||
return node
|
||||
})
|
||||
|
||||
purifier.addHook("afterSanitizeAttributes", (node, hookevent, config) => {
|
||||
if (node.tagName == "IMG") {
|
||||
if (node.tagName == "img") {
|
||||
let src = node.getAttribute("src")
|
||||
if (src) src = resolveMxc(src)
|
||||
|
||||
node.setAttribute("src", src)
|
||||
} else if (node.tagName == "A") {
|
||||
|
||||
}
|
||||
if (node.tagName = "a") {
|
||||
node.setAttribute("rel", "noopener")
|
||||
} else if (node.tagName == "FONT" || node.tagName == "SPAN") {
|
||||
const color = node.getAttribute("data-mx-color")
|
||||
const bgColor = node.getAttribute("data-mx-bg-color")
|
||||
if (color) node.style.color = color;
|
||||
if (bgColor) node.style.backgroundColor = bgColor;
|
||||
}
|
||||
return node
|
||||
|
||||
})
|
||||
|
||||
|
||||
function sanitize(html) {
|
||||
return purifier.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 MatrixEvent {
|
||||
class HTMLMessage extends Event {
|
||||
render() {
|
||||
super.render()
|
||||
let html = this.data.content.formatted_body
|
||||
|
@ -89,7 +49,7 @@ class HTMLMessage extends MatrixEvent {
|
|||
|
||||
}
|
||||
|
||||
class TextMessage extends MatrixEvent {
|
||||
class TextMessage extends Event {
|
||||
render() {
|
||||
super.render()
|
||||
return this.text(this.data.content.body)
|
||||
|
|
|
@ -1,4 +1,15 @@
|
|||
const {simpleEvent} = require("./event")
|
||||
const UnknownEvent = simpleEvent(() => true, () => "Cannot render event")
|
||||
console.log(UnknownEvent)
|
||||
const {Event} = require("./event")
|
||||
|
||||
class UnknownEvent extends Event {
|
||||
render() {
|
||||
super.render()
|
||||
this.text("Cannot render event")
|
||||
}
|
||||
|
||||
static canRender(_event) {
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = [UnknownEvent]
|
||||
|
|
Loading…
Reference in a new issue