Cleaned up 'src/app/channel'
This commit is contained in:
parent
985f8a250f
commit
5b5f495853
|
|
@ -15,8 +15,69 @@ You should have received a copy of the GNU Affero General Public License
|
|||
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
|||
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{
|
||||
//Authenticate socket
|
||||
const userDB = await this.authSocket(socket);
|
||||
|
||||
//Get the active channel based on the socket
|
||||
var activeChan = await this.getActiveChan(socket);
|
||||
|
||||
//Define listeners
|
||||
this.defineListeners(socket);
|
||||
this.chatHandler.defineListeners(socket);
|
||||
|
||||
//Connect the socket to it's given channel
|
||||
activeChan.handleConnection(userDB, socket);
|
||||
}catch(err){
|
||||
//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,
|
||||
};
|
||||
|
||||
socket.chanName = socket.handshake.headers.referer.split('/c/')[1];
|
||||
return userDB;
|
||||
}
|
||||
|
||||
async getActiveChan(socket){
|
||||
socket.chan = 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;
|
||||
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(socket.chan);
|
||||
activeChan = new activeChannel(this, 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);
|
||||
|
||||
}catch(err){
|
||||
socket.disconnect("Server Error During Channel Connection Initialization");
|
||||
console.log(err);
|
||||
return;
|
||||
}
|
||||
|
||||
}else{
|
||||
socket.disconnect("Unauthenticated");
|
||||
return;
|
||||
//Return whatever the active channel is (new or old)
|
||||
return activeChan;
|
||||
}
|
||||
|
||||
defineListeners(socket){
|
||||
//Socket Listeners
|
||||
socket.conn.on("close", (reason) => {
|
||||
//Get active channel
|
||||
socket.conn.on("close", (reason) => {this.handleDisconnect(socket, reason)});
|
||||
}
|
||||
|
||||
handleDisconnect(socket, reason){
|
||||
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);
|
||||
activeChan.handleDisconnect(socket, reason);
|
||||
}
|
||||
|
||||
//and send out the filtered list
|
||||
this.broadcastUserList(socket.chan);
|
||||
});
|
||||
|
||||
//define chat listeners
|
||||
this.chatHandler.defineListeners(socket);
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
socketToUser(socket){
|
||||
getSocketInfo(socket){
|
||||
const channel = this.activeChannels.get(socket.chan);
|
||||
return channel.userList.get(socket.user.user);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,13 +28,17 @@ module.exports = class{
|
|||
}
|
||||
|
||||
defineListeners(socket){
|
||||
socket.on("chatMessage", (data) => {
|
||||
socket.on("chatMessage", (data) => {this.relayChat(socket, data)});
|
||||
socket.on("setFlair", async (data) => {this.setFlair(socket, data)});
|
||||
}
|
||||
|
||||
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.socketToUser(socket);
|
||||
const user = this.server.getSocketInfo(socket);
|
||||
|
||||
//nuke the message if its empty or huge
|
||||
if(!validator.isLength(msg, {min: 1, max: 255})){
|
||||
|
|
@ -47,9 +51,9 @@ module.exports = class{
|
|||
}
|
||||
|
||||
this.server.io.in(socket.chan).emit("chatMessage", {user: socket.user.user, flair: user.flair, high, msg});
|
||||
});
|
||||
}
|
||||
|
||||
socket.on("setFlair", async (data) => {
|
||||
async setFlair(socket, data){
|
||||
const userDB = await userModel.findOne({user: socket.user.user});
|
||||
|
||||
if(userDB){
|
||||
|
|
@ -61,6 +65,5 @@ module.exports = class{
|
|||
return loggerUtils.socketExceptionHandler(socket, err);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -25,3 +25,8 @@ 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()}]});
|
||||
}
|
||||
Loading…
Reference in a new issue