mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 11:35:55 +01:00
closes #4367
This commit is contained in:
@@ -12,7 +12,6 @@
|
|||||||
@import "./manage/tags";
|
@import "./manage/tags";
|
||||||
@import "./manage/groups";
|
@import "./manage/groups";
|
||||||
@import "./manage/users";
|
@import "./manage/users";
|
||||||
@import "./manage/blacklist";
|
|
||||||
@import "./appearance/customise";
|
@import "./appearance/customise";
|
||||||
@import "./appearance/themes";
|
@import "./appearance/themes";
|
||||||
@import "./extend/plugins";
|
@import "./extend/plugins";
|
||||||
@@ -22,6 +21,7 @@
|
|||||||
@import "./settings";
|
@import "./settings";
|
||||||
|
|
||||||
@import "../flags";
|
@import "../flags";
|
||||||
|
@import "../blacklist";
|
||||||
|
|
||||||
@import "./modules/alerts";
|
@import "./modules/alerts";
|
||||||
@import "./modules/selectable";
|
@import "./modules/selectable";
|
||||||
@@ -239,5 +239,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
[class^="col-"] .mdl-switch__label {
|
[class^="col-"] .mdl-switch__label {
|
||||||
padding-right: 15px;
|
padding-right: 15px;
|
||||||
}
|
}
|
||||||
@@ -2,4 +2,5 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 450px;
|
height: 450px;
|
||||||
display: block;
|
display: block;
|
||||||
|
border: 1px solid #eee;
|
||||||
}
|
}
|
||||||
@@ -1,23 +1,22 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
/* globals $, app, socket, templates */
|
/* globals $, app, socket, templates, define, bootbox */
|
||||||
|
|
||||||
define('admin/manage/ip-blacklist', ['settings'], function(Settings) {
|
define('admin/manage/ip-blacklist', [], function() {
|
||||||
|
|
||||||
var Blacklist = {};
|
var Blacklist = {};
|
||||||
|
|
||||||
Blacklist.init = function() {
|
Blacklist.init = function() {
|
||||||
var blacklist = ace.edit("blacklist-rules");
|
var blacklist = $('#blacklist-rules');
|
||||||
|
|
||||||
blacklist.on('change', function(e) {
|
blacklist.on('keyup', function() {
|
||||||
$('#blacklist-rules-holder').val(blacklist.getValue());
|
$('#blacklist-rules-holder').val(blacklist.val());
|
||||||
});
|
|
||||||
|
|
||||||
Settings.load('blacklist', $('.blacklist-settings'), function(err, settings) {
|
|
||||||
blacklist.setValue(settings.rules);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$('[data-action="apply"]').on('click', function() {
|
$('[data-action="apply"]').on('click', function() {
|
||||||
Settings.save('blacklist', $('.blacklist-settings'), function() {
|
socket.emit('blacklist.save', blacklist.val(), function(err) {
|
||||||
|
if (err) {
|
||||||
|
return app.alertError(err.message);
|
||||||
|
}
|
||||||
app.alert({
|
app.alert({
|
||||||
type: 'success',
|
type: 'success',
|
||||||
alert_id: 'blacklist-saved',
|
alert_id: 'blacklist-saved',
|
||||||
@@ -27,8 +26,8 @@ define('admin/manage/ip-blacklist', ['settings'], function(Settings) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$('[data-action="test"]').on('click', function() {
|
$('[data-action="test"]').on('click', function() {
|
||||||
socket.emit('admin.blacklist.validate', {
|
socket.emit('blacklist.validate', {
|
||||||
rules: blacklist.getValue()
|
rules: blacklist.val()
|
||||||
}, function(err, data) {
|
}, function(err, data) {
|
||||||
templates.parse('admin/partials/blacklist-validate', data, function(html) {
|
templates.parse('admin/partials/blacklist-validate', data, function(html) {
|
||||||
bootbox.alert(html);
|
bootbox.alert(html);
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var meta = require('../../meta');
|
||||||
|
|
||||||
var blacklistController = {};
|
var blacklistController = {};
|
||||||
|
|
||||||
blacklistController.get = function(req, res, next) {
|
blacklistController.get = function(req, res, next) {
|
||||||
res.render('admin/manage/ip-blacklist', {});
|
meta.blacklist.get(function(err, rules) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
res.render('admin/manage/ip-blacklist', {rules: rules});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = blacklistController;
|
module.exports = blacklistController;
|
||||||
|
|||||||
29
src/controllers/globalmods.js
Normal file
29
src/controllers/globalmods.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
var user = require('../user');
|
||||||
|
var adminFlagsController = require('./admin/flags');
|
||||||
|
var adminBlacklistController = require('./admin/blacklist');
|
||||||
|
|
||||||
|
var globalModsController = {};
|
||||||
|
|
||||||
|
globalModsController.flagged = function(req, res, next) {
|
||||||
|
user.isAdminOrGlobalMod(req.uid, function(err, isAdminOrGlobalMod) {
|
||||||
|
if (err || !isAdminOrGlobalMod) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
adminFlagsController.get(req, res, next);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
globalModsController.ipBlacklist = function(req, res, next) {
|
||||||
|
user.isAdminOrGlobalMod(req.uid, function(err, isAdminOrGlobalMod) {
|
||||||
|
if (err || !isAdminOrGlobalMod) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
adminBlacklistController.get(req, res, next);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = globalModsController;
|
||||||
@@ -12,7 +12,6 @@ var helpers = require('./helpers');
|
|||||||
|
|
||||||
var Controllers = {
|
var Controllers = {
|
||||||
topics: require('./topics'),
|
topics: require('./topics'),
|
||||||
posts: require('./posts'),
|
|
||||||
categories: require('./categories'),
|
categories: require('./categories'),
|
||||||
category: require('./category'),
|
category: require('./category'),
|
||||||
unread: require('./unread'),
|
unread: require('./unread'),
|
||||||
@@ -25,7 +24,8 @@ var Controllers = {
|
|||||||
accounts: require('./accounts'),
|
accounts: require('./accounts'),
|
||||||
authentication: require('./authentication'),
|
authentication: require('./authentication'),
|
||||||
api: require('./api'),
|
api: require('./api'),
|
||||||
admin: require('./admin')
|
admin: require('./admin'),
|
||||||
|
globalMods: require('./globalmods')
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
var user = require('../user');
|
|
||||||
var adminFlagsController = require('./admin/flags');
|
|
||||||
|
|
||||||
var postsController = {};
|
|
||||||
|
|
||||||
postsController.flagged = function(req, res, next) {
|
|
||||||
user.isAdminOrGlobalMod(req.uid, function(err, isAdminOrGlobalMod) {
|
|
||||||
if (err || !isAdminOrGlobalMod) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
adminFlagsController.get(req, res, next);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = postsController;
|
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var ip = require('ip'),
|
var ip = require('ip');
|
||||||
winston = require('winston'),
|
var winston = require('winston');
|
||||||
async = require('async');
|
var async = require('async');
|
||||||
|
var db = require('../database');
|
||||||
var meta = module.parent.exports;
|
|
||||||
|
|
||||||
var Blacklist = {
|
var Blacklist = {
|
||||||
_rules: []
|
_rules: []
|
||||||
@@ -12,7 +11,7 @@ var Blacklist = {
|
|||||||
|
|
||||||
Blacklist.load = function(callback) {
|
Blacklist.load = function(callback) {
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
async.apply(meta.settings.getOne, 'blacklist', 'rules'),
|
async.apply(db.get, 'ip-blacklist-rules'),
|
||||||
async.apply(Blacklist.validate)
|
async.apply(Blacklist.validate)
|
||||||
], function(err, rules) {
|
], function(err, rules) {
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -34,6 +33,19 @@ Blacklist.load = function(callback) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Blacklist.save = function(rules, callback) {
|
||||||
|
db.set('ip-blacklist-rules', rules, function(err) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
Blacklist.load(callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Blacklist.get = function(callback) {
|
||||||
|
db.get('ip-blacklist-rules', callback);
|
||||||
|
};
|
||||||
|
|
||||||
Blacklist.test = function(clientIp, callback) {
|
Blacklist.test = function(clientIp, callback) {
|
||||||
if (
|
if (
|
||||||
Blacklist._rules.ipv4.indexOf(clientIp) === -1 // not explicitly specified in ipv4 list
|
Blacklist._rules.ipv4.indexOf(clientIp) === -1 // not explicitly specified in ipv4 list
|
||||||
@@ -60,11 +72,11 @@ Blacklist.test = function(clientIp, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Blacklist.validate = function(rules, callback) {
|
Blacklist.validate = function(rules, callback) {
|
||||||
var rules = (rules || '').split('\n'),
|
rules = (rules || '').split('\n');
|
||||||
ipv4 = [],
|
var ipv4 = [];
|
||||||
ipv6 = [],
|
var ipv6 = [];
|
||||||
cidr = [],
|
var cidr = [];
|
||||||
invalid = [];
|
var invalid = [];
|
||||||
|
|
||||||
var isCidrSubnet = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$/;
|
var isCidrSubnet = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$/;
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ module.exports = function(Meta) {
|
|||||||
source += '\n@import (inline) "..' + path.sep + '..' + path.sep + 'public/vendor/jquery/textcomplete/jquery.textcomplete.css";';
|
source += '\n@import (inline) "..' + path.sep + '..' + path.sep + 'public/vendor/jquery/textcomplete/jquery.textcomplete.css";';
|
||||||
source += '\n@import (inline) "..' + path.sep + '..' + path.sep + 'public/vendor/colorpicker/colorpicker.css";';
|
source += '\n@import (inline) "..' + path.sep + '..' + path.sep + 'public/vendor/colorpicker/colorpicker.css";';
|
||||||
source += '\n@import "..' + path.sep + '..' + path.sep + 'public/less/flags.less";';
|
source += '\n@import "..' + path.sep + '..' + path.sep + 'public/less/flags.less";';
|
||||||
|
source += '\n@import "..' + path.sep + '..' + path.sep + 'public/less/blacklist.less";';
|
||||||
source += '\n@import "..' + path.sep + '..' + path.sep + 'public/less/generics.less";';
|
source += '\n@import "..' + path.sep + '..' + path.sep + 'public/less/generics.less";';
|
||||||
source += '\n@import "..' + path.sep + '..' + path.sep + 'public/less/mixins.less";';
|
source += '\n@import "..' + path.sep + '..' + path.sep + 'public/less/mixins.less";';
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,9 @@ function mainRoutes(app, middleware, controllers) {
|
|||||||
setupPageRoute(app, '/tos', middleware, [], controllers.termsOfUse);
|
setupPageRoute(app, '/tos', middleware, [], controllers.termsOfUse);
|
||||||
}
|
}
|
||||||
|
|
||||||
function postRoutes(app, middleware, controllers) {
|
function globalModRoutes(app, middleware, controllers) {
|
||||||
setupPageRoute(app, '/posts/flags', middleware, [], controllers.posts.flagged);
|
setupPageRoute(app, '/ip-blacklist', middleware, [], controllers.globalMods.ipBlacklist);
|
||||||
|
setupPageRoute(app, '/posts/flags', middleware, [], controllers.globalMods.flagged);
|
||||||
}
|
}
|
||||||
|
|
||||||
function topicRoutes(app, middleware, controllers) {
|
function topicRoutes(app, middleware, controllers) {
|
||||||
@@ -111,7 +112,7 @@ module.exports = function(app, middleware) {
|
|||||||
|
|
||||||
mainRoutes(router, middleware, controllers);
|
mainRoutes(router, middleware, controllers);
|
||||||
topicRoutes(router, middleware, controllers);
|
topicRoutes(router, middleware, controllers);
|
||||||
postRoutes(router, middleware, controllers);
|
globalModRoutes(router, middleware, controllers);
|
||||||
tagRoutes(router, middleware, controllers);
|
tagRoutes(router, middleware, controllers);
|
||||||
categoryRoutes(router, middleware, controllers);
|
categoryRoutes(router, middleware, controllers);
|
||||||
accountRoutes(router, middleware, controllers);
|
accountRoutes(router, middleware, controllers);
|
||||||
@@ -191,10 +192,8 @@ function handleErrors(app, middleware) {
|
|||||||
case 'EBADCSRFTOKEN':
|
case 'EBADCSRFTOKEN':
|
||||||
winston.error(req.path + '\n', err.message);
|
winston.error(req.path + '\n', err.message);
|
||||||
return res.sendStatus(403);
|
return res.sendStatus(403);
|
||||||
break;
|
|
||||||
case 'blacklisted-ip':
|
case 'blacklisted-ip':
|
||||||
return res.status(403).type('text/plain').send(err.message);
|
return res.status(403).type('text/plain').send(err.message);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parseInt(err.status, 10) === 302 && err.path) {
|
if (parseInt(err.status, 10) === 302 && err.path) {
|
||||||
|
|||||||
@@ -33,8 +33,7 @@ var async = require('async'),
|
|||||||
settings: {},
|
settings: {},
|
||||||
email: {},
|
email: {},
|
||||||
analytics: {},
|
analytics: {},
|
||||||
logs: {},
|
logs: {}
|
||||||
blacklist: {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SocketAdmin.before = function(socket, method, data, next) {
|
SocketAdmin.before = function(socket, method, data, next) {
|
||||||
@@ -274,8 +273,5 @@ SocketAdmin.deleteAllEvents = function(socket, data, callback) {
|
|||||||
events.deleteAll(callback);
|
events.deleteAll(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
SocketAdmin.blacklist.validate = function(socket, data, callback) {
|
|
||||||
meta.blacklist.validate(data.rules, callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = SocketAdmin;
|
module.exports = SocketAdmin;
|
||||||
|
|||||||
27
src/socket.io/blacklist.js
Normal file
27
src/socket.io/blacklist.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var async = require('async');
|
||||||
|
var winston = require('winston');
|
||||||
|
|
||||||
|
var user = require('../user');
|
||||||
|
var meta = require('../meta');
|
||||||
|
|
||||||
|
var SocketBlacklist = {};
|
||||||
|
|
||||||
|
SocketBlacklist.validate = function(socket, data, callback) {
|
||||||
|
meta.blacklist.validate(data.rules, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
SocketBlacklist.save = function(socket, rules, callback) {
|
||||||
|
user.isAdminOrGlobalMod(socket.uid, function(err, isAdminOrGlobalMod) {
|
||||||
|
if (err || !isAdminOrGlobalMod) {
|
||||||
|
return callback(err || new Error('[[error:no-privileges]]'));
|
||||||
|
}
|
||||||
|
|
||||||
|
meta.blacklist.save(rules, callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = SocketBlacklist;
|
||||||
@@ -121,7 +121,7 @@ function onMessage(socket, payload) {
|
|||||||
|
|
||||||
function requireModules() {
|
function requireModules() {
|
||||||
var modules = ['admin', 'categories', 'groups', 'meta', 'modules',
|
var modules = ['admin', 'categories', 'groups', 'meta', 'modules',
|
||||||
'notifications', 'plugins', 'posts', 'topics', 'user'
|
'notifications', 'plugins', 'posts', 'topics', 'user', 'blacklist'
|
||||||
];
|
];
|
||||||
|
|
||||||
modules.forEach(function(module) {
|
modules.forEach(function(module) {
|
||||||
|
|||||||
@@ -11,10 +11,7 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<div id="blacklist-rules"></div>
|
<textarea id="blacklist-rules">{rules}</textarea>
|
||||||
<form class="blacklist-settings">
|
|
||||||
<input type="hidden" id="blacklist-rules-holder" value="" name="rules" />
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
|
|||||||
Reference in New Issue
Block a user