mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 19:15:58 +01:00 
			
		
		
		
	closes #5078
This commit is contained in:
		| @@ -101,7 +101,9 @@ define('forum/chats', [ | ||||
| 				if (err) { | ||||
| 					return app.alertError(err.message); | ||||
| 				} | ||||
|  | ||||
| 				if (!data) { | ||||
| 					return; | ||||
| 				} | ||||
| 				messages.parseMessage(data, function(html) { | ||||
| 					var currentScrollTop = el.scrollTop(); | ||||
| 					var previousHeight = el[0].scrollHeight; | ||||
| @@ -309,7 +311,9 @@ define('forum/chats', [ | ||||
| 			if (err) { | ||||
| 				return app.alertError(err.message); | ||||
| 			} | ||||
|  | ||||
| 			if (!messageData) { | ||||
| 				return; | ||||
| 			} | ||||
| 			chatContentEl.find('[component="chat/message"]').remove(); | ||||
|  | ||||
| 			messages.appendChatMessage(chatContentEl, messageData); | ||||
|   | ||||
| @@ -30,10 +30,13 @@ chatsController.get = function(req, res, callback) { | ||||
| 			if (!uid) { | ||||
| 				return callback(); | ||||
| 			} | ||||
| 			messaging.getRecentChats(uid, 0, 19, next); | ||||
| 			messaging.getRecentChats(req.uid, uid, 0, 19, next); | ||||
| 		}, | ||||
| 		function(_recentChats, next) { | ||||
| 			recentChats = _recentChats; | ||||
| 			if (!recentChats) { | ||||
| 				return callback(); | ||||
| 			} | ||||
| 			if (!req.params.roomid) { | ||||
| 				return res.render('chats', { | ||||
| 					rooms: recentChats.rooms, | ||||
| @@ -48,12 +51,13 @@ chatsController.get = function(req, res, callback) { | ||||
| 			messaging.isUserInRoom(req.uid, req.params.roomid, next); | ||||
| 		}, | ||||
| 		function(inRoom, next) { | ||||
| 			if (!inRoom && parseInt(req.uid, 10) === parseInt(uid, 10)) { | ||||
| 			if (!inRoom) { | ||||
| 				return callback(); | ||||
| 			} | ||||
| 			async.parallel({ | ||||
| 				users: async.apply(messaging.getUsersInRoom, req.params.roomid, 0, -1), | ||||
| 				messages: async.apply(messaging.getMessages, { | ||||
| 					callerUid: req.uid, | ||||
| 					uid: uid, | ||||
| 					roomId: req.params.roomid, | ||||
| 					since: 'recent', | ||||
|   | ||||
							
								
								
									
										108
									
								
								src/messaging.js
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								src/messaging.js
									
									
									
									
									
								
							| @@ -1,18 +1,17 @@ | ||||
| 'use strict'; | ||||
|  | ||||
|  | ||||
| var async = require('async'), | ||||
| 	winston = require('winston'), | ||||
| 	S = require('string'), | ||||
| var async = require('async'); | ||||
| var winston = require('winston'); | ||||
| var S = require('string'); | ||||
|  | ||||
|  | ||||
| 	db = require('./database'), | ||||
| 	user = require('./user'), | ||||
| 	plugins = require('./plugins'), | ||||
| 	meta = require('./meta'), | ||||
| 	utils = require('../public/src/utils'), | ||||
| 	notifications = require('./notifications'), | ||||
| 	userNotifications = require('./user/notifications'); | ||||
| var db = require('./database'); | ||||
| var user = require('./user'); | ||||
| var plugins = require('./plugins'); | ||||
| var meta = require('./meta'); | ||||
| var utils = require('../public/src/utils'); | ||||
| var notifications = require('./notifications'); | ||||
| var userNotifications = require('./user/notifications'); | ||||
|  | ||||
| (function(Messaging) { | ||||
|  | ||||
| @@ -63,34 +62,37 @@ var async = require('async'), | ||||
| 			count = 50; | ||||
| 			min = 0; | ||||
| 		} | ||||
|  | ||||
| 		db.getSortedSetRevRangeByScore('uid:' + uid + ':chat:room:' + roomId + ':mids', start, count, '+inf', min, function(err, mids) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 		var indices = {}; | ||||
| 		async.waterfall([ | ||||
| 			function(next) { | ||||
| 				canGetMessages(params.callerUid, params.uid, next); | ||||
| 			}, | ||||
| 			function(canGet, next) { | ||||
| 				if (!canGet) { | ||||
| 					return callback(null, null); | ||||
| 				} | ||||
|  | ||||
| 				db.getSortedSetRevRangeByScore('uid:' + uid + ':chat:room:' + roomId + ':mids', start, count, '+inf', min, next); | ||||
| 			}, | ||||
| 			function(mids, next) { | ||||
| 				if (!Array.isArray(mids) || !mids.length) { | ||||
| 					return callback(null, []); | ||||
| 				} | ||||
| 			var indices = {}; | ||||
|  | ||||
| 				mids.forEach(function(mid, index) { | ||||
| 					indices[mid] = start + index; | ||||
| 				}); | ||||
|  | ||||
| 				mids.reverse(); | ||||
|  | ||||
| 			Messaging.getMessagesData(mids, uid, roomId, isNew, function(err, messageData) { | ||||
| 				if (err) { | ||||
| 					return callback(err); | ||||
| 				} | ||||
|  | ||||
| 				for(var i=0; i<messageData.length; i++) { | ||||
| 				 	messageData[i].index = indices[messageData[i].messageId.toString()]; | ||||
| 				} | ||||
|  | ||||
| 				callback(null, messageData); | ||||
| 			}); | ||||
| 				Messaging.getMessagesData(mids, uid, roomId, isNew, next); | ||||
| 			}, | ||||
| 			function(messageData, next) { | ||||
| 				messageData.forEach(function(messageData) { | ||||
| 					messageData.index = indices[messageData.messageId.toString()]; | ||||
| 				}); | ||||
| 				next(null, messageData); | ||||
| 			} | ||||
| 		], callback); | ||||
|  | ||||
| 		if (markRead) { | ||||
| 			notifications.markRead('chat_' + roomId + '_' + uid, uid, function(err) { | ||||
| @@ -103,6 +105,16 @@ var async = require('async'), | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	function canGetMessages(callerUid, uid, callback) { | ||||
| 		plugins.fireHook('filter:messaging.canGetMessages', { | ||||
| 			callerUid: callerUid, | ||||
| 			uid: uid, | ||||
| 			canGet: parseInt(callerUid, 10) === parseInt(uid, 10) | ||||
| 		}, function(err, data) { | ||||
| 			callback(err, data ? data.canGet : false); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	Messaging.getMessagesData = function(mids, uid, roomId, isNew, callback) { | ||||
|  | ||||
| 		var keys = mids.map(function(mid) { | ||||
| @@ -250,12 +262,18 @@ var async = require('async'), | ||||
| 	}; | ||||
|  | ||||
|  | ||||
| 	Messaging.getRecentChats = function(uid, start, stop, callback) { | ||||
| 		db.getSortedSetRevRange('uid:' + uid + ':chat:rooms', start, stop, function(err, roomIds) { | ||||
| 			if (err) { | ||||
| 				return callback(err); | ||||
| 	Messaging.getRecentChats = function(callerUid, uid, start, stop, callback) { | ||||
| 		async.waterfall([ | ||||
| 			function(next) { | ||||
| 				canGetRecentChats(callerUid, uid, next); | ||||
| 			}, | ||||
| 			function(canGet, next) { | ||||
| 				if (!canGet) { | ||||
| 					return callback(null, null); | ||||
| 				} | ||||
|  | ||||
| 				db.getSortedSetRevRange('uid:' + uid + ':chat:rooms', start, stop, next); | ||||
| 			}, | ||||
| 			function(roomIds, next) { | ||||
| 				async.parallel({ | ||||
| 					roomData: function(next) { | ||||
| 						Messaging.getRoomsData(roomIds, next); | ||||
| @@ -281,11 +299,9 @@ var async = require('async'), | ||||
| 							Messaging.getTeaser(uid, roomId, next); | ||||
| 						}, next); | ||||
| 					} | ||||
| 			}, function(err, results) { | ||||
| 				if (err) { | ||||
| 					return callback(err); | ||||
| 				} | ||||
|  | ||||
| 				}, next); | ||||
| 			}, | ||||
| 			function(results, next) { | ||||
| 				results.roomData.forEach(function(room, index) { | ||||
| 					room.users = results.users[index]; | ||||
| 					room.groupChat = room.hasOwnProperty('groupChat') ? room.groupChat : room.users.length > 2; | ||||
| @@ -307,11 +323,21 @@ var async = require('async'), | ||||
| 					}).join(', '); | ||||
| 				}); | ||||
|  | ||||
| 				callback(null, {rooms: results.roomData, nextStart: stop + 1}); | ||||
| 			}); | ||||
| 		}); | ||||
| 				next(null, {rooms: results.roomData, nextStart: stop + 1}); | ||||
| 			} | ||||
| 		], callback); | ||||
| 	}; | ||||
|  | ||||
| 	function canGetRecentChats(callerUid, uid, callback) { | ||||
| 		plugins.fireHook('filter:messaging.canGetRecentChats', { | ||||
| 			callerUid: callerUid, | ||||
| 			uid: uid, | ||||
| 			canGet: parseInt(callerUid, 10) === parseInt(uid, 10) | ||||
| 		}, function(err, data) { | ||||
| 			callback(err, data ? data.canGet : false); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	Messaging.getTeaser = function (uid, roomId, callback) { | ||||
| 		var teaser; | ||||
| 		async.waterfall([ | ||||
|   | ||||
| @@ -5,6 +5,7 @@ var validator = require('validator'); | ||||
|  | ||||
| var db = require('../database'); | ||||
| var user = require('../user'); | ||||
| var plugins = require('../plugins'); | ||||
|  | ||||
| module.exports = function(Messaging) { | ||||
|  | ||||
| @@ -74,7 +75,17 @@ module.exports = function(Messaging) { | ||||
| 	}; | ||||
|  | ||||
| 	Messaging.isUserInRoom = function(uid, roomId, callback) { | ||||
| 		db.isSortedSetMember('chat:room:' + roomId + ':uids', uid, callback); | ||||
| 		async.waterfall([ | ||||
| 			function(next) { | ||||
| 				db.isSortedSetMember('chat:room:' + roomId + ':uids', uid, next); | ||||
| 			}, | ||||
| 			function(inRoom, next) { | ||||
| 				plugins.fireHook('filter:messaging.isUserInRoom', {uid: uid, roomId: roomId, inRoom: inRoom}, next); | ||||
| 			}, | ||||
| 			function(data, next) { | ||||
| 				next(null, data.inRoom); | ||||
| 			} | ||||
| 		], callback); | ||||
| 	}; | ||||
|  | ||||
| 	Messaging.roomExists = function(roomId, callback) { | ||||
|   | ||||
| @@ -31,6 +31,6 @@ module.exports = function (app, middleware, controllers) { | ||||
| 	app.delete('/api/user/:userslug/session/:uuid', [middleware.requireUser], controllers.accounts.session.revoke); | ||||
|  | ||||
| 	setupPageRoute(app, '/notifications', middleware, [middleware.authenticate], controllers.accounts.notifications.get); | ||||
| 	setupPageRoute(app, '/user/:userslug/chats/:roomid?', middleware, accountMiddlewares, controllers.accounts.chats.get); | ||||
| 	setupPageRoute(app, '/user/:userslug/chats/:roomid?', middleware, middlewares, controllers.accounts.chats.get); | ||||
| 	setupPageRoute(app, '/chats/:roomid?', middleware, [], controllers.accounts.chats.redirectToChat); | ||||
| }; | ||||
|   | ||||
| @@ -55,7 +55,7 @@ SocketModules.chats.newRoom = function(socket, data, callback) { | ||||
| }; | ||||
|  | ||||
| SocketModules.chats.send = function(socket, data, callback) { | ||||
| 	if (!data || !data.roomId) { | ||||
| 	if (!data || !data.roomId || !socket.uid) { | ||||
| 		return callback(new Error('[[error:invalid-data]]')); | ||||
| 	} | ||||
|  | ||||
| @@ -106,13 +106,10 @@ SocketModules.chats.loadRoom = function(socket, data, callback) { | ||||
|  | ||||
| 	async.waterfall([ | ||||
| 		function (next) { | ||||
| 			async.parallel({ | ||||
| 				inRoom: async.apply(Messaging.isUserInRoom, socket.uid, data.roomId), | ||||
| 				isAdminOrGlobalMod: async.apply(user.isAdminOrGlobalMod, socket.uid) | ||||
| 			}, next); | ||||
| 			Messaging.isUserInRoom(socket.uid, data.roomId, next); | ||||
| 		}, | ||||
| 		function (results, next) { | ||||
| 			if (!results.isAdminOrGlobalMod && !results.inRoom) { | ||||
| 		function (inRoom, next) { | ||||
| 			if (!inRoom) { | ||||
| 				return next(new Error('[[error:not-allowed]]')); | ||||
| 			} | ||||
|  | ||||
| @@ -222,6 +219,9 @@ SocketModules.chats.canMessage = function(socket, roomId, callback) { | ||||
| }; | ||||
|  | ||||
| SocketModules.chats.markRead = function(socket, roomId, callback) { | ||||
| 	if (!socket.uid) { | ||||
| 		return callback(new Error('[[error:invalid-data]]')); | ||||
| 	} | ||||
| 	async.parallel({ | ||||
| 		usersInRoom: async.apply(Messaging.getUidsInRoom, roomId, 0, -1), | ||||
| 		markRead: async.apply(Messaging.markRead, socket.uid, roomId) | ||||
| @@ -283,21 +283,12 @@ SocketModules.chats.renameRoom = function(socket, data, callback) { | ||||
| }; | ||||
|  | ||||
| SocketModules.chats.getRecentChats = function(socket, data, callback) { | ||||
| 	if (!data || !utils.isNumber(data.after)) { | ||||
| 	if (!data || !utils.isNumber(data.after) || !utils.isNumber(data.uid)) { | ||||
| 		return callback(new Error('[[error:invalid-data]]')); | ||||
| 	} | ||||
| 	var start = parseInt(data.after, 10); | ||||
| 	var stop = start + 9; | ||||
| 	if (socket.uid === parseInt(data.uid, 10)) { | ||||
| 		return Messaging.getRecentChats(socket.uid, start, stop, callback); | ||||
| 	} | ||||
|  | ||||
| 	user.isAdminOrGlobalMod(socket.uid, function(err, isAdminOrGlobalMod) { | ||||
| 		if (err || !isAdminOrGlobalMod) { | ||||
| 			return callback(err || new Error('[[error:no-privileges]]')); | ||||
| 		} | ||||
| 		Messaging.getRecentChats(data.uid, start, stop, callback); | ||||
| 	}); | ||||
| 	Messaging.getRecentChats(socket.uid, data.uid, start, stop, callback); | ||||
| }; | ||||
|  | ||||
| SocketModules.chats.hasPrivateChat = function(socket, uid, callback) { | ||||
| @@ -313,6 +304,7 @@ SocketModules.chats.getMessages = function(socket, data, callback) { | ||||
| 	} | ||||
|  | ||||
| 	var params = { | ||||
| 		callerUid: socket.uid, | ||||
| 		uid: data.uid, | ||||
| 		roomId: data.roomId, | ||||
| 		start: parseInt(data.start, 10) || 0, | ||||
| @@ -328,15 +320,7 @@ SocketModules.chats.getMessages = function(socket, data, callback) { | ||||
| 		params.markRead = data.markRead; | ||||
| 	} | ||||
|  | ||||
| 	if (socket.uid === parseInt(data.uid, 10)) { | ||||
| 		return Messaging.getMessages(params, callback); | ||||
| 	} | ||||
| 	user.isAdminOrGlobalMod(socket.uid, function(err, isAdminOrGlobalMod) { | ||||
| 		if (err || !isAdminOrGlobalMod) { | ||||
| 			return callback(err || new Error('[[error:no-privileges]]')); | ||||
| 		} | ||||
| 	Messaging.getMessages(params, callback); | ||||
| 	}); | ||||
| }; | ||||
|  | ||||
| /* Sounds */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user