/** * Copyright 2013 Calvin 'calzoneman' Montgomery * * Licensed under Creative Commons Attribution-NonCommercial 3.0 * See http://creativecommons.org/licenses/by-nc/3.0/ * */ var Rank = require('./rank.js'); var Auth = require('./auth.js'); var Channel = require('./channel.js').Channel; var Server = require('./server.js'); // Represents a client connected via socket.io var User = function(socket, ip) { this.ip = ip; this.socket = socket; this.loggedIn = false; this.rank = Rank.Guest; this.channel = null; this.playerReady = false; this.name = ""; this.initCallbacks(); }; // Set up socket callbacks User.prototype.initCallbacks = function() { // What a shame this.socket.on('disconnect', function() { if(this.channel != null) this.channel.userLeave(this); }.bind(this)); this.socket.on('joinChannel', function(data) { // Channel already loaded if(data.name in Server.channels) { this.channel = Server.channels[data.name]; this.channel.userJoin(this); } // Channel not loaded else { Server.channels[data.name] = new Channel(data.name); this.channel = Server.channels[data.name]; this.channel.userJoin(this); } }.bind(this)); this.socket.on('login', function(data) { this.login(data.name, data.sha256); }.bind(this)); this.socket.on('register', function(data) { this.register(data.name, data.sha256); }.bind(this)); this.socket.on('assignLeader', function(data) { if(Rank.hasPermission(this, "assignLeader")) { if(this.channel != null) this.channel.changeLeader(data.name); } }.bind(this)); this.socket.on('promote', function(data) { if(this.channel != null) { this.channel.promoteUser(this, data.name); } }.bind(this)); this.socket.on('demote', function(data) { if(this.channel != null) { this.channel.demoteUser(this, data.name); } }.bind(this)); this.socket.on('chatMsg', function(data) { if(this.name != "" && this.channel != null) { this.channel.chatMessage(this, data.msg); } }.bind(this)); this.socket.on('playerReady', function() { if(this.channel != null) { this.channel.sendMediaUpdate(this); } this.playerReady = true; }.bind(this)); this.socket.on('queue', function(data) { if(Rank.hasPermission(this, "queue")) { if(this.channel != null) this.channel.enqueue(data); } }.bind(this)); this.socket.on('unqueue', function(data) { if(Rank.hasPermission(this, "queue")) { if(this.channel != null) this.channel.unqueue(data); } }.bind(this)); this.socket.on('moveMedia', function(data) { if(Rank.hasPermission(this, "queue")) { if(this.channel != null) this.channel.moveMedia(data); } }.bind(this)); this.socket.on('playNext', function() { if(Rank.hasPermission(this, "queue") || (this.channel != null && this.channel.leader == this)) { this.channel.playNext(); } }.bind(this)); this.socket.on('mediaUpdate', function(data) { if(this.channel != null && this.channel.leader == this) { this.channel.update(data); } }.bind(this)); this.socket.on('searchLibrary', function(data) { if(this.channel != null && Rank.hasPermission(this, "search")) { this.socket.emit('librarySearchResults', { results: this.channel.searchLibrary(data.query) }); } }.bind(this)); } // Attempt to login User.prototype.login = function(name, sha256) { // No password => try guest login if(sha256 == "") { // Sorry bud, can't take that name if(Auth.isRegistered(name)) { this.socket.emit('login', { success: false, error: "That username is already taken" }); return false; } // YOUR ARGUMENT IS INVALID else if(!Auth.validateName(name)) { this.socket.emit('login', { success: false, error: "Invalid username. Usernames must be 1-20 characters long and consist only of alphanumeric characters and underscores" }); } // Woah, success! else { console.log(this.ip + " signed in as " + name); this.name = name; this.loggedIn = false; this.socket.emit('login', { success: true }); this.socket.emit('rank', { rank: this.rank }); if(this.channel != null) { if(this.rank >= Rank.Moderator) this.channel.sendPlaylist(this); this.channel.broadcastNewUser(this); } } } else { var row; if((row = Auth.login(name, sha256))) { this.socket.emit('login', { success: true }); console.log(this.ip + " logged in as " + name); // Sweet, let's look up our rank var chanrank = (this.channel != null) ? this.channel.getRank(name) : Rank.Guest; this.rank = (chanrank > row.global_rank) ? chanrank : row.global_rank; this.socket.emit('rank', { rank: this.rank }); this.name = name; if(this.channel != null) { if(this.rank >= Rank.Moderator) this.channel.sendPlaylist(this); this.channel.broadcastNewUser(this); } } // Wrong password else { this.socket.emit('login', { success: false, error: "Invalid username/password pair" }); return false; } } } // Attempt to register a user account User.prototype.register = function(name, sha256) { if(sha256 == "") { // Sorry bud, password required this.socket.emit('register', { success: false, error: "You must provide a password" }); return false; } else if(Auth.isRegistered(name)) { this.socket.emit('register', { success: false, error: "That username is already taken" }); return false; } else if(!Auth.validateName(name)) { this.socket.emit('register', { success: false, error: "Invalid username. Usernames must be 1-20 characters long and consist only of alphanumeric characters and underscores" }); } else if(Auth.register(name, sha256)) { console.log(this.ip + " registered " + name); this.socket.emit('register', { success: true }); this.login(name, sha256); } else { this.socket.emit('register', { success: false, error: "[](/ppshrug) Registration Failed." }); } } exports.User = User;