sync/src/customembed.js

112 lines
2.8 KiB
JavaScript
Raw Normal View History

2015-06-18 22:46:33 +00:00
var cheerio = require("cheerio");
var crypto = require("crypto");
var Media = require("./media");
2013-08-03 15:50:41 +00:00
2015-06-18 22:46:33 +00:00
function sha256(input) {
var hash = crypto.createHash("sha256");
hash.update(input);
return hash.digest("base64");
}
function filter(input) {
var $ = cheerio.load(input, {
lowerCaseTags: true,
lowerCaseAttributeNames: true
});
2015-06-18 22:46:33 +00:00
var meta = getMeta($);
var id = "cu:" + sha256(input);
return new Media(id, "Custom Media", "--:--", "cu", meta);
}
function getMeta($) {
var tag = $("embed");
if (tag.length !== 0) {
return filterEmbed(tag[0]);
}
tag = $("object");
if (tag.length !== 0) {
return filterObject(tag[0]);
}
tag = $("iframe");
if (tag.length !== 0) {
return filterIframe(tag[0]);
2014-02-19 03:56:54 +00:00
}
2015-06-18 22:46:33 +00:00
throw new Error("Invalid embed. Input must be an <iframe>, <object>, or " +
"<embed> tag.");
}
const ALLOWED_PARAMS = /^(flashvars|bgcolor|movie)$/i;
function filterEmbed(tag) {
if (tag.attribs.type && tag.attribs.type !== "application/x-shockwave-flash") {
2015-06-18 22:46:33 +00:00
throw new Error("Invalid embed. Only type 'application/x-shockwave-flash' " +
"is allowed for <embed> tags.");
}
if (!/^https:/.test(tag.attribs.src)) {
throw new Error("Invalid embed. Embed source must be HTTPS, plain HTTP is not supported.");
}
2015-06-18 22:46:33 +00:00
var meta = {
embed: {
tag: "object",
src: tag.attribs.src,
params: {}
2013-08-03 15:50:41 +00:00
}
2015-06-18 22:46:33 +00:00
}
for (var key in tag.attribs) {
if (ALLOWED_PARAMS.test(key)) {
meta.embed.params[key] = tag.attribs[key];
}
}
return meta;
}
function filterObject(tag) {
if (tag.attribs.type && tag.attribs.type !== "application/x-shockwave-flash") {
2015-06-18 22:46:33 +00:00
throw new Error("Invalid embed. Only type 'application/x-shockwave-flash' " +
"is allowed for <object> tags.");
2015-06-18 22:46:33 +00:00
}
if (!/^https:/.test(tag.attribs.data)) {
throw new Error("Invalid embed. Embed source must be HTTPS, plain HTTP is not supported.");
}
2015-06-18 22:46:33 +00:00
var meta = {
embed: {
tag: "object",
src: tag.attribs.data,
params: {}
}
};
tag.children.forEach(function (child) {
if (child.name !== "param") return;
if (!ALLOWED_PARAMS.test(child.attribs.name)) return;
meta.embed.params[child.attribs.name] = child.attribs.value;
2013-08-03 15:50:41 +00:00
});
2014-02-19 03:56:54 +00:00
2015-06-18 22:46:33 +00:00
return meta;
}
function filterIframe(tag) {
if (!/^https:/.test(tag.attribs.src)) {
throw new Error("Invalid embed. Embed source must be HTTPS, plain HTTP is not supported.");
}
2015-06-18 22:46:33 +00:00
var meta = {
embed: {
tag: "iframe",
src: tag.attribs.src
}
};
return meta;
2013-08-03 15:50:41 +00:00
}
exports.filter = filter;