diff --git a/src/meta/configs.js b/src/meta/configs.js index 0a8435e531..0ad2bf2545 100644 --- a/src/meta/configs.js +++ b/src/meta/configs.js @@ -1,7 +1,7 @@ 'use strict'; -var winston = require('winston'); +var async = require('async'); var nconf = require('nconf'); var db = require('../database'); @@ -16,17 +16,17 @@ module.exports = function (Meta) { Meta.configs.init = function (callback) { delete Meta.config; - Meta.configs.list(function (err, config) { - if (err) { - winston.error(err.stack); - return callback(err); - } - - config['cache-buster'] = utils.generateUUID(); + async.waterfall([ + function (next) { + Meta.configs.list(next); + }, + function (config, next) { + config['cache-buster'] = utils.generateUUID(); - Meta.config = config; - callback(); - }); + Meta.config = config; + setImmediate(next); + } + ], callback); }; Meta.configs.list = function (callback) { @@ -49,57 +49,50 @@ module.exports = function (Meta) { Meta.configs.set = function (field, value, callback) { callback = callback || function () {}; if (!field) { - return callback(new Error('invalid config field')); + return callback(new Error('[[error:invalid-data]]')); } - db.setObjectField('config', field, value, function (err) { - if (err) { - return callback(err); - } - var data = {}; - data[field] = value; - updateConfig(data); - - callback(); - }); + var data = {}; + data[field] = value; + Meta.configs.setMultiple(data, callback); }; - Meta.configs.setMultiple = function (data, callback) { - processConfig(data, function (err) { - if (err) { - return callback(err); - } - db.setObject('config', data, function (err) { - if (err) { - return callback(err); - } + Meta.configs.setMultiple = function (data, callback) { + async.waterfall([ + function (next) { + processConfig(data, next); + }, + function (next) { + db.setObject('config', data, next); + }, + function (next) { updateConfig(data); - callback(); - }); - }); + setImmediate(next); + } + ], callback); }; function processConfig(data, callback) { if (data.customCSS) { - saveRenderedCss(data, callback); - return; + return saveRenderedCss(data, callback); } - callback(); + setImmediate(callback); } function saveRenderedCss(data, callback) { var less = require('less'); - less.render(data.customCSS, { - compress: true - }, function (err, lessObject) { - if (err) { - winston.error('[less] Could not convert custom LESS to CSS! Please check your syntax.'); - return callback(null, ''); + async.waterfall([ + function (next) { + less.render(data.customCSS, { + compress: true + }, next); + }, + function (lessObject, next) { + data.renderedCustomCSS = lessObject.css; + setImmediate(next); } - data.renderedCustomCSS = lessObject.css; - callback(); - }); + ], callback); } function updateConfig(config) { @@ -107,39 +100,39 @@ module.exports = function (Meta) { } pubsub.on('config:update', function onConfigReceived(config) { - if (typeof config !== 'object' || !Meta.config) { - return; - } - - for(var field in config) { - if(config.hasOwnProperty(field)) { - Meta.config[field] = config[field]; + if (typeof config === 'object' && Meta.config) { + for (var field in config) { + if (config.hasOwnProperty(field)) { + Meta.config[field] = config[field]; + } } } }); Meta.configs.setOnEmpty = function (values, callback) { - db.getObject('config', function (err, data) { - if (err) { - return callback(err); - } - data = data || {}; - var empty = {}; - Object.keys(values).forEach(function (key) { - if (!data.hasOwnProperty(key)) { - empty[key] = values[key]; + async.waterfall([ + function (next) { + db.getObject('config', next); + }, + function (data, next) { + data = data || {}; + var empty = {}; + Object.keys(values).forEach(function (key) { + if (!data.hasOwnProperty(key)) { + empty[key] = values[key]; + } + }); + if (Object.keys(empty).length) { + db.setObject('config', empty, next); + } else { + setImmediate(next); } - }); - if (Object.keys(empty).length) { - db.setObject('config', empty, callback); - } else { - callback(); } - }); + ], callback); }; - Meta.configs.remove = function (field) { - db.deleteObjectField('config', field); + Meta.configs.remove = function (field, callback) { + db.deleteObjectField('config', field, callback); }; }; diff --git a/src/socket.io/admin.js b/src/socket.io/admin.js index 88b800a5ce..b16bafa296 100644 --- a/src/socket.io/admin.js +++ b/src/socket.io/admin.js @@ -37,16 +37,12 @@ var SocketAdmin = { }; SocketAdmin.before = function (socket, method, data, next) { - if (!socket.uid) { - return; - } - user.isAdministrator(socket.uid, function (err, isAdmin) { if (err || isAdmin) { return next(err); } - winston.warn('[socket.io] Call to admin method ( ' + method + ' ) blocked (accessed by uid ' + socket.uid + ')'); + next(new Error('[[error:no-privileges]]')); }); }; @@ -150,21 +146,9 @@ SocketAdmin.config.set = function (socket, data, callback) { if (!data) { return callback(new Error('[[error:invalid-data]]')); } - - meta.configs.set(data.key, data.value, function (err) { - if (err) { - return callback(err); - } - - callback(); - - plugins.fireHook('action:config.set', { - key: data.key, - value: data.value - }); - - logger.monitorConfig({io: index.server}, data); - }); + var _data = {}; + _data[data.key] = data.value; + SocketAdmin.config.setMultiple(socket, data, callback); }; SocketAdmin.config.setMultiple = function (socket, data, callback) { @@ -172,29 +156,29 @@ SocketAdmin.config.setMultiple = function (socket, data, callback) { return callback(new Error('[[error:invalid-data]]')); } - meta.configs.setMultiple(data, function (err) { - if(err) { - return callback(err); - } - - callback(); - var setting; - for(var field in data) { - if (data.hasOwnProperty(field)) { - setting = { - key: field, - value: data[field] - }; - plugins.fireHook('action:config.set', setting); - logger.monitorConfig({io: index.server}, setting); + async.waterfall([ + function (next) { + meta.configs.setMultiple(data, next); + }, + function (next) { + var setting; + for (var field in data) { + if (data.hasOwnProperty(field)) { + setting = { + key: field, + value: data[field] + }; + plugins.fireHook('action:config.set', setting); + logger.monitorConfig({io: index.server}, setting); + } } + setImmediate(next); } - }); + ], callback); }; SocketAdmin.config.remove = function (socket, key, callback) { - meta.configs.remove(key); - callback(); + meta.configs.remove(key, callback); }; SocketAdmin.settings.get = function (socket, data, callback) { diff --git a/test/meta.js b/test/meta.js index b0e076090e..6f27de6a8e 100644 --- a/test/meta.js +++ b/test/meta.js @@ -8,7 +8,7 @@ var meta = require('../src/meta'); var User = require('../src/user'); var Groups = require('../src/groups'); -describe('Messaging Library', function () { +describe('meta', function () { var fooUid; var bazUid; var herpUid; @@ -95,6 +95,92 @@ describe('Messaging Library', function () { }); + describe('config', function () { + var socketAdmin = require('../src/socket.io/admin'); + before(function (done) { + db.setObject('config', {minimumTagLength: 3, maximumTagLength: 15}, done); + }); + + it('should get config fields', function (done) { + meta.configs.getFields(['minimumTagLength', 'maximumTagLength'], function (err, data) { + assert.ifError(err); + assert.equal(data.minimumTagLength, 3); + assert.equal(data.maximumTagLength, 15); + done(); + }); + }); + + it('should fail if field is invalid', function (done) { + meta.configs.set('', 'someValue', function (err) { + assert.equal(err.message, '[[error:invalid-data]]'); + done(); + }); + }); + + it('should fail if data is invalid', function (done) { + socketAdmin.config.set({uid: fooUid}, null, function (err) { + assert.equal(err.message, '[[error:invalid-data]]'); + done(); + }); + }); + + it('should set config value', function (done) { + meta.configs.set('someField', 'someValue', function (err) { + assert.ifError(err); + meta.configs.getFields(['someField'], function (err, data) { + assert.ifError(err); + assert.equal(data.someField, 'someValue'); + done(); + }); + }); + }); + + it('should fail if data is invalid', function (done) { + socketAdmin.config.setMultiple({uid: fooUid}, null, function (err) { + assert.equal(err.message, '[[error:invalid-data]]'); + done(); + }); + }); + + it('should set multiple values', function (done ) { + socketAdmin.config.setMultiple({uid: fooUid}, { + someField1: 'someValue1', + someField2: 'someValue2', + customCSS: '.derp{color:#00ff00;}' + }, function (err) { + assert.ifError(err); + meta.configs.getFields(['someField1', 'someField2'], function (err, data) { + assert.ifError(err); + assert.equal(data.someField1, 'someValue1'); + assert.equal(data.someField2, 'someValue2'); + done(); + }); + }); + }); + + it('should not set config if not empty', function (done) { + meta.configs.setOnEmpty({someField1: 'foo'}, function (err) { + assert.ifError(err); + db.getObjectField('config', 'someField1', function (err, value) { + assert.ifError(err); + assert.equal(value, 'someValue1'); + done(); + }); + }); + }); + + it('should remove config field', function (done) { + socketAdmin.config.remove({uid: fooUid}, 'someField1', function (err) { + assert.ifError(err); + db.isObjectField('config', 'someField1', function (err, isObjectField) { + assert.ifError(err); + assert(!isObjectField); + done(); + }); + }); + }); + + }); diff --git a/test/socket.io.js b/test/socket.io.js index ddb136d3b0..d4eea47df4 100644 --- a/test/socket.io.js +++ b/test/socket.io.js @@ -372,6 +372,14 @@ describe('socket.io', function () { }); }); + it('should return error', function (done) { + var socketAdmin = require('../src/socket.io/admin'); + socketAdmin.before({uid: 10}, 'someMethod', {}, function (err) { + assert.equal(err.message, '[[error:no-privileges]]'); + done(); + }); + }); + after(function (done) { db.emptydb(done); });