diff --git a/README.md b/README.md index 3c905931..0d550ba5 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ I'm using v0.8.20, please feel free to report which versions do/do not work 5. Install your distribution's `libmysqlclient` package 6. Install the libmysql node module: `npm install mysql-libmysqlclient` 7. Edit `config.js` and input your database details and connection port - 8. Edit `www/assets/js/client.js` and change the value of `IO_URL` to `yourhostname:port` where `port` is the port defined in `config.js` + 8. Edit `www/assets/js/iourl.js` and change the value of `IO_URL` to `yourhostname:port` where `port` is the port defined in `config.js` Running ------- diff --git a/database.js b/database.js new file mode 100644 index 00000000..02f4be19 --- /dev/null +++ b/database.js @@ -0,0 +1,101 @@ +var mysql = require('mysql-libmysqlclient'); +var Config = require('./config.js'); + +var initialized = false; + +exports.init = function() { + if(initialized) + return; + + var db = mysql.createConnectionSync(); + db.connectSync(Config.MYSQL_SERVER, Config.MYSQL_USER, + Config.MYSQL_PASSWORD, Config.MYSQL_DB); + var query = "CREATE TABLE IF NOT EXISTS `channels` \ + (`id` INT NOT NULL, \ + `name` VARCHAR(255) NOT NULL, \ + PRIMARY KEY (`id`)) \ + ENGINE = MyISAM;"; + var results = db.querySync(query); + if(!results) { + console.log("Database initialization failed! Could not create channel table"); + return false; + } + + var query = "CREATE TABLE IF NOT EXISTS `registrations` \ + (`id` INT NOT NULL, \ + `uname` VARCHAR(20) NOT NULL, \ + `pw` VARCHAR(64) NOT NULL, \ + `global_rank` INT NOT NULL, \ + PRIMARY KEY (`id`)) \ + ENGINE = MyISAM;"; + var results = db.querySync(query); + if(!results) { + console.log("Database initialization failed! Could not create registration table"); + return false; + } + + initialized = true; + return true; +} + +exports.listChannels = function() { + if(!initialized) + return false; + var db = mysql.createConnectionSync(); + db.connectSync(Config.MYSQL_SERVER, Config.MYSQL_USER, + Config.MYSQL_PASSWORD, Config.MYSQL_DB); + var query = "SELECT * FROM `channels`"; + var results = db.querySync(query); + if(!results) { + console.log("Database channel listing failed!"); + return false; + } + + if(results) { + var rows = results.fetchAllSync(); + db.closeSync(); + return rows; + } +}; + +exports.listUsers = function() { + if(!initialized) + return false; + var db = mysql.createConnectionSync(); + db.connectSync(Config.MYSQL_SERVER, Config.MYSQL_USER, + Config.MYSQL_PASSWORD, Config.MYSQL_DB); + var query = "SELECT * FROM `registrations`"; + var results = db.querySync(query); + if(!results) { + console.log("Database user listing failed!"); + return false; + } + + if(results) { + var rows = results.fetchAllSync(); + db.closeSync(); + return rows; + } +}; + +exports.listChannelRanks = function(chan) { + if(!initialized) + return false; + var db = mysql.createConnectionSync(); + db.connectSync(Config.MYSQL_SERVER, Config.MYSQL_USER, + Config.MYSQL_PASSWORD, Config.MYSQL_DB); + var query = "SELECT * FROM `chan_{}_ranks`" + .replace(/\{\}/, chan); + console.log(query); + var results = db.querySync(query); + if(!results) { + console.log("Database channel listing failed!"); + return false; + } + + if(results) { + var rows = results.fetchAllSync(); + db.closeSync(); + return rows; + } +}; diff --git a/rank.js b/rank.js index a4257d32..5358b015 100644 --- a/rank.js +++ b/rank.js @@ -13,6 +13,7 @@ exports.Owner = 3; exports.Siteadmin = 255; var permissions = { + acp: exports.Siteadmin, queue: exports.Moderator, assignLeader: exports.Moderator, kick: exports.Moderator, diff --git a/server.js b/server.js index e813639a..d721f4b0 100644 --- a/server.js +++ b/server.js @@ -11,6 +11,8 @@ var Config = require('./config.js'); var connect = require('connect'); var app = connect.createServer(connect.static(__dirname+'/www')).listen(Config.IO_PORT); var io = require('socket.io').listen(app); +var Database = require('./database.js'); +Database.init(); exports.channels = {}; diff --git a/user.js b/user.js index 3d9b281f..212546d2 100644 --- a/user.js +++ b/user.js @@ -10,6 +10,7 @@ var Rank = require('./rank.js'); var Auth = require('./auth.js'); var Channel = require('./channel.js').Channel; var Server = require('./server.js'); +var Database = require('./database.js'); // Represents a client connected via socket.io var User = function(socket, ip) { @@ -133,8 +134,65 @@ User.prototype.initCallbacks = function() { } }.bind(this)); + this.socket.on('adm', function(data) { + if(Rank.hasPermission(this, "acp")) { + this.handleAdm(data); + } + }.bind(this)); } +// Handle administration +User.prototype.handleAdm = function(data) { + if(data.cmd == "listloadedchannels") { + var chans = []; + for(var chan in Server.channels) { + var users = []; + for(var i = 0; i < Server.channels[chan].users.length; i++) { + users.push(Server.channels[chan].users[i].name); + } + chans.push({ + chan: chan, + users: users + }); + } + this.socket.emit('adm', { + cmd: "listloadedchannels", + chans: chans + }); + } + else if(data.cmd == "listchannels") { + this.socket.emit('adm', { + cmd: "listchannels", + chans: Database.listChannels() + }); + } + else if(data.cmd == "listusers") { + var users = []; + var dbusers = Database.listUsers(); + if(!dbusers) + return; + for(var i = 0; i < dbusers.length; i++) { + users[i] = { + name: dbusers[i].uname, + rank: dbusers[i].global_rank + }; + } + this.socket.emit('adm', { + cmd: "listusers", + users: users + }); + } + else if(data.cmd == "listchannelranks") { + if(data.chan == undefined) + return; + this.socket.emit('adm', { + cmd: "listchannelranks", + ranks: Database.listChannelRanks(data.chan) + }); + } + +}; + // Attempt to login User.prototype.login = function(name, sha256) { // No password => try guest login diff --git a/www/acp.html b/www/acp.html new file mode 100644 index 00000000..45a36b25 --- /dev/null +++ b/www/acp.html @@ -0,0 +1,90 @@ + + + + + Sync + + + + + + + + + + + + + + +
+
+ +
+
+
+

Channel List

+ + + + + + + +
idChannel Name
+
+
+

Channel:

+ + + + + + + + +
UsernameRank
+
+
+
+
+
+ + + + + + + + + diff --git a/www/assets/js/acp.js b/www/assets/js/acp.js new file mode 100644 index 00000000..484166b0 --- /dev/null +++ b/www/assets/js/acp.js @@ -0,0 +1,183 @@ +/** + * Copyright 2013 Calvin 'calzoneman' Montgomery + * + * Licensed under Creative Commons Attribution-NonCommercial 3.0 + * See http://creativecommons.org/licenses/by-nc/3.0/ + * + */ + +var RANK = 0; +var uname = readCookie('sync_uname'); +var pw = readCookie('sync_pw'); +var manageChannel = false; + +var Rank = { + Guest: 0, + Member: 1, + Moderator: 2, + Owner: 3, + Siteadmin: 255 +}; + +var socket = io.connect(IO_URL); +initCallbacks(); + +function initCallbacks() { + + socket.on('adm', function(data) { + console.log(data); + if(data.cmd == "listchannels") + handleChannelList(data); + if(data.cmd == "listchannelranks") + handleChannelRanks(data); + }); + + socket.on('login', function(data) { + if(data.success && $('#password').val()) { + createCookie('sync_uname', uname, 1); + createCookie('sync_pw', pw, 1); + } + if(data.success) { + $('#loggedin').css('display', ''); + $('#logoutform').css('display', ''); + $('#loginform').css('display', 'none'); + } + socket.emit('adm', { + cmd: "listloadedchannels" + }); + socket.emit('adm', { + cmd: "listchannels" + }); + socket.emit('adm', { + cmd: "listusers" + }); + }); +} + +function handleChannelList(data) { + if($('#chanlist').children.length > 1) + $($('#chanlist').children()[1]).remove(); + for(var i = 0; i < data.chans.length; i++) { + var row = $('').appendTo($('#chanlist')); + var id = $('').appendTo(row).text(data.chans[i].id); + var name = $('').appendTo(row).text(data.chans[i].name); + var manage = $('