mirror of
https://github.com/calzoneman/sync.git
synced 2024-09-13 04:32:09 +00:00

Camo: https://github.com/atmos/camo. This has a couple advantages over just allowing images to be dumped as-is: - Prevents mixed-content warnings by allowing the server to proxy HTTP images to an HTTPS camo instance - Protects users' privacy by not exposing their browser directly to the image host - Allows the camo proxy to intercept and reject bad image sources (URLs that are not actually images, gigapixel-sized images likely to DoS users' browsers, etc.) Whitelisting specific domains is supported for cases where the source is known to be trustworthy.
114 lines
2.7 KiB
JavaScript
114 lines
2.7 KiB
JavaScript
var sanitizeHTML = require("sanitize-html");
|
|
|
|
// These tags are allowed in addition to the defaults
|
|
// See https://github.com/punkave/sanitize-html
|
|
const ALLOWED_TAGS = [
|
|
"button",
|
|
"center",
|
|
"cite",
|
|
"details",
|
|
"font",
|
|
"h1",
|
|
"h2",
|
|
"img",
|
|
"marquee", // It pains me to do this, but a lot of people use it...
|
|
"s",
|
|
"section",
|
|
"small",
|
|
"span",
|
|
"sub",
|
|
"summary",
|
|
"sup",
|
|
"template"
|
|
];
|
|
|
|
const ALLOWED_ATTRIBUTES = [
|
|
"id",
|
|
"aria-*",
|
|
"border",
|
|
"class",
|
|
"color",
|
|
"data-*",
|
|
"height",
|
|
"role",
|
|
"style",
|
|
"title",
|
|
"valign",
|
|
"width",
|
|
"rel"
|
|
];
|
|
|
|
const ALLOWED_SCHEMES = [
|
|
"mumble"
|
|
];
|
|
|
|
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"]
|
|
}
|
|
|
|
for (var key in ATTRIBUTE_MAP) {
|
|
ALLOWED_ATTRIBUTES.forEach(function (attr) {
|
|
ATTRIBUTE_MAP[key].push(attr);
|
|
});
|
|
}
|
|
|
|
sanitizeHTML.defaults.allowedTags.concat(ALLOWED_TAGS).forEach(function (tag) {
|
|
if (!(tag in ATTRIBUTE_MAP)) {
|
|
ATTRIBUTE_MAP[tag] = ALLOWED_ATTRIBUTES;
|
|
}
|
|
});
|
|
|
|
const SETTINGS = {
|
|
allowedSchemes: sanitizeHTML.defaults.allowedSchemes.concat(ALLOWED_SCHEMES),
|
|
allowedTags: sanitizeHTML.defaults.allowedTags.concat(ALLOWED_TAGS),
|
|
allowedAttributes: ATTRIBUTE_MAP
|
|
};
|
|
|
|
function looseSanitizeText(str) {
|
|
str = str.replace(/&/g, "&")
|
|
.replace(/</g, "<")
|
|
.replace(/>/g, ">")
|
|
.replace(/"/g, """);
|
|
return str;
|
|
}
|
|
|
|
function sanitizeText(str) {
|
|
str = str.replace(/&/g, "&")
|
|
.replace(/</g, "<")
|
|
.replace(/>/g, ">")
|
|
.replace(/"/g, """)
|
|
.replace(/'/g, "'")
|
|
.replace(/\(/g, "(")
|
|
.replace(/\)/g, ")");
|
|
return str;
|
|
}
|
|
|
|
function decodeText(str) {
|
|
str = str.replace(/&#([0-9]{2,7});?/g, function (m, p1) {
|
|
return String.fromCharCode(parseInt(p1));
|
|
});
|
|
str = str.replace(/&#x([0-9a-f]{2,7});?/ig, function (m, p1) {
|
|
return String.fromCharCode(parseInt(p1, 16));
|
|
});
|
|
str = str.replace(/</g, "<")
|
|
.replace(/>/g, ">")
|
|
.replace(/"/g, "\"")
|
|
.replace(/&/g, "&");
|
|
return str;
|
|
}
|
|
|
|
module.exports.sanitizeHTML = function (html, extraSettings = {}) {
|
|
const options = Object.assign({}, SETTINGS, extraSettings);
|
|
return sanitizeHTML(html, options);
|
|
};
|
|
|
|
module.exports.looseSanitizeText = looseSanitizeText;
|
|
module.exports.sanitizeText = sanitizeText;
|
|
module.exports.decodeText = decodeText;
|