[http deprecation] enforce HTTPS for externalcss URLs

This commit is contained in:
Calvin Montgomery 2016-12-10 23:23:57 -08:00
parent e8d39850c5
commit 453ed607ba
5 changed files with 125 additions and 50 deletions

View file

@ -3,6 +3,10 @@ var Config = require("../config");
var Utilities = require("../utilities");
var url = require("url");
function realTypeOf(thing) {
return thing === null ? 'null' : typeof thing;
}
function OptionsModule(channel) {
ChannelModule.apply(this, arguments);
this.opts = {
@ -100,8 +104,11 @@ OptionsModule.prototype.handleSetOptions = function (user, data) {
return;
}
var sendUpdate = false;
if ("allow_voteskip" in data) {
this.opts.allow_voteskip = Boolean(data.allow_voteskip);
sendUpdate = true;
}
if ("voteskip_ratio" in data) {
@ -110,6 +117,7 @@ OptionsModule.prototype.handleSetOptions = function (user, data) {
ratio = 0;
}
this.opts.voteskip_ratio = ratio;
sendUpdate = true;
}
if ("afk_timeout" in data) {
@ -125,12 +133,14 @@ OptionsModule.prototype.handleSetOptions = function (user, data) {
u.autoAFK();
});
}
sendUpdate = true;
}
if ("pagetitle" in data && user.account.effectiveRank >= 3) {
var title = (""+data.pagetitle).substring(0, 100);
if (!title.trim().match(Config.get("reserved-names.pagetitles"))) {
this.opts.pagetitle = (""+data.pagetitle).substring(0, 100);
sendUpdate = true;
} else {
user.socket.emit("errorMsg", {
msg: "That pagetitle is reserved",
@ -151,31 +161,42 @@ OptionsModule.prototype.handleSetOptions = function (user, data) {
ml = 0;
}
this.opts.maxlength = ml;
sendUpdate = true;
}
if ("externalcss" in data && user.account.effectiveRank >= 3) {
var link = (""+data.externalcss).substring(0, 255);
var prefix = "Invalid URL for external CSS: ";
if (typeof data.externalcss !== "string") {
user.socket.emit("validationError", {
target: "#cs-externalcss",
message: prefix + "URL must be a string, not "
+ realTypeOf(data.externalcss)
});
}
var link = data.externalcss.substring(0, 255).trim();
if (!link) {
this.opts.externalcss = "";
sendUpdate = true;
} else {
try {
var data = url.parse(link);
if (!data.protocol || !data.protocol.match(/^(https?|ftp):/)) {
throw "Unacceptable protocol " + data.protocol;
} else if (!data.host) {
throw "URL is missing host";
} else {
link = data.href;
}
} catch (e) {
user.socket.emit("errorMsg", {
msg: "Invalid URL for external CSS: " + e,
alert: true
var data = url.parse(link);
if (!data.protocol || data.protocol !== 'https:') {
user.socket.emit("validationError", {
target: "#cs-externalcss",
message: prefix + " URL must begin with 'https://'"
});
return;
} else if (!data.host) {
user.socket.emit("validationError", {
target: "#cs-externalcss",
message: prefix + "missing hostname"
});
} else {
user.socket.emit("validationPassed", {
target: "#cs-externalcss"
});
this.opts.externalcss = data.href;
sendUpdate = true;
}
this.opts.externalcss = link;
}
}
@ -183,6 +204,7 @@ OptionsModule.prototype.handleSetOptions = function (user, data) {
var link = (""+data.externaljs).substring(0, 255);
if (!link) {
this.opts.externaljs = "";
sendUpdate = true;
} else {
try {
@ -203,11 +225,13 @@ OptionsModule.prototype.handleSetOptions = function (user, data) {
}
this.opts.externaljs = link;
sendUpdate = true;
}
}
if ("chat_antiflood" in data) {
this.opts.chat_antiflood = Boolean(data.chat_antiflood);
sendUpdate = true;
}
if ("chat_antiflood_params" in data) {
@ -238,38 +262,46 @@ OptionsModule.prototype.handleSetOptions = function (user, data) {
sustained: s,
cooldown: c
};
sendUpdate = true;
}
if ("show_public" in data && user.account.effectiveRank >= 3) {
this.opts.show_public = Boolean(data.show_public);
sendUpdate = true;
}
if ("enable_link_regex" in data) {
this.opts.enable_link_regex = Boolean(data.enable_link_regex);
sendUpdate = true;
}
if ("password" in data && user.account.effectiveRank >= 3) {
var pw = data.password + "";
pw = pw === "" ? false : pw.substring(0, 100);
this.opts.password = pw;
sendUpdate = true;
}
if ("allow_dupes" in data) {
this.opts.allow_dupes = Boolean(data.allow_dupes);
sendUpdate = true;
}
if ("torbanned" in data && user.account.effectiveRank >= 3) {
this.opts.torbanned = Boolean(data.torbanned);
sendUpdate = true;
}
if ("allow_ascii_control" in data && user.account.effectiveRank >= 3) {
this.opts.allow_ascii_control = Boolean(data.allow_ascii_control);
sendUpdate = true;
}
if ("playlist_max_per_user" in data && user.account.effectiveRank >= 3) {
var max = parseInt(data.playlist_max_per_user);
if (!isNaN(max) && max >= 0) {
this.opts.playlist_max_per_user = max;
sendUpdate = true;
}
}
@ -277,6 +309,7 @@ OptionsModule.prototype.handleSetOptions = function (user, data) {
var delay = data.new_user_chat_delay;
if (!isNaN(delay) && delay >= 0) {
this.opts.new_user_chat_delay = delay;
sendUpdate = true;
}
}
@ -284,11 +317,14 @@ OptionsModule.prototype.handleSetOptions = function (user, data) {
var delay = data.new_user_chat_link_delay;
if (!isNaN(delay) && delay >= 0) {
this.opts.new_user_chat_link_delay = delay;
sendUpdate = true;
}
}
this.channel.logger.log("[mod] " + user.getName() + " updated channel options");
this.sendOpts(this.channel.users);
if (sendUpdate) {
this.sendOpts(this.channel.users);
}
};
module.exports = OptionsModule;