diff --git a/src/app/channel/activeChannel.js b/src/app/channel/activeChannel.js
index 143c03e..949e438 100644
--- a/src/app/channel/activeChannel.js
+++ b/src/app/channel/activeChannel.js
@@ -15,8 +15,69 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .*/
module.exports = class{
- constructor(name){
+ constructor(server, name){
+ this.server = server;
this.name = name;
this.userList = new Map();
}
+
+ handleConnection(userDB, socket){
+ //get current user object from the userlist
+ var userObj = this.userList.get(userDB.user);
+
+ //If user is already connected
+ if(userObj){
+ //Add this socket on to the userobject
+ userObj.sockets.push(socket.id);
+ }else{
+ //if this is the first connection, initialize the userObject w/ the current socked id
+ userObj = {
+ id: userDB.id,
+ rank: userDB.rank,
+ flair: userDB.flair,
+ sockets: [socket.id]
+ }
+ }
+
+ //Set user entry in userlist
+ this.userList.set(userDB.user, userObj);
+
+ //if everything looks good, admit the connection to the channel
+ socket.join(socket.chan);
+
+ //Send out the userlist
+ this.broadcastUserList(socket.chan);
+ }
+
+ handleDisconnect(socket, reason){
+ //If we have more than one active connection
+ if(this.userList.get(socket.user.user).sockets.length > 1){
+ //temporarily store userObj
+ var userObj = this.userList.get(socket.user.user);
+
+ //Filter out disconnecting socket from socket list, and set as current socket list for user
+ userObj.sockets = userObj.sockets.filter((id) => {
+ return id != socket.id;
+ });
+
+ //Update the userlist
+ this.userList.set(socket.user.user, userObj);
+ }else{
+ //If this is the last connection for this user, remove them from the userlist
+ this.userList.delete(socket.user.user);
+ }
+
+ //and send out the filtered list
+ this.broadcastUserList(socket.chan);
+ }
+
+ broadcastUserList(){
+ var userList = [];
+
+ this.userList.forEach((userObj, user) => {
+ userList.push(user);
+ });
+
+ this.server.io.in(this.name).emit("user-list", userList);
+ }
}
\ No newline at end of file
diff --git a/src/app/channel/channelManager.js b/src/app/channel/channelManager.js
index 74cb43a..7b0006e 100644
--- a/src/app/channel/channelManager.js
+++ b/src/app/channel/channelManager.js
@@ -18,6 +18,7 @@ along with this program. If not, see .*/
const channelModel = require('../../schemas/channelSchema');
const flairModel = require('../../schemas/flairSchema');
const userModel = require('../../schemas/userSchema');
+const loggerUtils = require('../../utils/loggerUtils');
const activeChannel = require('./activeChannel');
const chatHandler = require('./chatHandler');
@@ -40,111 +41,78 @@ module.exports = class{
//Prevent logged out connections and authenticate socket
if(socket.request.session.user != null){
try{
- //Find the user in the Database since the session won't store enough data to fulfill our needs :P
- const userDB = await userModel.findOne({user: socket.request.session.user.user});
+ //Authenticate socket
+ const userDB = await this.authSocket(socket);
- //Set socket user and channel values
- socket.user = {
- id: userDB.id,
- user: userDB.user,
- };
+ //Get the active channel based on the socket
+ var activeChan = await this.getActiveChan(socket);
- socket.chanName = socket.handshake.headers.referer.split('/c/')[1];
-
- //Check if channel exists
- if(await channelModel.findOne({name: socket.chanName}) == null){
- socket.disconnect("Channel does not exist!");
- return;
- }
-
- //Check if current channel is active
- var activeChan = this.activeChannels.get(socket.chan);
- if(!activeChan){
- //If not, make it so
- activeChan = new activeChannel(socket.chan);
- this.activeChannels.set(socket.chan, activeChan);
- }
-
- //Check if this user is already connected
- if(activeChan.userList.get(socket.user.user)){
- //get current list of socket connnections of selected user
- var userObj = activeChan.userList.get(userDB.user);
- //Add this one on
- userObj.sockets.push(socket.id);
- //Set the user back socket list back
- activeChan.userList.set(userDB.user, userObj);
- }else{
- //if this is the first connection, initialize the socket array for this user
- var userObj = {
- id: userDB.id,
- rank: userDB.rank,
- flair: userDB.flair,
- sockets: [socket.id]
- }
-
- activeChan.userList.set(userDB.user, userObj);
- }
-
- //if everything looks good, admit the connection to the channel
- socket.join(socket.chan);
-
- //Send out the userlist
- this.broadcastUserList(socket.chan);
+ //Define listeners
+ this.defineListeners(socket);
+ this.chatHandler.defineListeners(socket);
+ //Connect the socket to it's given channel
+ activeChan.handleConnection(userDB, socket);
}catch(err){
- socket.disconnect("Server Error During Channel Connection Initialization");
- console.log(err);
- return;
+ //Flip a table if something fucks up
+ return loggerUtils.socketCriticalExceptionHandler(socket, err);
}
-
}else{
+ //Toss out anon's
socket.disconnect("Unauthenticated");
return;
}
+ }
+ async authSocket(socket){
+ //Find the user in the Database since the session won't store enough data to fulfill our needs :P
+ const userDB = await userModel.findOne({user: socket.request.session.user.user});
+
+ if(userDB == null){
+ throw new Error("User not found!");
+ }
+
+ //Set socket user and channel values
+ socket.user = {
+ id: userDB.id,
+ user: userDB.user,
+ };
+
+ return userDB;
+ }
+
+ async getActiveChan(socket){
+ socket.chan = socket.handshake.headers.referer.split('/c/')[1];
+
+ //Check if channel exists
+ if(await channelModel.findOne({name: socket.chan}) == null){
+ throw new Error("Channel not found!")
+ }
+
+ //Check if current channel is active
+ var activeChan = this.activeChannels.get(socket.chan);
+
+ if(!activeChan){
+ //If not, make it so
+ activeChan = new activeChannel(this, socket.chan);
+ this.activeChannels.set(socket.chan, activeChan);
+ }
+
+ //Return whatever the active channel is (new or old)
+ return activeChan;
+ }
+
+ defineListeners(socket){
//Socket Listeners
- socket.conn.on("close", (reason) => {
- //Get active channel
- var activeChan = this.activeChannels.get(socket.chan);
-
- //If we have more than one active connection
- if(activeChan.userList.get(socket.user.user).sockets.length > 1){
- //temporarily store userObj
- var userObj = activeChan.userList.get(socket.user.user);
-
- //Filter out disconnecting socket from socket list, and set as current socket list for user
- userObj.sockets = userObj.sockets.filter((id) => {
- return id != socket.id;
- });
-
- //Update the userlist
- activeChan.userList.set(socket.user.user, userObj);
- }else{
- //If this is the last connection for this user, remove them from the userlist
- activeChan.userList.delete(socket.user.user);
- }
-
- //and send out the filtered list
- this.broadcastUserList(socket.chan);
- });
-
- //define chat listeners
- this.chatHandler.defineListeners(socket);
-
+ socket.conn.on("close", (reason) => {this.handleDisconnect(socket, reason)});
}
- broadcastUserList(chan){
- var activeChan = this.activeChannels.get(chan);
- var userList = [];
-
- activeChan.userList.forEach((socketlist, user) => {
- userList.push(user);
- });
-
- this.io.in(chan).emit("user-list", userList);
+ handleDisconnect(socket, reason){
+ var activeChan = this.activeChannels.get(socket.chan);
+ activeChan.handleDisconnect(socket, reason);
}
- socketToUser(socket){
+ getSocketInfo(socket){
const channel = this.activeChannels.get(socket.chan);
return channel.userList.get(socket.user.user);
}
diff --git a/src/app/channel/chatHandler.js b/src/app/channel/chatHandler.js
index 327071e..48f6ffd 100644
--- a/src/app/channel/chatHandler.js
+++ b/src/app/channel/chatHandler.js
@@ -28,39 +28,42 @@ module.exports = class{
}
defineListeners(socket){
- socket.on("chatMessage", (data) => {
- //Trim and Sanatize for XSS
- const msg = validator.trim(validator.escape(data.msg));
- //make sure high is an int
- const high = validator.toInt(data.high);
-
- const user = this.server.socketToUser(socket);
+ socket.on("chatMessage", (data) => {this.relayChat(socket, data)});
+ socket.on("setFlair", async (data) => {this.setFlair(socket, data)});
+ }
- //nuke the message if its empty or huge
- if(!validator.isLength(msg, {min: 1, max: 255})){
- return;
+ relayChat(socket, data){
+ //Trim and Sanatize for XSS
+ const msg = validator.trim(validator.escape(data.msg));
+ //make sure high is an int
+ const high = validator.toInt(data.high);
+
+ const user = this.server.getSocketInfo(socket);
+
+ //nuke the message if its empty or huge
+ if(!validator.isLength(msg, {min: 1, max: 255})){
+ return;
+ }
+
+ //nuke the message if the high number is wrong
+ if(high < 0 || high > 10){
+ return;
+ }
+
+ this.server.io.in(socket.chan).emit("chatMessage", {user: socket.user.user, flair: user.flair, high, msg});
+ }
+
+ async setFlair(socket, data){
+ const userDB = await userModel.findOne({user: socket.user.user});
+
+ if(userDB){
+ try{
+ //We can take this data raw since our schema checks it against existing flairs, and mongoose sanatizes queries
+ userDB.flair = data.flair;
+ await userDB.save();
+ }catch(err){
+ return loggerUtils.socketExceptionHandler(socket, err);
}
-
- //nuke the message if the high number is wrong
- if(high < 0 || high > 10){
- return;
- }
-
- this.server.io.in(socket.chan).emit("chatMessage", {user: socket.user.user, flair: user.flair, high, msg});
- });
-
- socket.on("setFlair", async (data) => {
- const userDB = await userModel.findOne({user: socket.user.user});
-
- if(userDB){
- try{
- //We can take this data raw since our schema checks it against existing flairs, and mongoose sanatizes queries
- userDB.flair = data.flair;
- await userDB.save();
- }catch(err){
- return loggerUtils.socketExceptionHandler(socket, err);
- }
- }
- });
+ }
}
}
\ No newline at end of file
diff --git a/src/utils/loggerUtils.js b/src/utils/loggerUtils.js
index 86fd372..7e246c5 100644
--- a/src/utils/loggerUtils.js
+++ b/src/utils/loggerUtils.js
@@ -24,4 +24,9 @@ module.exports.exceptionHandler = function(res, err){
module.exports.socketExceptionHandler = function(socket, err){
//if not yell at the browser for fucking up, and tell it what it did wrong.
return socket.emit("error", {errors: [{type: "Caught Exception", msg: err.message, date: new Date()}]});
+}
+
+module.exports.socketCriticalExceptionHandler = function(socket, err){
+ //if not yell at the browser for fucking up, and tell it what it did wrong.
+ return socket.disconnect("error", {errors: [{type: "Caught Exception", msg: err.message, date: new Date()}]});
}
\ No newline at end of file