v1.18.x
Barış Soner Uşaklı 7 years ago
parent 19491b5210
commit a7267df404

@ -11,7 +11,6 @@
"maximumTagsPerTopic": 5, "maximumTagsPerTopic": 5,
"minimumTagLength": 3, "minimumTagLength": 3,
"maximumTagLength": 15, "maximumTagLength": 15,
"allowGuestSearching": 0,
"allowTopicsThumbnail": 0, "allowTopicsThumbnail": 0,
"registrationType": "normal", "registrationType": "normal",
"allowLocalLogin": 1, "allowLocalLogin": 1,

@ -75,9 +75,9 @@
"nodebb-plugin-spam-be-gone": "0.5.3", "nodebb-plugin-spam-be-gone": "0.5.3",
"nodebb-rewards-essentials": "0.0.11", "nodebb-rewards-essentials": "0.0.11",
"nodebb-theme-lavender": "5.0.4", "nodebb-theme-lavender": "5.0.4",
"nodebb-theme-persona": "9.0.6", "nodebb-theme-persona": "9.0.7",
"nodebb-theme-slick": "1.2.1", "nodebb-theme-slick": "1.2.2",
"nodebb-theme-vanilla": "10.0.6", "nodebb-theme-vanilla": "10.0.7",
"nodebb-widget-essentials": "4.0.4", "nodebb-widget-essentials": "4.0.4",
"nodemailer": "4.6.4", "nodemailer": "4.6.4",
"passport": "^0.4.0", "passport": "^0.4.0",

@ -1,8 +1,5 @@
{ {
"handles": "Guest Handles", "handles": "Guest Handles",
"handles.enabled": "Allow guest handles", "handles.enabled": "Allow guest handles",
"handles.enabled-help": "This option exposes a new field that allows guests to pick a name to associate with each post they make. If disabled, they will simply be called \"Guest\"", "handles.enabled-help": "This option exposes a new field that allows guests to pick a name to associate with each post they make. If disabled, they will simply be called \"Guest\""
"privileges": "Guest Privileges",
"privileges.can-search": "Allow guests to search without logging in",
"privileges.can-search-users": "Allow guests to search users without logging in"
} }

@ -521,7 +521,7 @@ app.cacheBuster = null;
} }
searchButton.on('click', function (e) { searchButton.on('click', function (e) {
if (!config.loggedIn && !config.allowGuestSearching) { if (!config.loggedIn && !app.user.privileges['search:content']) {
app.alert({ app.alert({
message: '[[error:search-requires-login]]', message: '[[error:search-requires-login]]',
timeout: 3000, timeout: 3000,

@ -20,7 +20,6 @@
generateCategoryBackground: generateCategoryBackground, generateCategoryBackground: generateCategoryBackground,
generateChildrenCategories: generateChildrenCategories, generateChildrenCategories: generateChildrenCategories,
generateTopicClass: generateTopicClass, generateTopicClass: generateTopicClass,
displayUserSearch: displayUserSearch,
membershipBtn: membershipBtn, membershipBtn: membershipBtn,
spawnPrivilegeStates: spawnPrivilegeStates, spawnPrivilegeStates: spawnPrivilegeStates,
localeToHTML: localeToHTML, localeToHTML: localeToHTML,
@ -159,10 +158,6 @@
return style.join(' '); return style.join(' ');
} }
function displayUserSearch(data, allowGuestUserSearching) {
return data.loggedIn || allowGuestUserSearching === 'true';
}
// Groups helpers // Groups helpers
function membershipBtn(groupObj) { function membershipBtn(groupObj) {
if (groupObj.isMember && groupObj.name !== 'administrators') { if (groupObj.isMember && groupObj.name !== 'administrators') {

@ -32,8 +32,6 @@ apiController.loadConfig = function (req, callback) {
config.minimumTagLength = meta.config.minimumTagLength || 3; config.minimumTagLength = meta.config.minimumTagLength || 3;
config.maximumTagLength = meta.config.maximumTagLength || 15; config.maximumTagLength = meta.config.maximumTagLength || 15;
config.useOutgoingLinksPage = parseInt(meta.config.useOutgoingLinksPage, 10) === 1; config.useOutgoingLinksPage = parseInt(meta.config.useOutgoingLinksPage, 10) === 1;
config.allowGuestSearching = parseInt(meta.config.allowGuestSearching, 10) === 1;
config.allowGuestUserSearching = parseInt(meta.config.allowGuestUserSearching, 10) === 1;
config.allowGuestHandles = parseInt(meta.config.allowGuestHandles, 10) === 1; config.allowGuestHandles = parseInt(meta.config.allowGuestHandles, 10) === 1;
config.allowFileUploads = parseInt(meta.config.allowFileUploads, 10) === 1; config.allowFileUploads = parseInt(meta.config.allowFileUploads, 10) === 1;
config.allowTopicsThumbnail = parseInt(meta.config.allowTopicsThumbnail, 10) === 1; config.allowTopicsThumbnail = parseInt(meta.config.allowTopicsThumbnail, 10) === 1;

@ -9,6 +9,7 @@ var plugins = require('../plugins');
var search = require('../search'); var search = require('../search');
var categories = require('../categories'); var categories = require('../categories');
var pagination = require('../pagination'); var pagination = require('../pagination');
var privileges = require('../privileges');
var helpers = require('./helpers'); var helpers = require('./helpers');
var searchController = module.exports; var searchController = module.exports;
@ -17,64 +18,68 @@ searchController.search = function (req, res, next) {
if (!plugins.hasListeners('filter:search.query')) { if (!plugins.hasListeners('filter:search.query')) {
return next(); return next();
} }
if (!req.loggedIn && parseInt(meta.config.allowGuestSearching, 10) !== 1) {
return helpers.notAllowed(req, res);
}
var page = Math.max(1, parseInt(req.query.page, 10)) || 1; var page = Math.max(1, parseInt(req.query.page, 10)) || 1;
if (req.query.categories && !Array.isArray(req.query.categories)) {
req.query.categories = [req.query.categories];
}
var data = { async.waterfall([
query: req.query.term, function (next) {
searchIn: req.query.in || 'posts', privileges.global.can('search:content', req.uid, next);
matchWords: req.query.matchWords || 'all', },
postedBy: req.query.by, function (allowed, next) {
categories: req.query.categories, if (!allowed) {
searchChildren: req.query.searchChildren, return helpers.notAllowed(req, res);
hasTags: req.query.hasTags, }
replies: req.query.replies,
repliesFilter: req.query.repliesFilter, if (req.query.categories && !Array.isArray(req.query.categories)) {
timeRange: req.query.timeRange, req.query.categories = [req.query.categories];
timeFilter: req.query.timeFilter, }
sortBy: req.query.sortBy || meta.config.searchDefaultSortBy || '',
sortDirection: req.query.sortDirection,
page: page,
uid: req.uid,
qs: req.query,
};
async.parallel({ var data = {
categories: async.apply(categories.buildForSelect, req.uid, 'read'), query: req.query.term,
search: async.apply(search.search, data), searchIn: req.query.in || 'posts',
}, function (err, results) { matchWords: req.query.matchWords || 'all',
if (err) { postedBy: req.query.by,
return next(err); categories: req.query.categories,
} searchChildren: req.query.searchChildren,
hasTags: req.query.hasTags,
replies: req.query.replies,
repliesFilter: req.query.repliesFilter,
timeRange: req.query.timeRange,
timeFilter: req.query.timeFilter,
sortBy: req.query.sortBy || meta.config.searchDefaultSortBy || '',
sortDirection: req.query.sortDirection,
page: page,
uid: req.uid,
qs: req.query,
};
results.categories = results.categories.filter(function (category) { async.parallel({
return category && !category.link; categories: async.apply(categories.buildForSelect, req.uid, 'read'),
}); search: async.apply(search.search, data),
}, next);
},
function (results) {
results.categories = results.categories.filter(function (category) {
return category && !category.link;
});
var categoriesData = [ var categoriesData = [
{ value: 'all', text: '[[unread:all_categories]]' }, { value: 'all', text: '[[unread:all_categories]]' },
{ value: 'watched', text: '[[category:watched-categories]]' }, { value: 'watched', text: '[[category:watched-categories]]' },
].concat(results.categories); ].concat(results.categories);
var searchData = results.search; var searchData = results.search;
searchData.categories = categoriesData; searchData.categories = categoriesData;
searchData.categoriesCount = Math.max(10, Math.min(20, categoriesData.length)); searchData.categoriesCount = Math.max(10, Math.min(20, categoriesData.length));
searchData.pagination = pagination.create(page, searchData.pageCount, req.query); searchData.pagination = pagination.create(page, searchData.pageCount, req.query);
searchData.showAsPosts = !req.query.showAs || req.query.showAs === 'posts'; searchData.showAsPosts = !req.query.showAs || req.query.showAs === 'posts';
searchData.showAsTopics = req.query.showAs === 'topics'; searchData.showAsTopics = req.query.showAs === 'topics';
searchData.title = '[[global:header.search]]'; searchData.title = '[[global:header.search]]';
searchData.breadcrumbs = helpers.buildBreadcrumbs([{ text: '[[global:search]]' }]); searchData.breadcrumbs = helpers.buildBreadcrumbs([{ text: '[[global:search]]' }]);
searchData.expandSearch = !req.query.term; searchData.expandSearch = !req.query.term;
searchData.searchDefaultSortBy = meta.config.searchDefaultSortBy || ''; searchData.searchDefaultSortBy = meta.config.searchDefaultSortBy || '';
searchData.search_query = validator.escape(String(req.query.term || '')); searchData.search_query = validator.escape(String(req.query.term || ''));
searchData.term = req.query.term; searchData.term = req.query.term;
res.render('search', searchData); res.render('search', searchData);
}); },
], next);
}; };

@ -5,6 +5,7 @@ var validator = require('validator');
var user = require('../user'); var user = require('../user');
var topics = require('../topics'); var topics = require('../topics');
var privileges = require('../privileges');
var pagination = require('../pagination'); var pagination = require('../pagination');
var helpers = require('./helpers'); var helpers = require('./helpers');
@ -71,12 +72,20 @@ tagsController.getTag = function (req, res, next) {
tagsController.getTags = function (req, res, next) { tagsController.getTags = function (req, res, next) {
async.waterfall([ async.waterfall([
function (next) { function (next) {
topics.getTags(0, 99, next); async.parallel({
canSearch: function (next) {
privileges.global.can('search:tags', req.uid, next);
},
tags: function (next) {
topics.getTags(0, 99, next);
},
}, next);
}, },
function (tags) { function (results) {
tags = tags.filter(Boolean); results.tags = results.tags.filter(Boolean);
var data = { var data = {
tags: tags, tags: results.tags,
displayTagSearch: results.canSearch,
nextStart: 100, nextStart: 100,
breadcrumbs: helpers.buildBreadcrumbs([{ text: '[[tags:tags]]' }]), breadcrumbs: helpers.buildBreadcrumbs([{ text: '[[tags:tags]]' }]),
title: '[[pages:tags]]', title: '[[pages:tags]]',

@ -4,8 +4,9 @@ var async = require('async');
var user = require('../user'); var user = require('../user');
var meta = require('../meta'); var meta = require('../meta');
var pagination = require('../pagination');
var db = require('../database'); var db = require('../database');
var pagination = require('../pagination');
var privileges = require('../privileges');
var helpers = require('./helpers'); var helpers = require('./helpers');
var usersController = module.exports; var usersController = module.exports;
@ -33,6 +34,12 @@ usersController.index = function (req, res, next) {
usersController.search = function (req, res, next) { usersController.search = function (req, res, next) {
async.waterfall([ async.waterfall([
function (next) { function (next) {
privileges.global.can('search:users', req.uid, next);
},
function (allowed, next) {
if (!allowed) {
return next(new Error('[[error:no-privileges]]'));
}
async.parallel({ async.parallel({
search: function (next) { search: function (next) {
user.search({ user.search({
@ -56,6 +63,7 @@ usersController.search = function (req, res, next) {
results.search.isAdminOrGlobalMod = results.isAdminOrGlobalMod; results.search.isAdminOrGlobalMod = results.isAdminOrGlobalMod;
results.search.pagination = pagination.create(req.query.page, results.search.pageCount, req.query); results.search.pagination = pagination.create(req.query.page, results.search.pageCount, req.query);
results.search['section_' + section] = true; results.search['section_' + section] = true;
results.displayUserSearch = true;
render(req, res, results.search, next); render(req, res, results.search, next);
}, },
], next); ], next);
@ -171,6 +179,9 @@ usersController.getUsers = function (set, uid, query, callback) {
isAdminOrGlobalMod: function (next) { isAdminOrGlobalMod: function (next) {
user.isAdminOrGlobalMod(uid, next); user.isAdminOrGlobalMod(uid, next);
}, },
canSearch: function (next) {
privileges.global.can('search:users', uid, next);
},
usersData: function (next) { usersData: function (next) {
usersController.getUsersAndCount(set, uid, start, stop, next); usersController.getUsersAndCount(set, uid, start, stop, next);
}, },
@ -185,6 +196,7 @@ usersController.getUsers = function (set, uid, query, callback) {
title: setToData[set].title || '[[pages:users/latest]]', title: setToData[set].title || '[[pages:users/latest]]',
breadcrumbs: helpers.buildBreadcrumbs(breadcrumbs), breadcrumbs: helpers.buildBreadcrumbs(breadcrumbs),
isAdminOrGlobalMod: results.isAdminOrGlobalMod, isAdminOrGlobalMod: results.isAdminOrGlobalMod,
displayUserSearch: results.canSearch,
}; };
userData['section_' + (query.section || 'joindate')] = true; userData['section_' + (query.section || 'joindate')] = true;
next(null, userData); next(null, userData);

@ -380,7 +380,8 @@ function createGlobalModeratorsGroup(next) {
function giveGlobalPrivileges(next) { function giveGlobalPrivileges(next) {
var privileges = require('./privileges'); var privileges = require('./privileges');
privileges.global.give(['chat', 'upload:post:image', 'signature'], 'registered-users', next); var defaultPrivileges = ['chat', 'upload:post:image', 'signature', 'search:content', 'search:users', 'search:tags'];
privileges.global.give(defaultPrivileges, 'registered-users', next);
} }
function createCategories(next) { function createCategories(next) {

@ -18,6 +18,9 @@ module.exports = function (privileges) {
{ name: 'Upload Files' }, { name: 'Upload Files' },
{ name: 'Signature' }, { name: 'Signature' },
{ name: 'Ban' }, { name: 'Ban' },
{ name: 'Search Content' },
{ name: 'Search Users' },
{ name: 'Search Tags' },
]; ];
privileges.global.userPrivilegeList = [ privileges.global.userPrivilegeList = [
@ -26,6 +29,9 @@ module.exports = function (privileges) {
'upload:post:file', 'upload:post:file',
'signature', 'signature',
'ban', 'ban',
'search:content',
'search:users',
'search:tags',
]; ];
privileges.global.groupPrivilegeList = privileges.global.userPrivilegeList.map(function (privilege) { privileges.global.groupPrivilegeList = privileges.global.userPrivilegeList.map(function (privilege) {
@ -81,6 +87,9 @@ module.exports = function (privileges) {
chat: privData.chat || isAdminOrMod, chat: privData.chat || isAdminOrMod,
'upload:post:image': privData['upload:post:image'] || isAdminOrMod, 'upload:post:image': privData['upload:post:image'] || isAdminOrMod,
'upload:post:file': privData['upload:post:file'] || isAdminOrMod, 'upload:post:file': privData['upload:post:file'] || isAdminOrMod,
'search:content': privData['search:content'] || isAdminOrMod,
'search:users': privData['search:users'] || isAdminOrMod,
'search:tags': privData['search:tags'] || isAdminOrMod,
}, next); }, next);
}, },
], callback); ], callback);

@ -3,6 +3,7 @@
var async = require('async'); var async = require('async');
var db = require('../../database'); var db = require('../../database');
var topics = require('../../topics'); var topics = require('../../topics');
var privileges = require('../../privileges');
var utils = require('../../utils'); var utils = require('../../utils');
module.exports = function (SocketTopics) { module.exports = function (SocketTopics) {
@ -25,13 +26,27 @@ module.exports = function (SocketTopics) {
}; };
SocketTopics.searchTags = function (socket, data, callback) { SocketTopics.searchTags = function (socket, data, callback) {
topics.searchTags(data, callback); searchTags(socket.uid, topics.searchTags, data, callback);
}; };
SocketTopics.searchAndLoadTags = function (socket, data, callback) { SocketTopics.searchAndLoadTags = function (socket, data, callback) {
topics.searchAndLoadTags(data, callback); searchTags(socket.uid, topics.searchAndLoadTags, data, callback);
}; };
function searchTags(uid, method, data, callback) {
async.waterfall([
function (next) {
privileges.global.can('search:tags', uid, next);
},
function (allowed, next) {
if (!allowed) {
return next(new Error('[[error:no-privileges]]'));
}
method(data, next);
},
], callback);
}
SocketTopics.loadMoreTags = function (socket, data, callback) { SocketTopics.loadMoreTags = function (socket, data, callback) {
if (!data || !utils.isNumber(data.after)) { if (!data || !utils.isNumber(data.after)) {
return callback(new Error('[[error:invalid-data]]')); return callback(new Error('[[error:invalid-data]]'));

@ -3,8 +3,8 @@
var async = require('async'); var async = require('async');
var user = require('../../user'); var user = require('../../user');
var meta = require('../../meta');
var pagination = require('../../pagination'); var pagination = require('../../pagination');
var privileges = require('../../privileges');
module.exports = function (SocketUser) { module.exports = function (SocketUser) {
SocketUser.search = function (socket, data, callback) { SocketUser.search = function (socket, data, callback) {
@ -12,12 +12,14 @@ module.exports = function (SocketUser) {
return callback(new Error('[[error:invalid-data]]')); return callback(new Error('[[error:invalid-data]]'));
} }
if (!socket.uid && parseInt(meta.config.allowGuestUserSearching, 10) !== 1) {
return callback(new Error('[[error:not-logged-in]]'));
}
async.waterfall([ async.waterfall([
function (next) { function (next) {
privileges.global.can('search:users', socket.uid, next);
},
function (allowed, next) {
if (!allowed) {
return next(new Error('[[error:no-privileges]]'));
}
user.search({ user.search({
query: data.query, query: data.query,
page: data.page, page: data.page,

@ -0,0 +1,30 @@
'use strict';
var async = require('async');
module.exports = {
name: 'Give global search privileges',
timestamp: Date.UTC(2018, 4, 28),
method: function (callback) {
var meta = require('../../meta');
var privileges = require('../../privileges');
var allowGuestSearching = parseInt(meta.config.allowGuestSearching, 10) === 1;
var allowGuestUserSearching = parseInt(meta.config.allowGuestUserSearching, 10) === 1;
async.waterfall([
function (next) {
privileges.global.give(['search:content', 'search:users', 'search:tags'], 'registered-users', next);
},
function (next) {
var guestPrivs = [];
if (allowGuestSearching) {
guestPrivs.push('search:content');
}
if (allowGuestUserSearching) {
guestPrivs.push('search:users');
}
guestPrivs.push('search:tags');
privileges.global.give(guestPrivs, 'guests', next);
},
], callback);
},
};

@ -17,26 +17,4 @@
</div> </div>
</div> </div>
<div class="row">
<div class="col-sm-2 col-xs-12 settings-header">[[admin/settings/guest:privileges]]</div>
<div class="col-sm-10 col-xs-12">
<form role="form">
<div class="checkbox">
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input class="mdl-switch__input" type="checkbox" data-field="allowGuestSearching">
<span class="mdl-switch__label"><strong>[[admin/settings/guest:privileges.can-search]]</strong></span>
</label>
</div>
<div class="checkbox">
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
<input class="mdl-switch__input" type="checkbox" data-field="allowGuestUserSearching">
<span class="mdl-switch__label"><strong>[[admin/settings/guest:privileges.can-search-users]]</strong></span>
</label>
</div>
</form>
</div>
</div>
<!-- IMPORT admin/partials/settings/footer.tpl --> <!-- IMPORT admin/partials/settings/footer.tpl -->

@ -667,6 +667,9 @@ describe('Categories', function () {
assert.deepEqual(data, { assert.deepEqual(data, {
ban: false, ban: false,
chat: false, chat: false,
'search:content': false,
'search:users': false,
'search:tags': false,
'upload:post:image': false, 'upload:post:image': false,
'upload:post:file': false, 'upload:post:file': false,
signature: false, signature: false,
@ -705,6 +708,9 @@ describe('Categories', function () {
assert.deepEqual(data, { assert.deepEqual(data, {
'groups:ban': false, 'groups:ban': false,
'groups:chat': true, 'groups:chat': true,
'groups:search:content': true,
'groups:search:users': true,
'groups:search:tags': true,
'groups:upload:post:image': true, 'groups:upload:post:image': true,
'groups:upload:post:file': false, 'groups:upload:post:file': false,
'groups:signature': true, 'groups:signature': true,

@ -630,15 +630,28 @@ describe('Controllers', function () {
}); });
}); });
it('should load users search page', function (done) { it('should error if guests do not have search privilege', function (done) {
request(nconf.get('url') + '/users?term=bar&section=sort-posts', function (err, res, body) { request(nconf.get('url') + '/api/users?term=bar&section=sort-posts', { json: true }, function (err, res, body) {
assert.ifError(err); assert.ifError(err);
assert.equal(res.statusCode, 200); assert.equal(res.statusCode, 500);
assert(body); assert(body);
assert.equal(body.error, '[[error:no-privileges]]');
done(); done();
}); });
}); });
it('should load users search page', function (done) {
privileges.global.give(['search:users'], 'guests', function (err) {
assert.ifError(err);
request(nconf.get('url') + '/users?term=bar&section=sort-posts', function (err, res, body) {
assert.ifError(err);
assert.equal(res.statusCode, 200);
assert(body);
privileges.global.rescind(['search:users'], 'guests', done);
});
});
});
it('should load groups page', function (done) { it('should load groups page', function (done) {
request(nconf.get('url') + '/groups', function (err, res, body) { request(nconf.get('url') + '/groups', function (err, res, body) {
assert.ifError(err); assert.ifError(err);

@ -205,7 +205,7 @@ function setupDefaultConfigs(meta, next) {
function giveDefaultGlobalPrivileges(next) { function giveDefaultGlobalPrivileges(next) {
var privileges = require('../../src/privileges'); var privileges = require('../../src/privileges');
privileges.global.give(['chat', 'upload:post:image', 'signature'], 'registered-users', next); privileges.global.give(['chat', 'upload:post:image', 'signature', 'search:content', 'search:users', 'search:tags'], 'registered-users', next);
} }
function enableDefaultPlugins(callback) { function enableDefaultPlugins(callback) {

@ -11,6 +11,7 @@ var topics = require('../src/topics');
var categories = require('../src/categories'); var categories = require('../src/categories');
var user = require('../src/user'); var user = require('../src/user');
var search = require('../src/search'); var search = require('../src/search');
var privileges = require('../src/privileges');
describe('Search', function () { describe('Search', function () {
var phoebeUid; var phoebeUid;
@ -96,21 +97,22 @@ describe('Search', function () {
it('should search term in titles and posts', function (done) { it('should search term in titles and posts', function (done) {
var meta = require('../src/meta'); var meta = require('../src/meta');
meta.config.allowGuestSearching = 1;
var qs = '/api/search?term=cucumber&in=titlesposts&categories[]=' + cid1 + '&by=phoebe&replies=1&repliesFilter=atleast&sortBy=timestamp&sortDirection=desc&showAs=posts'; var qs = '/api/search?term=cucumber&in=titlesposts&categories[]=' + cid1 + '&by=phoebe&replies=1&repliesFilter=atleast&sortBy=timestamp&sortDirection=desc&showAs=posts';
privileges.global.give(['search:content'], 'guests', function (err) {
request({
url: nconf.get('url') + qs,
json: true,
}, function (err, response, body) {
assert.ifError(err); assert.ifError(err);
assert(body); request({
assert.equal(body.matchCount, 1); url: nconf.get('url') + qs,
assert.equal(body.posts.length, 1); json: true,
assert.equal(body.posts[0].pid, post1Data.pid); }, function (err, response, body) {
assert.equal(body.posts[0].uid, phoebeUid); assert.ifError(err);
assert(body);
done(); assert.equal(body.matchCount, 1);
assert.equal(body.posts.length, 1);
assert.equal(body.posts[0].pid, post1Data.pid);
assert.equal(body.posts[0].uid, phoebeUid);
privileges.global.rescind(['search:content'], 'guests', done);
});
}); });
}); });

@ -293,10 +293,8 @@ describe('User', function () {
}); });
it('should error for guest', function (done) { it('should error for guest', function (done) {
meta.config.allowGuestUserSearching = 0;
socketUser.search({ uid: 0 }, { query: 'john' }, function (err) { socketUser.search({ uid: 0 }, { query: 'john' }, function (err) {
assert.equal(err.message, '[[error:not-logged-in]]'); assert.equal(err.message, '[[error:no-privileges]]');
meta.config.allowGuestUserSearching = 1;
done(); done();
}); });
}); });

Loading…
Cancel
Save