Merge pull request #313 from calzoneman/roompassword
Add channel passwords
This commit is contained in:
commit
d0544a8eb8
46
lib/api.js
46
lib/api.js
|
@ -74,8 +74,48 @@ module.exports = function (Server) {
|
||||||
loaded: false
|
loaded: false
|
||||||
};
|
};
|
||||||
|
|
||||||
if(Server.isChannelLoaded(name))
|
var needPassword = false;
|
||||||
data = getChannelData(Server.getChannel(name));
|
var chan = null;
|
||||||
|
if (Server.isChannelLoaded(name)) {
|
||||||
|
chan = Server.getChannel(name);
|
||||||
|
data = getChannelData(chan);
|
||||||
|
needPassword = chan.opts.password;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needPassword !== false) {
|
||||||
|
var pw = req.query.password;
|
||||||
|
if (pw !== needPassword) {
|
||||||
|
var uname = req.cookies.cytube_uname;
|
||||||
|
var session = req.cookies.cytube_session;
|
||||||
|
Server.db.userLoginSession(uname, session, function (err, row) {
|
||||||
|
if (err) {
|
||||||
|
res.status(403);
|
||||||
|
res.type("application/json");
|
||||||
|
res.jsonp({
|
||||||
|
error: "Password required to view this channel"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chan !== null) {
|
||||||
|
chan.getRank(uname, function (err, rank) {
|
||||||
|
if (err || rank < 2) {
|
||||||
|
res.status(403);
|
||||||
|
res.type("application/json");
|
||||||
|
res.jsonp({
|
||||||
|
error: "Password required to view this channel"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.type("application/json");
|
||||||
|
res.jsonp(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
res.type("application/json");
|
res.type("application/json");
|
||||||
res.jsonp(data);
|
res.jsonp(data);
|
||||||
|
@ -127,7 +167,7 @@ module.exports = function (Server) {
|
||||||
var channels = [];
|
var channels = [];
|
||||||
for(var key in Server.channels) {
|
for(var key in Server.channels) {
|
||||||
var channel = Server.channels[key];
|
var channel = Server.channels[key];
|
||||||
if(channel.opts.show_public)
|
if(channel.opts.show_public && channel.opts.password === false)
|
||||||
channels.push(getChannelData(channel));
|
channels.push(getChannelData(channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,7 @@ var Channel = function(name) {
|
||||||
},
|
},
|
||||||
show_public: false,
|
show_public: false,
|
||||||
enable_link_regex: true,
|
enable_link_regex: true,
|
||||||
|
password: false
|
||||||
};
|
};
|
||||||
self.filters = [
|
self.filters = [
|
||||||
new Filter("monospace", "`([^`]+)`", "g", "<code>$1</code>"),
|
new Filter("monospace", "`([^`]+)`", "g", "<code>$1</code>"),
|
||||||
|
@ -800,23 +801,51 @@ Channel.prototype.search = function(query, callback) {
|
||||||
|
|
||||||
/* REGION User interaction */
|
/* REGION User interaction */
|
||||||
|
|
||||||
|
Channel.prototype.addPendingJoin = function (user, password) {
|
||||||
|
var self = this;
|
||||||
|
if (!("pendingJoins" in self)) {
|
||||||
|
self.pendingJoins = [];
|
||||||
|
}
|
||||||
|
for (var i = 0; i < self.pendingJoins.length; i++) {
|
||||||
|
if (self.pendingJoins[i].user === user) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.pendingJoins.push({
|
||||||
|
user: user,
|
||||||
|
pw: password
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Channel.prototype.handlePendingJoins = function () {
|
Channel.prototype.handlePendingJoins = function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.pendingJoins.forEach(function (u) {
|
self.pendingJoins.forEach(function (u) {
|
||||||
self.userJoin(u);
|
self.userJoin(u.user, u.pw);
|
||||||
});
|
});
|
||||||
delete self["pendingJoins"];
|
delete self["pendingJoins"];
|
||||||
};
|
};
|
||||||
|
|
||||||
Channel.prototype.userJoin = function(user) {
|
Channel.prototype.userJoin = function(user, password) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!self.ready) {
|
if (!self.ready) {
|
||||||
if (!("pendingJoins" in self)) {
|
self.addPendingJoin(user, password);
|
||||||
self.pendingJoins = [];
|
|
||||||
}
|
|
||||||
self.pendingJoins.push(user);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.opts.password !== false &&
|
||||||
|
this.opts.password !== password &&
|
||||||
|
user.rank < 2) {
|
||||||
|
user.socket.emit("needPassword", password !== undefined &&
|
||||||
|
this.opts.password !== password);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
user.channel = this;
|
||||||
|
if (("pendingChannel" in user)) {
|
||||||
|
user.socket.emit("cancelNeedPassword");
|
||||||
|
delete user["pendingChannel"];
|
||||||
|
}
|
||||||
|
|
||||||
var parts = user.ip.split(".");
|
var parts = user.ip.split(".");
|
||||||
var slash24 = parts[0] + "." + parts[1] + "." + parts[2];
|
var slash24 = parts[0] + "." + parts[1] + "." + parts[2];
|
||||||
// GTFO
|
// GTFO
|
||||||
|
@ -2117,7 +2146,8 @@ Channel.prototype.tryUpdateOptions = function(user, data) {
|
||||||
pagetitle: true,
|
pagetitle: true,
|
||||||
externalcss: true,
|
externalcss: true,
|
||||||
externaljs: true,
|
externaljs: true,
|
||||||
show_public: true
|
show_public: true,
|
||||||
|
password: true
|
||||||
};
|
};
|
||||||
|
|
||||||
if ("allow_voteskip" in data) {
|
if ("allow_voteskip" in data) {
|
||||||
|
@ -2198,6 +2228,12 @@ Channel.prototype.tryUpdateOptions = function(user, data) {
|
||||||
this.opts.enable_link_regex = Boolean(data.enable_link_regex);
|
this.opts.enable_link_regex = Boolean(data.enable_link_regex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ("password" in data && user.rank >= 3) {
|
||||||
|
var pw = data.password+"";
|
||||||
|
pw = pw === "" ? false : pw;
|
||||||
|
this.opts.password = pw;
|
||||||
|
}
|
||||||
|
|
||||||
this.logger.log("%%% " + user.name + " updated channel options");
|
this.logger.log("%%% " + user.name + " updated channel options");
|
||||||
this.broadcastOpts();
|
this.broadcastOpts();
|
||||||
}
|
}
|
||||||
|
|
27
lib/user.js
27
lib/user.js
|
@ -28,6 +28,7 @@ var User = function (socket) {
|
||||||
this.rank = -1
|
this.rank = -1
|
||||||
this.global_rank = -1;
|
this.global_rank = -1;
|
||||||
this.channel = null;
|
this.channel = null;
|
||||||
|
this.pendingChannel = null;
|
||||||
this.name = "";
|
this.name = "";
|
||||||
this.meta = {
|
this.meta = {
|
||||||
afk: false,
|
afk: false,
|
||||||
|
@ -54,6 +55,10 @@ User.prototype.inChannel = function () {
|
||||||
return this.channel !== null && !this.channel.dead;
|
return this.channel !== null && !this.channel.dead;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
User.prototype.inPendingChannel = function () {
|
||||||
|
return this.pendingChannel != null && !this.pendingChannel.dead;
|
||||||
|
};
|
||||||
|
|
||||||
// Throttling/cooldown
|
// Throttling/cooldown
|
||||||
User.prototype.noflood = function (name, hz) {
|
User.prototype.noflood = function (name, hz) {
|
||||||
var time = new Date().getTime();
|
var time = new Date().getTime();
|
||||||
|
@ -144,7 +149,7 @@ User.prototype.initCallbacks = function () {
|
||||||
|
|
||||||
self.socket.on("joinChannel", function (data) {
|
self.socket.on("joinChannel", function (data) {
|
||||||
data = (typeof data !== "object") ? {} : data;
|
data = (typeof data !== "object") ? {} : data;
|
||||||
if (self.inChannel())
|
if (self.inChannel() || self.inPendingChannel())
|
||||||
return;
|
return;
|
||||||
if (typeof data.name != "string") {
|
if (typeof data.name != "string") {
|
||||||
return;
|
return;
|
||||||
|
@ -158,14 +163,21 @@ User.prototype.initCallbacks = function () {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data.name = data.name.toLowerCase();
|
data.name = data.name.toLowerCase();
|
||||||
self.channel = self.server.getChannel(data.name);
|
self.pendingChannel = self.server.getChannel(data.name);
|
||||||
if (self.loggedIn) {
|
if (self.loggedIn) {
|
||||||
self.channel.getRank(self.name, function (err, rank) {
|
// TODO fix
|
||||||
|
self.pendingChannel.getRank(self.name, function (err, rank) {
|
||||||
if (!err && rank > self.rank)
|
if (!err && rank > self.rank)
|
||||||
self.rank = rank;
|
self.rank = rank;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
self.channel.userJoin(self);
|
self.pendingChannel.userJoin(self);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.socket.on("channelPassword", function (pw) {
|
||||||
|
if (!self.inChannel() && self.inPendingChannel()) {
|
||||||
|
self.pendingChannel.userJoin(self, pw);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
self.socket.on("login", function (data) {
|
self.socket.on("login", function (data) {
|
||||||
|
@ -755,10 +767,13 @@ User.prototype.login = function (name, pw, session) {
|
||||||
self.channel.logger.log(self.ip + " logged in as " +
|
self.channel.logger.log(self.ip + " logged in as " +
|
||||||
name);
|
name);
|
||||||
self.channel.broadcastNewUser(self);
|
self.channel.broadcastNewUser(self);
|
||||||
|
} else if (self.inPendingChannel()) {
|
||||||
|
self.pendingChannel.userJoin(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (self.inChannel()) {
|
if (self.inChannel() || self.inPendingChannel()) {
|
||||||
self.channel.getRank(name, function (err, rank) {
|
var chan = self.channel != null ? self.channel : self.pendingChannel;
|
||||||
|
chan.getRank(name, function (err, rank) {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
self.saverank = true;
|
self.saverank = true;
|
||||||
self.rank = rank;
|
self.rank = rank;
|
||||||
|
|
|
@ -46,6 +46,9 @@ Callbacks = {
|
||||||
socket.emit("joinChannel", {
|
socket.emit("joinChannel", {
|
||||||
name: CHANNEL.name
|
name: CHANNEL.name
|
||||||
});
|
});
|
||||||
|
if (CHANNEL.opts.password) {
|
||||||
|
socket.emit("channelPassword", CHANNEL.opts.password);
|
||||||
|
}
|
||||||
if(NAME && SESSION) {
|
if(NAME && SESSION) {
|
||||||
socket.emit("login", {
|
socket.emit("login", {
|
||||||
name: NAME,
|
name: NAME,
|
||||||
|
@ -127,26 +130,44 @@ Callbacks = {
|
||||||
scrollChat();
|
scrollChat();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
needPassword: function (wrongpw) {
|
||||||
|
var div = $("<div/>");
|
||||||
|
$("<strong/>").text("Channel Password")
|
||||||
|
.appendTo(div);
|
||||||
|
if (wrongpw) {
|
||||||
|
$("<br/>").appendTo(div);
|
||||||
|
$("<span/>").addClass("text-error")
|
||||||
|
.text("Wrong Password")
|
||||||
|
.appendTo(div);
|
||||||
|
}
|
||||||
|
|
||||||
|
var pwbox = $("<input/>").addClass("input-block-level")
|
||||||
|
.attr("type", "password")
|
||||||
|
.appendTo(div);
|
||||||
|
var submit = $("<button/>").addClass("btn btn-mini btn-block")
|
||||||
|
.text("Submit")
|
||||||
|
.appendTo(div);
|
||||||
|
var parent = chatDialog(div);
|
||||||
|
parent.attr("id", "needpw");
|
||||||
|
var sendpw = function () {
|
||||||
|
socket.emit("channelPassword", pwbox.val());
|
||||||
|
parent.remove();
|
||||||
|
};
|
||||||
|
submit.click(sendpw);
|
||||||
|
pwbox.keydown(function (ev) {
|
||||||
|
if (ev.keyCode == 13) {
|
||||||
|
sendpw();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
pwbox.focus();
|
||||||
|
},
|
||||||
|
|
||||||
|
cancelNeedPassword: function () {
|
||||||
|
$("#needpw").remove();
|
||||||
|
},
|
||||||
|
|
||||||
chatCooldown: function (time) {
|
chatCooldown: function (time) {
|
||||||
time = time + 200;
|
time = time + 200;
|
||||||
/*
|
|
||||||
var msg = $("#chat-cooldown-msg");
|
|
||||||
if (msg.length > 0) {
|
|
||||||
var timer = msg.data("timer");
|
|
||||||
if (timer) {
|
|
||||||
clearTimeout(timer);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
msg = $("<div/>")
|
|
||||||
.addClass("server-msg-disconnect")
|
|
||||||
.attr("id", "chat-cooldown-msg")
|
|
||||||
.text("Chat rate limit exceeded, please wait before sending another message")
|
|
||||||
.appendTo($("#messagebuffer"));
|
|
||||||
}
|
|
||||||
if (SCROLLCHAT) {
|
|
||||||
scrollChat();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
$("#chatline").css("color", "#ff0000");
|
$("#chatline").css("color", "#ff0000");
|
||||||
if (CHATTHROTTLE && $("#chatline").data("throttle_timer")) {
|
if (CHATTHROTTLE && $("#chatline").data("throttle_timer")) {
|
||||||
clearTimeout($("#chatline").data("throttle_timer"));
|
clearTimeout($("#chatline").data("throttle_timer"));
|
||||||
|
@ -155,12 +176,6 @@ Callbacks = {
|
||||||
$("#chatline").data("throttle_timer", setTimeout(function () {
|
$("#chatline").data("throttle_timer", setTimeout(function () {
|
||||||
CHATTHROTTLE = false;
|
CHATTHROTTLE = false;
|
||||||
$("#chatline").css("color", "");
|
$("#chatline").css("color", "");
|
||||||
/*
|
|
||||||
msg.remove();
|
|
||||||
if (SCROLLCHAT) {
|
|
||||||
scrollChat();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}, time));
|
}, time));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,7 @@
|
||||||
sustained: $("#opt_chat_antiflood_sustained").val()
|
sustained: $("#opt_chat_antiflood_sustained").val()
|
||||||
},
|
},
|
||||||
show_public: $("#opt_show_public").prop("checked"),
|
show_public: $("#opt_show_public").prop("checked"),
|
||||||
|
password: $("#opt_password").val(),
|
||||||
enable_link_regex: $("#opt_enable_link_regex").prop("checked"),
|
enable_link_regex: $("#opt_enable_link_regex").prop("checked"),
|
||||||
afk_timeout: parseInt($("#opt_afktimeout").val())
|
afk_timeout: parseInt($("#opt_afktimeout").val())
|
||||||
});
|
});
|
||||||
|
|
|
@ -1010,10 +1010,14 @@ function handleModPermissions() {
|
||||||
$("#opt_externaljs").val(CHANNEL.opts.externaljs);
|
$("#opt_externaljs").val(CHANNEL.opts.externaljs);
|
||||||
$("#opt_externaljs").attr("disabled", CLIENT.rank < 3);
|
$("#opt_externaljs").attr("disabled", CLIENT.rank < 3);
|
||||||
$("#opt_chat_antiflood").prop("checked", CHANNEL.opts.chat_antiflood);
|
$("#opt_chat_antiflood").prop("checked", CHANNEL.opts.chat_antiflood);
|
||||||
$("#opt_chat_antiflood_burst").val(CHANNEL.opts.chat_antiflood_params.burst);
|
if ("chat_antiflood_parans" in CHANNEL.opts) {
|
||||||
$("#opt_chat_antiflood_sustained").val(CHANNEL.opts.chat_antiflood_params.sustained);
|
$("#opt_chat_antiflood_burst").val(CHANNEL.opts.chat_antiflood_params.burst);
|
||||||
|
$("#opt_chat_antiflood_sustained").val(CHANNEL.opts.chat_antiflood_params.sustained);
|
||||||
|
}
|
||||||
$("#opt_show_public").prop("checked", CHANNEL.opts.show_public);
|
$("#opt_show_public").prop("checked", CHANNEL.opts.show_public);
|
||||||
$("#opt_show_public").attr("disabled", CLIENT.rank < 3);
|
$("#opt_show_public").attr("disabled", CLIENT.rank < 3);
|
||||||
|
$("#opt_password").val(CHANNEL.opts.password || "");
|
||||||
|
$("#opt_password").attr("disabled", CLIENT.rank < 3);
|
||||||
$("#opt_enable_link_regex").prop("checked", CHANNEL.opts.enable_link_regex);
|
$("#opt_enable_link_regex").prop("checked", CHANNEL.opts.enable_link_regex);
|
||||||
$("#opt_afktimeout").val(CHANNEL.opts.afk_timeout);
|
$("#opt_afktimeout").val(CHANNEL.opts.afk_timeout);
|
||||||
$("#opt_allow_voteskip").prop("checked", CHANNEL.opts.allow_voteskip);
|
$("#opt_allow_voteskip").prop("checked", CHANNEL.opts.allow_voteskip);
|
||||||
|
@ -1758,6 +1762,22 @@ function unhidePlayer() {
|
||||||
.attr("height", PLAYER.size.height);
|
.attr("height", PLAYER.size.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function chatDialog(div) {
|
||||||
|
var parent = $("<div/>").addClass("profile-box")
|
||||||
|
.css("padding", "10px")
|
||||||
|
.appendTo($("body"));
|
||||||
|
|
||||||
|
div.appendTo(parent);
|
||||||
|
var cw = $("#chatwrap").width();
|
||||||
|
var ch = $("#chatwrap").height();
|
||||||
|
var cp = $("#chatwrap").offset();
|
||||||
|
var x = cp.left + cw/2 - parent.width()/2;
|
||||||
|
var y = cp.top + ch/2 - parent.height()/2;
|
||||||
|
parent.css("left", x + "px");
|
||||||
|
parent.css("top", y + "px");
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
function errDialog(err) {
|
function errDialog(err) {
|
||||||
var div = $("<div/>").addClass("profile-box")
|
var div = $("<div/>").addClass("profile-box")
|
||||||
.css("padding", "10px")
|
.css("padding", "10px")
|
||||||
|
|
|
@ -87,6 +87,13 @@
|
||||||
<input type="text" id="opt_pagetitle" placeholder="CyTube">
|
<input type="text" id="opt_pagetitle" placeholder="CyTube">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- password -->
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label" for="opt_password">Password (blank to disable)</label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" id="opt_password">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!-- external CSS -->
|
<!-- external CSS -->
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label" for="opt_externalcss">External CSS</label>
|
<label class="control-label" for="opt_externalcss">External CSS</label>
|
||||||
|
|
Loading…
Reference in a new issue