mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 02:55:58 +01:00 
			
		
		
		
	closes #6311
This commit is contained in:
		| @@ -25,6 +25,7 @@ | |||||||
|         "body-parser": "^1.18.2", |         "body-parser": "^1.18.2", | ||||||
|         "bootstrap": "^3.3.7", |         "bootstrap": "^3.3.7", | ||||||
|         "chart.js": "^2.7.1", |         "chart.js": "^2.7.1", | ||||||
|  |         "clipboard": "1.7.1", | ||||||
|         "colors": "^1.1.2", |         "colors": "^1.1.2", | ||||||
|         "compression": "^1.7.1", |         "compression": "^1.7.1", | ||||||
|         "commander": "^2.12.2", |         "commander": "^2.12.2", | ||||||
|   | |||||||
| @@ -14,5 +14,6 @@ | |||||||
| 	"alerts.applied-success": "Blacklist Applied", | 	"alerts.applied-success": "Blacklist Applied", | ||||||
|  |  | ||||||
| 	"analytics.blacklist-hourly": "<strong>Figure 1</strong> – Blacklist hits per hour", | 	"analytics.blacklist-hourly": "<strong>Figure 1</strong> – Blacklist hits per hour", | ||||||
| 	"analytics.blacklist-daily": "<strong>Figure 2</strong> – Blacklist hits per day" | 	"analytics.blacklist-daily": "<strong>Figure 2</strong> – Blacklist hits per day", | ||||||
|  | 	"ip-banned": "IP banned" | ||||||
| } | } | ||||||
| @@ -33,6 +33,8 @@ | |||||||
| 	"locked": "Locked", | 	"locked": "Locked", | ||||||
| 	"pinned": "Pinned", | 	"pinned": "Pinned", | ||||||
| 	"moved": "Moved", | 	"moved": "Moved", | ||||||
|  | 	"copy-ip": "Copy IP", | ||||||
|  | 	"ban-ip": "Ban IP", | ||||||
|  |  | ||||||
| 	"bookmark_instructions" : "Click here to return to the last read post in this thread.", | 	"bookmark_instructions" : "Click here to return to the last read post in this thread.", | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,8 +8,7 @@ define('forum/topic/postTools', [ | |||||||
| 	'translator', | 	'translator', | ||||||
| 	'forum/topic/votes', | 	'forum/topic/votes', | ||||||
| 	'forum/topic/move-post', | 	'forum/topic/move-post', | ||||||
| 	'benchpress', | ], function (share, navigator, components, translator, votes, movePost) { | ||||||
| ], function (share, navigator, components, translator, votes, movePost, Benchpress) { |  | ||||||
| 	var PostTools = {}; | 	var PostTools = {}; | ||||||
|  |  | ||||||
| 	var staleReplyAnyway = false; | 	var staleReplyAnyway = false; | ||||||
| @@ -45,11 +44,12 @@ define('forum/topic/postTools', [ | |||||||
| 				} | 				} | ||||||
| 				data.posts.display_move_tools = data.posts.display_move_tools && index !== 0; | 				data.posts.display_move_tools = data.posts.display_move_tools && index !== 0; | ||||||
|  |  | ||||||
| 				Benchpress.parse('partials/topic/post-menu-list', data, function (html) { | 				app.parseAndTranslate('partials/topic/post-menu-list', data, function (html) { | ||||||
| 					translator.translate(html, function (html) { | 					dropdownMenu.html(html); | ||||||
| 						dropdownMenu.html(html); | 					require(['clipboard'], function (clipboard) { | ||||||
| 						$(window).trigger('action:post.tools.load'); | 						new clipboard('[data-clipboard-text]'); | ||||||
| 					}); | 					}); | ||||||
|  | 					$(window).trigger('action:post.tools.load'); | ||||||
| 				}); | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| @@ -192,6 +192,16 @@ define('forum/topic/postTools', [ | |||||||
| 			movePost.openMovePostModal($(this)); | 			movePost.openMovePostModal($(this)); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
|  | 		postContainer.on('click', '[component="post/ban-ip"]', function () { | ||||||
|  | 			var ip = $(this).attr('data-ip'); | ||||||
|  | 			socket.emit('blacklist.addRule', ip, function (err) { | ||||||
|  | 				if (err) { | ||||||
|  | 					return app.alertError(err.message); | ||||||
|  | 				} | ||||||
|  | 				app.alertSuccess('[[admin/manage/blacklist:ban-ip]]'); | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  |  | ||||||
| 		postContainer.on('click', '[component="post/chat"]', function () { | 		postContainer.on('click', '[component="post/chat"]', function () { | ||||||
| 			openChat($(this)); | 			openChat($(this)); | ||||||
| 		}); | 		}); | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ var analytics = require('../../analytics'); | |||||||
| var blacklistController = module.exports; | var blacklistController = module.exports; | ||||||
|  |  | ||||||
| blacklistController.get = function (req, res, next) { | blacklistController.get = function (req, res, next) { | ||||||
| 	// Analytics.getBlacklistAnalytics |  | ||||||
| 	async.parallel({ | 	async.parallel({ | ||||||
| 		rules: async.apply(meta.blacklist.get), | 		rules: async.apply(meta.blacklist.get), | ||||||
| 		analytics: async.apply(analytics.getBlacklistAnalytics), | 		analytics: async.apply(analytics.getBlacklistAnalytics), | ||||||
|   | |||||||
| @@ -9,9 +9,8 @@ var pubsub = require('../pubsub'); | |||||||
| var plugins = require('../plugins'); | var plugins = require('../plugins'); | ||||||
| var analytics = require('../analytics'); | var analytics = require('../analytics'); | ||||||
|  |  | ||||||
| var Blacklist = { | var Blacklist = module.exports; | ||||||
| 	_rules: [], | Blacklist._rules = []; | ||||||
| }; |  | ||||||
|  |  | ||||||
| Blacklist.load = function (callback) { | Blacklist.load = function (callback) { | ||||||
| 	callback = callback || function () {}; | 	callback = callback || function () {}; | ||||||
| @@ -182,4 +181,22 @@ Blacklist.validate = function (rules, callback) { | |||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| module.exports = Blacklist; | Blacklist.addRule = function (rule, callback) { | ||||||
|  | 	var valid; | ||||||
|  | 	async.waterfall([ | ||||||
|  | 		function (next) { | ||||||
|  | 			Blacklist.validate(rule, next); | ||||||
|  | 		}, | ||||||
|  | 		function (result, next) { | ||||||
|  | 			valid = result.valid; | ||||||
|  | 			if (!valid.length) { | ||||||
|  | 				return next(new Error('[[error:invalid-rule]]')); | ||||||
|  | 			} | ||||||
|  | 			Blacklist.get(next); | ||||||
|  | 		}, | ||||||
|  | 		function (rules, next) { | ||||||
|  | 			rules = rules + '\n' + valid[0]; | ||||||
|  | 			Blacklist.save(rules, next); | ||||||
|  | 		}, | ||||||
|  | 	], callback); | ||||||
|  | }; | ||||||
|   | |||||||
| @@ -98,6 +98,7 @@ JS.scripts = { | |||||||
| 		'jqueryui.js': 'public/vendor/jquery/js/jquery-ui.js', | 		'jqueryui.js': 'public/vendor/jquery/js/jquery-ui.js', | ||||||
| 		'zxcvbn.js': 'node_modules/zxcvbn/dist/zxcvbn.js', | 		'zxcvbn.js': 'node_modules/zxcvbn/dist/zxcvbn.js', | ||||||
| 		ace: 'node_modules/ace-builds/src-min', | 		ace: 'node_modules/ace-builds/src-min', | ||||||
|  | 		'clipboard.js': 'node_modules/clipboard/dist/clipboard.min.js', | ||||||
| 	}, | 	}, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -82,23 +82,20 @@ module.exports = function (Plugins) { | |||||||
|  |  | ||||||
| 		var hookList = Plugins.loadedHooks[hook]; | 		var hookList = Plugins.loadedHooks[hook]; | ||||||
| 		var hookType = hook.split(':')[0]; | 		var hookType = hook.split(':')[0]; | ||||||
| 		try { | 		switch (hookType) { | ||||||
| 			switch (hookType) { | 		case 'filter': | ||||||
| 			case 'filter': | 			fireFilterHook(hook, hookList, params, callback); | ||||||
| 				fireFilterHook(hook, hookList, params, callback); | 			break; | ||||||
| 				break; | 		case 'action': | ||||||
| 			case 'action': | 			fireActionHook(hook, hookList, params, callback); | ||||||
| 				fireActionHook(hook, hookList, params, callback); | 			break; | ||||||
| 				break; | 		case 'static': | ||||||
| 			case 'static': | 			fireStaticHook(hook, hookList, params, callback); | ||||||
| 				fireStaticHook(hook, hookList, params, callback); | 			break; | ||||||
| 				break; | 		default: | ||||||
| 			default: | 			winston.warn('[plugins] Unknown hookType: ' + hookType + ', hook : ' + hook); | ||||||
| 				winston.warn('[plugins] Unknown hookType: ' + hookType + ', hook : ' + hook); | 			callback(); | ||||||
| 				break; | 			break; | ||||||
| 			} |  | ||||||
| 		} catch (err) { |  | ||||||
| 			callback(err); |  | ||||||
| 		} | 		} | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,3 +26,18 @@ SocketBlacklist.save = function (socket, rules, callback) { | |||||||
| 		}, | 		}, | ||||||
| 	], callback); | 	], callback); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | SocketBlacklist.addRule = function (socket, rule, callback) { | ||||||
|  | 	async.waterfall([ | ||||||
|  | 		function (next) { | ||||||
|  | 			user.isAdminOrGlobalMod(socket.uid, next); | ||||||
|  | 		}, | ||||||
|  | 		function (isAdminOrGlobalMod, next) { | ||||||
|  | 			if (!isAdminOrGlobalMod) { | ||||||
|  | 				return callback(new Error('[[error:no-privileges]]')); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			meta.blacklist.addRule(rule, next); | ||||||
|  | 		}, | ||||||
|  | 	], callback); | ||||||
|  | }; | ||||||
|   | |||||||
| @@ -10,6 +10,8 @@ var socketTopics = require('../topics'); | |||||||
| var privileges = require('../../privileges'); | var privileges = require('../../privileges'); | ||||||
| var plugins = require('../../plugins'); | var plugins = require('../../plugins'); | ||||||
| var social = require('../../social'); | var social = require('../../social'); | ||||||
|  | var user = require('../../user'); | ||||||
|  |  | ||||||
|  |  | ||||||
| module.exports = function (SocketPosts) { | module.exports = function (SocketPosts) { | ||||||
| 	SocketPosts.loadPostTools = function (socket, data, callback) { | 	SocketPosts.loadPostTools = function (socket, data, callback) { | ||||||
| @@ -20,10 +22,16 @@ module.exports = function (SocketPosts) { | |||||||
| 			function (next) { | 			function (next) { | ||||||
| 				async.parallel({ | 				async.parallel({ | ||||||
| 					posts: function (next) { | 					posts: function (next) { | ||||||
| 						posts.getPostFields(data.pid, ['deleted', 'bookmarks', 'uid'], next); | 						posts.getPostFields(data.pid, ['deleted', 'bookmarks', 'uid', 'ip'], next); | ||||||
| 					}, | 					}, | ||||||
| 					isAdminOrMod: function (next) { | 					isAdmin: function (next) { | ||||||
| 						privileges.categories.isAdminOrMod(data.cid, socket.uid, next); | 						user.isAdministrator(socket.uid, next); | ||||||
|  | 					}, | ||||||
|  | 					isGlobalMod: function (next) { | ||||||
|  | 						user.isGlobalModerator(socket.uid, next); | ||||||
|  | 					}, | ||||||
|  | 					isModerator: function (next) { | ||||||
|  | 						user.isModerator(socket.uid, data.cid, next); | ||||||
| 					}, | 					}, | ||||||
| 					canEdit: function (next) { | 					canEdit: function (next) { | ||||||
| 						privileges.posts.canEdit(data.pid, socket.uid, next); | 						privileges.posts.canEdit(data.pid, socket.uid, next); | ||||||
| @@ -54,7 +62,12 @@ module.exports = function (SocketPosts) { | |||||||
| 				results.posts.display_delete_tools = results.canDelete.flag; | 				results.posts.display_delete_tools = results.canDelete.flag; | ||||||
| 				results.posts.display_flag_tools = socket.uid && !results.posts.selfPost && results.canFlag.flag; | 				results.posts.display_flag_tools = socket.uid && !results.posts.selfPost && results.canFlag.flag; | ||||||
| 				results.posts.display_moderator_tools = results.posts.display_edit_tools || results.posts.display_delete_tools; | 				results.posts.display_moderator_tools = results.posts.display_edit_tools || results.posts.display_delete_tools; | ||||||
| 				results.posts.display_move_tools = results.isAdminOrMod; | 				results.posts.display_move_tools = results.isAdmin || results.isModerator; | ||||||
|  | 				results.posts.display_ip_ban = (results.isAdmin || results.isGlobalMod) && !results.posts.selfPost; | ||||||
|  |  | ||||||
|  | 				if (!results.isAdmin && !results.isGlobalMod && !results.isModerator) { | ||||||
|  | 					results.posts.ip = undefined; | ||||||
|  | 				} | ||||||
| 				next(null, results); | 				next(null, results); | ||||||
| 			}, | 			}, | ||||||
| 		], callback); | 		], callback); | ||||||
|   | |||||||
| @@ -70,22 +70,6 @@ describe('Plugins', function () { | |||||||
| 		}); | 		}); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should not crash if there is an exception in a hook', function (done) { |  | ||||||
| 		function filterMethod(data, callback) { |  | ||||||
| 			var crash; |  | ||||||
| 			crash.a = 5; |  | ||||||
| 			callback(null, data); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		plugins.registerHook('test-plugin-crash', { hook: 'filter:test.crashHook', method: filterMethod }); |  | ||||||
|  |  | ||||||
| 		plugins.fireHook('filter:test.crashHook', { foo: 1 }, function (err, data) { |  | ||||||
| 			assert(err); |  | ||||||
| 			assert.equal(err.message, 'Cannot set property \'a\' of undefined'); |  | ||||||
| 			done(); |  | ||||||
| 		}); |  | ||||||
| 	}); |  | ||||||
|  |  | ||||||
| 	it('should get plugin data from nbbpm', function (done) { | 	it('should get plugin data from nbbpm', function (done) { | ||||||
| 		plugins.get('nodebb-plugin-markdown', function (err, data) { | 		plugins.get('nodebb-plugin-markdown', function (err, data) { | ||||||
| 			assert.ifError(err); | 			assert.ifError(err); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user