2015-01-06 17:20:48 +00:00
|
|
|
var sanitizeHTML = require("sanitize-html");
|
|
|
|
|
2015-01-06 18:00:36 +00:00
|
|
|
// These tags are allowed in addition to the defaults
|
|
|
|
// See https://github.com/punkave/sanitize-html
|
2015-01-06 17:20:48 +00:00
|
|
|
const ALLOWED_TAGS = [
|
|
|
|
"button",
|
|
|
|
"center",
|
2016-07-07 11:52:03 +00:00
|
|
|
"cite"
|
2015-01-06 17:20:48 +00:00
|
|
|
"details",
|
|
|
|
"font",
|
|
|
|
"h1",
|
|
|
|
"h2",
|
|
|
|
"img",
|
|
|
|
"marquee", // It pains me to do this, but a lot of people use it...
|
2015-01-19 07:26:46 +00:00
|
|
|
"s",
|
2015-01-06 17:20:48 +00:00
|
|
|
"section",
|
2016-07-07 11:52:03 +00:00
|
|
|
"small",
|
2015-01-06 17:20:48 +00:00
|
|
|
"span",
|
2016-07-07 11:52:03 +00:00
|
|
|
"sub",
|
|
|
|
"summary",
|
|
|
|
"sup",
|
|
|
|
"template"
|
2015-01-06 17:20:48 +00:00
|
|
|
];
|
|
|
|
|
|
|
|
const ALLOWED_ATTRIBUTES = [
|
|
|
|
"id",
|
2015-01-06 18:00:36 +00:00
|
|
|
"aria-*",
|
2015-01-06 17:20:48 +00:00
|
|
|
"border",
|
|
|
|
"class",
|
|
|
|
"color",
|
2015-01-06 18:00:36 +00:00
|
|
|
"data-*",
|
2015-01-06 17:20:48 +00:00
|
|
|
"height",
|
|
|
|
"role",
|
|
|
|
"style",
|
|
|
|
"title",
|
|
|
|
"valign",
|
2016-05-05 03:58:18 +00:00
|
|
|
"width",
|
|
|
|
"rel"
|
2015-01-06 17:20:48 +00:00
|
|
|
];
|
|
|
|
|
2015-04-16 06:07:12 +00:00
|
|
|
const ALLOWED_SCHEMES = [
|
|
|
|
"mumble"
|
|
|
|
];
|
|
|
|
|
2015-01-06 17:20:48 +00:00
|
|
|
var ATTRIBUTE_MAP = {
|
|
|
|
a: ["href", "name", "target"],
|
|
|
|
font: ["size"],
|
|
|
|
img: ["src"],
|
|
|
|
marquee: ["behavior", "behaviour", "direction", "scrollamount"],
|
|
|
|
table: ["cellpadding", "cellspacing"],
|
|
|
|
th: ["colspan", "rowspan"],
|
|
|
|
td: ["colspan", "rowspan"]
|
2013-10-31 05:39:35 +00:00
|
|
|
}
|
|
|
|
|
2015-01-06 17:20:48 +00:00
|
|
|
for (var key in ATTRIBUTE_MAP) {
|
|
|
|
ALLOWED_ATTRIBUTES.forEach(function (attr) {
|
|
|
|
ATTRIBUTE_MAP[key].push(attr);
|
2014-01-23 17:45:08 +00:00
|
|
|
});
|
2015-01-06 17:20:48 +00:00
|
|
|
}
|
2014-01-23 17:45:08 +00:00
|
|
|
|
2015-01-06 17:20:48 +00:00
|
|
|
sanitizeHTML.defaults.allowedTags.concat(ALLOWED_TAGS).forEach(function (tag) {
|
|
|
|
if (!(tag in ATTRIBUTE_MAP)) {
|
|
|
|
ATTRIBUTE_MAP[tag] = ALLOWED_ATTRIBUTES;
|
2013-10-31 05:48:01 +00:00
|
|
|
}
|
2015-01-06 17:20:48 +00:00
|
|
|
});
|
2013-10-31 05:39:35 +00:00
|
|
|
|
2015-01-06 17:20:48 +00:00
|
|
|
const SETTINGS = {
|
2015-04-16 06:07:12 +00:00
|
|
|
allowedSchemes: sanitizeHTML.defaults.allowedSchemes.concat(ALLOWED_SCHEMES),
|
2015-01-06 17:20:48 +00:00
|
|
|
allowedTags: sanitizeHTML.defaults.allowedTags.concat(ALLOWED_TAGS),
|
|
|
|
allowedAttributes: ATTRIBUTE_MAP
|
2013-10-31 05:39:35 +00:00
|
|
|
};
|
|
|
|
|
2013-10-31 23:53:03 +00:00
|
|
|
function sanitizeText(str) {
|
|
|
|
str = str.replace(/&/g, "&")
|
|
|
|
.replace(/</g, "<")
|
|
|
|
.replace(/>/g, ">")
|
|
|
|
.replace(/"/g, """)
|
|
|
|
.replace(/'/g, "'")
|
|
|
|
.replace(/\(/g, "(")
|
|
|
|
.replace(/\)/g, ")");
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2013-11-05 16:37:50 +00:00
|
|
|
function decodeText(str) {
|
2014-01-23 17:45:08 +00:00
|
|
|
str = str.replace(/&#([0-9]{2,7});?/g, function (m, p1) {
|
2013-11-05 16:37:50 +00:00
|
|
|
return String.fromCharCode(parseInt(p1));
|
|
|
|
});
|
2014-01-23 17:45:08 +00:00
|
|
|
str = str.replace(/&#x([0-9a-f]{2,7});?/ig, function (m, p1) {
|
2013-11-05 16:37:50 +00:00
|
|
|
return String.fromCharCode(parseInt(p1, 16));
|
|
|
|
});
|
|
|
|
str = str.replace(/</g, "<")
|
|
|
|
.replace(/>/g, ">")
|
|
|
|
.replace(/"/g, "\"")
|
|
|
|
.replace(/&/g, "&");
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2015-01-06 17:20:48 +00:00
|
|
|
module.exports.sanitizeHTML = function (html) {
|
|
|
|
return sanitizeHTML(html, SETTINGS);
|
|
|
|
};
|
|
|
|
|
2013-11-05 16:37:50 +00:00
|
|
|
module.exports.sanitizeText = sanitizeText;
|
|
|
|
module.exports.decodeText = decodeText;
|