diff --git a/package.json b/package.json index a10d5a16..633d67d5 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Calvin Montgomery", "name": "CyTube", "description": "Online media synchronizer and chat", - "version": "3.26.0", + "version": "3.27.0", "repository": { "url": "http://github.com/calzoneman/sync" }, @@ -53,10 +53,12 @@ "build-server": "babel -D --source-maps --loose es6.destructuring,es6.forOf --out-dir lib/ src/", "postinstall": "./postinstall.sh", "server-dev": "babel -D --watch --source-maps --loose es6.destructuring,es6.forOf --out-dir lib/ src/", - "generate-userscript": "$npm_node_execpath gdrive-userscript/generate-userscript $@ > www/js/cytube-google-drive.user.js" + "generate-userscript": "$npm_node_execpath gdrive-userscript/generate-userscript $@ > www/js/cytube-google-drive.user.js", + "test": "mocha" }, "devDependencies": { - "coffee-script": "^1.9.2" + "coffee-script": "^1.9.2", + "mocha": "^3.2.0" }, "babel": { "presets": [ diff --git a/src/config.js b/src/config.js index ebf55871..80dc58c6 100644 --- a/src/config.js +++ b/src/config.js @@ -414,3 +414,26 @@ exports.get = function (key) { return obj[current]; }; + +/** + * Sets a configuration value with the given key + * + * Accepts a dot-separated key for nested values, e.g. "http.port" + * Throws an error if a nonexistant key is requested + */ +exports.set = function (key, value) { + var obj = cfg; + var keylist = key.split("."); + var current = keylist.shift(); + var path = current; + while (keylist.length > 0) { + if (!(current in obj)) { + throw new Error("Nonexistant config key '" + path + "." + current + "'"); + } + obj = obj[current]; + current = keylist.shift(); + path += "." + current; + } + + obj[current] = value; +}; diff --git a/src/customembed.js b/src/customembed.js index 81abeb71..1ce81200 100644 --- a/src/customembed.js +++ b/src/customembed.js @@ -44,6 +44,10 @@ function filterEmbed(tag) { "is allowed for 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", @@ -67,6 +71,10 @@ function filterObject(tag) { "is allowed for 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", @@ -86,6 +94,10 @@ function filterObject(tag) { } function filterIframe(tag) { + 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: "iframe", diff --git a/src/ffmpeg.js b/src/ffmpeg.js index 828bb5d6..880206bb 100644 --- a/src/ffmpeg.js +++ b/src/ffmpeg.js @@ -40,7 +40,7 @@ function initFFLog() { } function fixRedirectIfNeeded(urldata, redirect) { - if (!/^https?:/.test(redirect)) { + if (!/^https:/.test(redirect)) { redirect = urldata.protocol + "//" + urldata.host + redirect; } @@ -74,8 +74,8 @@ function translateStatusCode(statusCode) { function testUrl(url, cb, redirCount) { if (!redirCount) redirCount = 0; var data = urlparse.parse(url); - if (!/https?:/.test(data.protocol)) { - return cb("Only links starting with 'http://' or 'https://' are supported " + + if (!/https:/.test(data.protocol)) { + return cb("Only links starting with 'https://' are supported " + "for raw audio/video support"); } @@ -315,9 +315,9 @@ exports.query = function (filename, cb) { return cb("Raw file playback is not enabled on this server"); } - if (!filename.match(/^https?:\/\//)) { - return cb("Raw file playback is only supported for links accessible via HTTP " + - "or HTTPS. Ensure that the link begins with 'http://' or 'https://'"); + if (!filename.match(/^https:\/\//)) { + return cb("Raw file playback is only supported for links accessible via HTTPS. " + + "Ensure that the link begins with 'https://'."); } testUrl(filename, function (err) { diff --git a/www/js/ui.js b/www/js/ui.js index d154583a..8e16af0b 100644 --- a/www/js/ui.js +++ b/www/js/ui.js @@ -446,7 +446,7 @@ $("#mediaurl").keyup(function(ev) { queue("end", "url"); } else { var url = $("#mediaurl").val().split("?")[0]; - if (url.match(/^https?:\/\/(.*)?\.(flv|mp4|og[gv]|webm|mp3|mov|m4a)$/) || + if (url.match(/^https:\/\/(.*)?\.(flv|mp4|og[gv]|webm|mp3|mov|m4a)$/) || url.match(/^fi:/)) { var title = $("#addfromurl-title"); if (title.length === 0) { diff --git a/www/js/util.js b/www/js/util.js index c29ab2d0..8a526ddd 100644 --- a/www/js/util.js +++ b/www/js/util.js @@ -1426,7 +1426,13 @@ function parseMediaLink(url) { /* Raw file */ var tmp = url.split("?")[0]; if (tmp.match(/^https?:\/\//)) { - if (tmp.match(/\.(mp4|flv|webm|og[gv]|mp3|mov|m4a)$/)) { + if (tmp.match(/^http:/)) { + Callbacks.queueFail({ + link: url, + msg: "Raw files must begin with 'https'. Plain http is not supported." + }); + throw new Error("ERROR_QUEUE_HTTP"); + } else if (tmp.match(/\.(mp4|flv|webm|og[gv]|mp3|mov|m4a)$/)) { return { id: url, type: "fi"