From adfb89a2ad308aa3adb422df425c941b5ebc9c89 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Thu, 30 Oct 2014 17:50:07 -0400 Subject: [PATCH] closed #2321 --- public/language/en_GB/error.json | 1 + public/language/en_GB/user.json | 1 + public/src/app.js | 24 +++++++++----- public/src/client/chats.js | 11 +++++-- public/src/modules/chat.js | 4 +++ src/messaging.js | 28 ++++++++++++++++ src/socket.io/modules.js | 56 ++++++++++++++++++++------------ src/user/settings.js | 4 ++- 8 files changed, 95 insertions(+), 34 deletions(-) diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json index 8bd73d2c93..6f0c2653da 100644 --- a/public/language/en_GB/error.json +++ b/public/language/en_GB/error.json @@ -77,6 +77,7 @@ "signature-too-long" : "Sorry, your signature cannot be longer than %1 characters.", "cant-chat-with-yourself": "You can't chat with yourself!", + "chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them", "reputation-system-disabled": "Reputation system is disabled.", "downvoting-disabled": "Downvoting is disabled", diff --git a/public/language/en_GB/user.json b/public/language/en_GB/user.json index 223363df05..2562dfe575 100644 --- a/public/language/en_GB/user.json +++ b/public/language/en_GB/user.json @@ -53,6 +53,7 @@ "settings": "Settings", "show_email": "Show My Email", "show_fullname": "Show My Full Name", + "restrict_chats": "Only allow chat messages from users I follow", "digest_label": "Subscribe to Digest", "digest_description": "Subscribe to email updates for this forum (new notifications and topics) according to a set schedule", "digest_off": "Off", diff --git a/public/src/app.js b/public/src/app.js index 815f4752cb..b13d2eca04 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -314,16 +314,22 @@ var socket, } require(['chat'], function (chat) { - if (!chat.modalExists(touid)) { - chat.createModal(username, touid, loadAndCenter); - } else { - loadAndCenter(chat.getModal(touid)); - } + chat.canMessage(touid, function(err) { + if (!err) { + if (!chat.modalExists(touid)) { + chat.createModal(username, touid, loadAndCenter); + } else { + loadAndCenter(chat.getModal(touid)); + } - function loadAndCenter(chatModal) { - chat.load(chatModal.attr('UUID')); - chat.center(chatModal); - } + function loadAndCenter(chatModal) { + chat.load(chatModal.attr('UUID')); + chat.center(chatModal); + } + } else { + app.alertError(err.message); + } + }); }); }; diff --git a/public/src/client/chats.js b/public/src/client/chats.js index aa1af729b3..ea3d937ffa 100644 --- a/public/src/client/chats.js +++ b/public/src/client/chats.js @@ -201,10 +201,15 @@ define('forum/chats', ['string', 'sounds', 'forum/infinitescroll'], function(S, socket.emit('modules.chats.send', { touid:toUid, message:msg + }, function(err) { + if (err) { + return app.alertError(err.message); + } + + inputEl.val(''); + sounds.play('chat-outgoing'); + Chats.notifyTyping(toUid, false); }); - inputEl.val(''); - sounds.play('chat-outgoing'); - Chats.notifyTyping(toUid, false); } }; diff --git a/public/src/modules/chat.js b/public/src/modules/chat.js index 30c7e163e5..512ec5ea0a 100644 --- a/public/src/modules/chat.js +++ b/public/src/modules/chat.js @@ -353,5 +353,9 @@ define('chat', ['taskbar', 'string', 'sounds', 'forum/chats'], function(taskbar, taskbar.toggleNew(uuid, state); }; + module.canMessage = function(toUid, callback) { + socket.emit('modules.chats.canMessage', toUid, callback); + }; + return module; }); diff --git a/src/messaging.js b/src/messaging.js index e7ccbeabdc..2e1f2d7cd2 100644 --- a/src/messaging.js +++ b/src/messaging.js @@ -292,6 +292,34 @@ var db = require('./database'), }, 1000*60); // wait 60s before sending }; + Messaging.canMessage = function(fromUid, toUid, callback) { + async.waterfall([ + function(next) { + // Check if the sending user is an admin + user.isAdministrator(fromUid, function(err, isAdmin) { + next(err || isAdmin); + }); + }, + function(next) { + // Retrieve the recipient's user setting + user.getSettings(toUid, function(err, settings) { + next(err || !settings.restrictChat); + }); + }, + function(next) { + // Does toUid follow fromUid? + user.isFollowing(toUid, fromUid, next); + } + ], function(err, allowed) { + // Handle premature returns + if (err === true) { + return callback(undefined, true); + } + + callback.apply(this, arguments); + }); + } + function sendNotifications(fromuid, touid, messageObj, callback) { // todo #1798 -- this should check if the user is in room `chat_{uidA}_{uidB}` instead, see `Sockets.uidInRoom(uid, room);` if (!websockets.isUserOnline(touid)) { diff --git a/src/socket.io/modules.js b/src/socket.io/modules.js index 0c1871aac0..67f4dc9f12 100644 --- a/src/socket.io/modules.js +++ b/src/socket.io/modules.js @@ -146,29 +146,43 @@ SocketModules.chats.send = function(socket, data, callback) { return callback(new Error('[[error:user-banned]]')); } - Messaging.addMessage(socket.uid, touid, msg, function(err, message) { - if (err) { - return callback(err); + Messaging.canMessage(socket.uid, touid, function(err, allowed) { + if (allowed) { + Messaging.addMessage(socket.uid, touid, msg, function(err, message) { + if (err) { + return callback(err); + } + + Messaging.notifyUser(socket.uid, touid, message); + + // Recipient + SocketModules.chats.pushUnreadCount(touid); + server.in('uid_' + touid).emit('event:chats.receive', { + withUid: socket.uid, + message: message, + self: 0 + }); + + // Sender + SocketModules.chats.pushUnreadCount(socket.uid); + server.in('uid_' + socket.uid).emit('event:chats.receive', { + withUid: touid, + message: message, + self: 1 + }); + + callback(); + }); + } else { + callback(new Error('[[error:chat-restricted]]')) } + }) + }); +}; - Messaging.notifyUser(socket.uid, touid, message); - - // Recipient - SocketModules.chats.pushUnreadCount(touid); - server.in('uid_' + touid).emit('event:chats.receive', { - withUid: socket.uid, - message: message, - self: 0 - }); - - // Sender - SocketModules.chats.pushUnreadCount(socket.uid); - server.in('uid_' + socket.uid).emit('event:chats.receive', { - withUid: touid, - message: message, - self: 1 - }); - }); +SocketModules.chats.canMessage = function(socket, toUid, callback) { + Messaging.canMessage(socket.uid, toUid, function(err, allowed) { + callback(!allowed ? new Error('[[error:chat-restricted]]') : undefined); }); }; diff --git a/src/user/settings.js b/src/user/settings.js index 0107410b63..9f75c7f1f4 100644 --- a/src/user/settings.js +++ b/src/user/settings.js @@ -37,6 +37,7 @@ module.exports = function(User) { settings.followTopicsOnCreate = (settings.followTopicsOnCreate === null || settings.followTopicsOnCreate === undefined) ? true : parseInt(settings.followTopicsOnCreate, 10) === 1; settings.followTopicsOnReply = parseInt(settings.followTopicsOnReply, 10) === 1; settings.sendChatNotifications = parseInt(settings.sendChatNotifications, 10) === 1; + settings.restrictChat = parseInt(settings.restrictChat, 10) === 1; callback(null, settings); }); @@ -88,7 +89,8 @@ module.exports = function(User) { language: data.language || meta.config.defaultLang, followTopicsOnCreate: data.followTopicsOnCreate, followTopicsOnReply: data.followTopicsOnReply, - sendChatNotifications: data.sendChatNotifications + sendChatNotifications: data.sendChatNotifications, + restrictChat: data.restrictChat }, callback); };