customembed: drop <object> and <embed>
This commit is contained in:
parent
9e5a63d880
commit
182e6f0816
|
@ -20,77 +20,12 @@ function filter(input) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMeta($) {
|
function getMeta($) {
|
||||||
var tag = $("embed");
|
let tag = $("iframe");
|
||||||
if (tag.length !== 0) {
|
|
||||||
return filterEmbed(tag[0]);
|
|
||||||
}
|
|
||||||
tag = $("object");
|
|
||||||
if (tag.length !== 0) {
|
|
||||||
return filterObject(tag[0]);
|
|
||||||
}
|
|
||||||
tag = $("iframe");
|
|
||||||
if (tag.length !== 0) {
|
if (tag.length !== 0) {
|
||||||
return filterIframe(tag[0]);
|
return filterIframe(tag[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error("Invalid embed. Input must be an <iframe>, <object>, or " +
|
throw new Error("Invalid embed. Input must be an <iframe> tag");
|
||||||
"<embed> tag.");
|
|
||||||
}
|
|
||||||
|
|
||||||
const ALLOWED_PARAMS = /^(flashvars|bgcolor|movie)$/i;
|
|
||||||
function filterEmbed(tag) {
|
|
||||||
if (tag.attribs.type && tag.attribs.type !== "application/x-shockwave-flash") {
|
|
||||||
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.");
|
|
||||||
}
|
|
||||||
|
|
||||||
var meta = {
|
|
||||||
embed: {
|
|
||||||
tag: "object",
|
|
||||||
src: tag.attribs.src,
|
|
||||||
params: {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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") {
|
|
||||||
throw new Error("Invalid embed. Only type 'application/x-shockwave-flash' " +
|
|
||||||
"is allowed for <object> tags.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!/^https:/.test(tag.attribs.data)) {
|
|
||||||
throw new Error("Invalid embed. Embed source must be HTTPS, plain HTTP is not supported.");
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
});
|
|
||||||
|
|
||||||
return meta;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterIframe(tag) {
|
function filterIframe(tag) {
|
||||||
|
|
|
@ -1,21 +1,47 @@
|
||||||
const customembed = require('../lib/customembed');
|
const customembed = require('../lib/customembed');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
|
const crypto = require("crypto");
|
||||||
|
|
||||||
|
function sha256(input) {
|
||||||
|
let hash = crypto.createHash('sha256');
|
||||||
|
hash.update(input);
|
||||||
|
return hash.digest('base64');
|
||||||
|
}
|
||||||
|
|
||||||
describe('customembed', () => {
|
describe('customembed', () => {
|
||||||
describe('#filter', () => {
|
describe('#filter', () => {
|
||||||
it('rejects plain-HTTP <embed> inputs', () => {
|
it('rejects <embed> inputs', () => {
|
||||||
const input = '<embed src="http://foo.bar/baz.swf" type="application/x-shockwave-flash"></embed>';
|
const input = '<embed src="https://example.com/baz.swf" type="application/x-shockwave-flash"></embed>';
|
||||||
assert.throws(() => { customembed.filter(input) }, /must be HTTPS/);
|
assert.throws(() => { customembed.filter(input) }, /must be an <iframe>/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('rejects plain-HTTP <object> inputs', () => {
|
it('rejects <object> inputs', () => {
|
||||||
const input = '<object data="http://foo.bar/baz.swf" type="application/x-shockwave-flash"></object>';
|
const input = '<object data="https://example.com/baz.swf" type="application/x-shockwave-flash"></object>';
|
||||||
assert.throws(() => { customembed.filter(input) }, /must be HTTPS/);
|
assert.throws(() => { customembed.filter(input) }, /must be an <iframe>/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('rejects plain-HTTP <iframe> inputs', () => {
|
it('rejects plain-HTTP <iframe> inputs', () => {
|
||||||
const input = '<iframe src="http://foo.bar/baz.swf"></iframe>';
|
const input = '<iframe src="http://foo.bar/baz.swf"></iframe>';
|
||||||
assert.throws(() => { customembed.filter(input) }, /must be HTTPS/);
|
assert.throws(() => { customembed.filter(input) }, /must be HTTPS/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('accepts a valid iframe', () => {
|
||||||
|
let input = '<iframe src="https://example.com/video.html"</iframe>';
|
||||||
|
const { id, title, seconds, duration, type, meta } = customembed.filter(input).pack();
|
||||||
|
const { embed } = meta;
|
||||||
|
|
||||||
|
assert.strictEqual(id, `cu:${sha256(input)}`);
|
||||||
|
assert.strictEqual(title, 'Custom Media');
|
||||||
|
assert.strictEqual(seconds, 0);
|
||||||
|
assert.strictEqual(duration, '--:--');
|
||||||
|
assert.strictEqual(type, 'cu');
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
embed,
|
||||||
|
{
|
||||||
|
tag: 'iframe',
|
||||||
|
src: 'https://example.com/video.html'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue