From 15e9bbac92852d7a5ae76fbed395471b8d85a836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Thu, 15 Feb 2018 14:52:49 -0500 Subject: [PATCH] closes #6311 --- install/package.json | 1 + .../en-GB/admin/manage/ip-blacklist.json | 3 +- public/language/en-GB/topic.json | 2 ++ public/src/client/topic/postTools.js | 22 +++++++++---- src/controllers/admin/blacklist.js | 1 - src/meta/blacklist.js | 25 ++++++++++++--- src/meta/js.js | 1 + src/plugins/hooks.js | 31 +++++++++---------- src/socket.io/blacklist.js | 15 +++++++++ src/socket.io/posts/tools.js | 21 ++++++++++--- test/plugins.js | 16 ---------- 11 files changed, 89 insertions(+), 49 deletions(-) diff --git a/install/package.json b/install/package.json index ef5caf1c55..42f4dd4303 100644 --- a/install/package.json +++ b/install/package.json @@ -25,6 +25,7 @@ "body-parser": "^1.18.2", "bootstrap": "^3.3.7", "chart.js": "^2.7.1", + "clipboard": "1.7.1", "colors": "^1.1.2", "compression": "^1.7.1", "commander": "^2.12.2", diff --git a/public/language/en-GB/admin/manage/ip-blacklist.json b/public/language/en-GB/admin/manage/ip-blacklist.json index cd79294266..588fbd62b6 100644 --- a/public/language/en-GB/admin/manage/ip-blacklist.json +++ b/public/language/en-GB/admin/manage/ip-blacklist.json @@ -14,5 +14,6 @@ "alerts.applied-success": "Blacklist Applied", "analytics.blacklist-hourly": "Figure 1 – Blacklist hits per hour", - "analytics.blacklist-daily": "Figure 2 – Blacklist hits per day" + "analytics.blacklist-daily": "Figure 2 – Blacklist hits per day", + "ip-banned": "IP banned" } \ No newline at end of file diff --git a/public/language/en-GB/topic.json b/public/language/en-GB/topic.json index a4892868b3..e084a9f24f 100644 --- a/public/language/en-GB/topic.json +++ b/public/language/en-GB/topic.json @@ -33,6 +33,8 @@ "locked": "Locked", "pinned": "Pinned", "moved": "Moved", + "copy-ip": "Copy IP", + "ban-ip": "Ban IP", "bookmark_instructions" : "Click here to return to the last read post in this thread.", diff --git a/public/src/client/topic/postTools.js b/public/src/client/topic/postTools.js index 934a3942b7..9cbfdbb366 100644 --- a/public/src/client/topic/postTools.js +++ b/public/src/client/topic/postTools.js @@ -8,8 +8,7 @@ define('forum/topic/postTools', [ 'translator', 'forum/topic/votes', 'forum/topic/move-post', - 'benchpress', -], function (share, navigator, components, translator, votes, movePost, Benchpress) { +], function (share, navigator, components, translator, votes, movePost) { var PostTools = {}; var staleReplyAnyway = false; @@ -45,11 +44,12 @@ define('forum/topic/postTools', [ } data.posts.display_move_tools = data.posts.display_move_tools && index !== 0; - Benchpress.parse('partials/topic/post-menu-list', data, function (html) { - translator.translate(html, function (html) { - dropdownMenu.html(html); - $(window).trigger('action:post.tools.load'); + app.parseAndTranslate('partials/topic/post-menu-list', data, function (html) { + dropdownMenu.html(html); + require(['clipboard'], function (clipboard) { + new clipboard('[data-clipboard-text]'); }); + $(window).trigger('action:post.tools.load'); }); }); }); @@ -192,6 +192,16 @@ define('forum/topic/postTools', [ 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 () { openChat($(this)); }); diff --git a/src/controllers/admin/blacklist.js b/src/controllers/admin/blacklist.js index a5f8136463..23d66d7c8a 100644 --- a/src/controllers/admin/blacklist.js +++ b/src/controllers/admin/blacklist.js @@ -7,7 +7,6 @@ var analytics = require('../../analytics'); var blacklistController = module.exports; blacklistController.get = function (req, res, next) { - // Analytics.getBlacklistAnalytics async.parallel({ rules: async.apply(meta.blacklist.get), analytics: async.apply(analytics.getBlacklistAnalytics), diff --git a/src/meta/blacklist.js b/src/meta/blacklist.js index 2b2f897284..c441c71b95 100644 --- a/src/meta/blacklist.js +++ b/src/meta/blacklist.js @@ -9,9 +9,8 @@ var pubsub = require('../pubsub'); var plugins = require('../plugins'); var analytics = require('../analytics'); -var Blacklist = { - _rules: [], -}; +var Blacklist = module.exports; +Blacklist._rules = []; Blacklist.load = function (callback) { 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); +}; diff --git a/src/meta/js.js b/src/meta/js.js index fb3d12f683..a6dc73331e 100644 --- a/src/meta/js.js +++ b/src/meta/js.js @@ -98,6 +98,7 @@ JS.scripts = { 'jqueryui.js': 'public/vendor/jquery/js/jquery-ui.js', 'zxcvbn.js': 'node_modules/zxcvbn/dist/zxcvbn.js', ace: 'node_modules/ace-builds/src-min', + 'clipboard.js': 'node_modules/clipboard/dist/clipboard.min.js', }, }; diff --git a/src/plugins/hooks.js b/src/plugins/hooks.js index 020ea4e024..c555424377 100644 --- a/src/plugins/hooks.js +++ b/src/plugins/hooks.js @@ -82,23 +82,20 @@ module.exports = function (Plugins) { var hookList = Plugins.loadedHooks[hook]; var hookType = hook.split(':')[0]; - try { - switch (hookType) { - case 'filter': - fireFilterHook(hook, hookList, params, callback); - break; - case 'action': - fireActionHook(hook, hookList, params, callback); - break; - case 'static': - fireStaticHook(hook, hookList, params, callback); - break; - default: - winston.warn('[plugins] Unknown hookType: ' + hookType + ', hook : ' + hook); - break; - } - } catch (err) { - callback(err); + switch (hookType) { + case 'filter': + fireFilterHook(hook, hookList, params, callback); + break; + case 'action': + fireActionHook(hook, hookList, params, callback); + break; + case 'static': + fireStaticHook(hook, hookList, params, callback); + break; + default: + winston.warn('[plugins] Unknown hookType: ' + hookType + ', hook : ' + hook); + callback(); + break; } }; diff --git a/src/socket.io/blacklist.js b/src/socket.io/blacklist.js index 1435d20737..d4f1481508 100644 --- a/src/socket.io/blacklist.js +++ b/src/socket.io/blacklist.js @@ -26,3 +26,18 @@ SocketBlacklist.save = function (socket, rules, 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); +}; diff --git a/src/socket.io/posts/tools.js b/src/socket.io/posts/tools.js index a9bbc6137b..a61e50ec6c 100644 --- a/src/socket.io/posts/tools.js +++ b/src/socket.io/posts/tools.js @@ -10,6 +10,8 @@ var socketTopics = require('../topics'); var privileges = require('../../privileges'); var plugins = require('../../plugins'); var social = require('../../social'); +var user = require('../../user'); + module.exports = function (SocketPosts) { SocketPosts.loadPostTools = function (socket, data, callback) { @@ -20,10 +22,16 @@ module.exports = function (SocketPosts) { function (next) { async.parallel({ posts: function (next) { - posts.getPostFields(data.pid, ['deleted', 'bookmarks', 'uid'], next); + posts.getPostFields(data.pid, ['deleted', 'bookmarks', 'uid', 'ip'], next); + }, + isAdmin: function (next) { + user.isAdministrator(socket.uid, next); + }, + isGlobalMod: function (next) { + user.isGlobalModerator(socket.uid, next); }, - isAdminOrMod: function (next) { - privileges.categories.isAdminOrMod(data.cid, socket.uid, next); + isModerator: function (next) { + user.isModerator(socket.uid, data.cid, next); }, canEdit: function (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_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_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); }, ], callback); diff --git a/test/plugins.js b/test/plugins.js index 47f3969a40..e948cbb160 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -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) { plugins.get('nodebb-plugin-markdown', function (err, data) { assert.ifError(err);