diff --git a/socketserver/db_mysql.js b/socketserver/db_mysql.js
index 580d40b..244d095 100644
--- a/socketserver/db_mysql.js
+++ b/socketserver/db_mysql.js
@@ -139,6 +139,12 @@ var MysqlDB = function(){
`time` DATETIME\
);\
\
+ CREATE TABLE IF NOT EXISTS `user_blocks` (\
+ `from` INTEGER UNSIGNED NOT NULL,\
+ `to` INTEGER UNSIGNED NOT NULL,\
+ PRIMARY KEY(`from`, `to`)\
+ );\
+ \
UPDATE `users` SET `lastdj` = false;\
", null, function(err, res){
if(err) throw new Error(err);
@@ -476,12 +482,16 @@ MysqlDB.prototype.getUserNoLogin = function(uid, callback){
un: res.un,
uid: res.id,
salt: res.salt,
+ blocked: [],
}
- that.execute("SELECT `id` FROM `playlists` WHERE `owner` = ?;", [ uid ], function(err, res) {
+ that.execute("SELECT `id` FROM `playlists` WHERE ?; SELECT `to` FROM `user_blocks` WHERE ?", [ { owner: uid, }, { from: uid,} ], function(err, res) {
- for(var ind in res)
- data.playlists.push(res[ind].id);
+ for(var ind in res[0])
+ data.playlists.push(res[0][ind].id);
+
+ for(var ind in res[1])
+ data.blocked.push(res[1][ind].to);
callback(null, data);
});
@@ -634,11 +644,15 @@ MysqlDB.prototype.loginUser = function(obj, callback) {
};
MysqlDB.prototype.putUser = function(email, data, callback) {
+ var that = this;
+
callback = callback || function(){};
var newData = {};
util._extend(newData, data);
+ var blocked = newData.blocked.map(function(x) { return [data.uid, x]; });
+
newData.badge_bottom = newData.badge.bottom;
newData.badge_top = newData.badge.top;
newData.recovery_timeout = new Date(newData.recovery.timeout);
@@ -649,9 +663,17 @@ MysqlDB.prototype.putUser = function(email, data, callback) {
delete newData.uid;
delete newData.badge;
delete newData.playlists;
- this.execute("INSERT INTO `users`(??) VALUES(?) ON DUPLICATE KEY UPDATE ?;", [ Object.keys(newData), _.values(newData), newData ], function(err, res) {
- if(err) callback(err);
- else callback(null, res.insertId);
+ delete newData.blocked;
+
+ this.execute("INSERT INTO `users`(??) VALUES(?) ON DUPLICATE KEY UPDATE ?; DELETE FROM `user_blocks` WHERE ?;", [ Object.keys(newData), _.values(newData), newData, { from: data.uid } ], function(err, res) {
+ if(err)
+ callback(err);
+ else
+ callback(null, res.insertId);
+
+ if(blocked.length) {
+ that.execute("INSERT INTO `user_blocks`(??) VALUES ?;", [ [ 'from', 'to' ], blocked ]);
+ }
});
};
diff --git a/socketserver/socketserver.js b/socketserver/socketserver.js
index 48e3eb3..fead46a 100644
--- a/socketserver/socketserver.js
+++ b/socketserver/socketserver.js
@@ -3078,6 +3078,74 @@ var SocketServer = function(server){
else
DB.getUserByUid(~~(data.data.uid), { getPlaylists: false }, cb);
break;
+ case 'blockUser':
+ /*
+ Expects {
+ type: 'blockUser',
+ data: {
+ uid: uid,
+ }
+ }
+ */
+
+ //Check for props
+ if (!(data.data.uid = +data.data.uid) || uid < 0){
+ returnObj.data = {
+ error: 'WrongProps'
+ };
+ socket.sendJSON(returnObj);
+ break;
+ }
+
+ //Add blocked user
+ socket.user.addBlockedUser(data.data.uid, function(err) {
+ if(err) {
+ returnObj.data = {
+ error: err
+ }
+ } else {
+ returnObj.data = {
+ success: true
+ }
+ }
+
+ socket.sendJSON(returnObj);
+ });
+ break;
+ case 'unblockUser':
+ /*
+ Expects {
+ type: 'unblockUser',
+ data: {
+ uid: uid,
+ }
+ }
+ */
+
+ //Check for props
+ if (!(data.data.uid = +data.data.uid)){
+ returnObj.data = {
+ error: 'WrongProps'
+ };
+ socket.sendJSON(returnObj);
+ break;
+ }
+
+ //Remove blocked user
+ socket.user.removeBlockedUser(data.data.uid, function(err) {
+ if(err) {
+ returnObj.data = {
+ error: err
+ }
+ } else {
+ returnObj.data = {
+ success: true
+ }
+ }
+
+ socket.sendJSON(returnObj);
+ });
+ break;
}
});
});
diff --git a/socketserver/user.js b/socketserver/user.js
index 2d47a6b..a37a2c9 100644
--- a/socketserver/user.js
+++ b/socketserver/user.js
@@ -23,6 +23,7 @@ var defaultObj = function(){
temp_uptime: Date.now(),
lastdj: false,
salt: '',
+ blocked: [],
};
};
@@ -39,6 +40,7 @@ var fieldsNotSent = [
'created',
'lastdj',
'salt',
+ 'blocked',
];
// These fields (key from defaultObj) are not saved in the db
@@ -180,6 +182,35 @@ User.prototype.removePlaylist = function (pid, callback) {
callback('PlaylistNotFound');
};
+User.prototype.addBlockedUser = function(uid, callback) {
+ var index = this.data.blocked.indexOf(uid);
+
+ if(index != -1) {
+ callback('UserAlreadyBlocked');
+
+ } else if(this.data.uid == uid) {
+ callback('CannotBlockSelf');
+
+ } else {
+ this.data.blocked.push(uid);
+ this.updateUser();
+ callback(null, true);
+ }
+};
+
+User.prototype.removeBlockedUser = function(uid, callback) {
+ var index = this.data.blocked.indexOf(uid);
+
+ if(index == -1) {
+ callback('UserNotBlocked');
+
+ } else {
+ this.data.blocked.splice(index, 1);
+ this.updateUser();
+ callback(null, true);
+ }
+}
+
/**
* getClientObj() Returns public information to be sent to clients
*
@@ -361,4 +392,14 @@ Object.defineProperty( User.prototype, 'salt', {
}
});
+Object.defineProperty( User.prototype, 'blocked', {
+ get: function() {
+ return this.data.blocked;
+ },
+ set: function(val) {
+ this.data.blocked = val;
+ this.updateUser();
+ }
+});
+
module.exports = User;
\ No newline at end of file
diff --git a/webserver/public/lib/js/app.js b/webserver/public/lib/js/app.js
index f38032c..a35b1b3 100644
--- a/webserver/public/lib/js/app.js
+++ b/webserver/public/lib/js/app.js
@@ -261,6 +261,7 @@
historylimit: 50,
lastdj: false,
description: '',
+ blockedusers: [],
},
isOnWaitlist: function(uid){
if (MP.session.queue.currentdj && MP.session.queue.currentdj.uid == uid) return true;
@@ -1580,6 +1581,54 @@
$('#creds-back').hide();
$('.dash, #app-left, #app-right').show();
},
+ user: {
+ isBlocked: function(uid) {
+ return MP.session.blockedusers.indexOf(uid) != -1;
+ },
+ block: function(uid, callback) {
+ if(!(uid = +uid))
+ return false
+
+ var obj = {
+ type: 'blockUser',
+ data: {
+ uid: uid
+ }
+ }
+
+ obj.id = MP.addCallback(obj.type, function(err, data) {
+ MP.session.blockedusers.push(uid);
+
+ if(callback)
+ callback(err, data);
+ });
+
+ socket.sendJSON(obj);
+ },
+ unblock: function(uid, callback) {
+ if(!(uid = +uid))
+ return false
+
+ var obj = {
+ type: 'unblockUser',
+ data: {
+ uid: uid
+ }
+ }
+
+ obj.id = MP.addCallback(obj.type, function(err, data) {
+ var index = MP.session.blockedusers.indexOf(uid);
+
+ if(index != -1)
+ MP.session.blockedusers.splice(index, 1);
+
+ if(callback)
+ callback(err, data);
+ });
+
+ socket.sendJSON(obj);
+ }
+ },
},
mediaPreview : {
isOpened: function(){return MP.session.mediaPreview.player != null;},
@@ -1923,6 +1972,9 @@
}
var user = data.user || MP.findUser(data.uid);
+ if(MP.api.user.isBlocked(user.uid))
+ return;
+
var queue_pos = MP.findPosInWaitlist();
var mention = '';
@@ -2550,6 +2602,38 @@
});
},
},
+
+ block: {
+ description: 'Blocks or unblocks a user, blocking will remove any further messages from him',
+ exec: function(arr){
+ arr.shift();
+
+ if (arr.length != 1 || typeof arr[0] != 'string' || arr[0].charAt(0)!='@' || (arr[1] = +arr[1])){
+ return API.chat.log('
Try /block @username', 'Block a user');
+ }
+
+ var user = MP.api.room.getUserByName(arr[0].substring(1));
+
+ if (!user)
+ return API.chat.log('User ' + arr[0] + ' is not in the pad', 'Block or unblock a user');
+
+ if(MP.api.user.isBlocked(user.uid)) {
+ MP.api.user.unblock(user.uid, function(err) {
+ if(err)
+ return API.chat.log('Could not unblock user ' + arr[0]);
+
+ API.chat.log('User ' + arr[0] + ' successfully unblocked');
+ })
+ } else {
+ MP.api.user.block(user.uid, function(err) {
+ if(err)
+ return API.chat.log('Could not block user ' + arr[0]);
+
+ API.chat.log('User ' + arr[0] + ' successfully blocked');
+ })
+ }
+ },
+ },
},
sendMessage: function(message, staff){
staff = staff || false;
@@ -4256,7 +4340,7 @@