mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 19:46:01 +01:00
closes #6464
This commit is contained in:
@@ -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,
|
|
||||||
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,
|
|
||||||
};
|
|
||||||
|
|
||||||
async.parallel({
|
if (req.query.categories && !Array.isArray(req.query.categories)) {
|
||||||
categories: async.apply(categories.buildForSelect, req.uid, 'read'),
|
req.query.categories = [req.query.categories];
|
||||||
search: async.apply(search.search, data),
|
}
|
||||||
}, function (err, results) {
|
|
||||||
if (err) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
results.categories = results.categories.filter(function (category) {
|
var data = {
|
||||||
return category && !category.link;
|
query: req.query.term,
|
||||||
});
|
searchIn: req.query.in || 'posts',
|
||||||
|
matchWords: req.query.matchWords || 'all',
|
||||||
|
postedBy: req.query.by,
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
|
||||||
var categoriesData = [
|
async.parallel({
|
||||||
{ value: 'all', text: '[[unread:all_categories]]' },
|
categories: async.apply(categories.buildForSelect, req.uid, 'read'),
|
||||||
{ value: 'watched', text: '[[category:watched-categories]]' },
|
search: async.apply(search.search, data),
|
||||||
].concat(results.categories);
|
}, next);
|
||||||
|
},
|
||||||
|
function (results) {
|
||||||
|
results.categories = results.categories.filter(function (category) {
|
||||||
|
return category && !category.link;
|
||||||
|
});
|
||||||
|
|
||||||
var searchData = results.search;
|
var categoriesData = [
|
||||||
searchData.categories = categoriesData;
|
{ value: 'all', text: '[[unread:all_categories]]' },
|
||||||
searchData.categoriesCount = Math.max(10, Math.min(20, categoriesData.length));
|
{ value: 'watched', text: '[[category:watched-categories]]' },
|
||||||
searchData.pagination = pagination.create(page, searchData.pageCount, req.query);
|
].concat(results.categories);
|
||||||
searchData.showAsPosts = !req.query.showAs || req.query.showAs === 'posts';
|
|
||||||
searchData.showAsTopics = req.query.showAs === 'topics';
|
var searchData = results.search;
|
||||||
searchData.title = '[[global:header.search]]';
|
searchData.categories = categoriesData;
|
||||||
searchData.breadcrumbs = helpers.buildBreadcrumbs([{ text: '[[global:search]]' }]);
|
searchData.categoriesCount = Math.max(10, Math.min(20, categoriesData.length));
|
||||||
searchData.expandSearch = !req.query.term;
|
searchData.pagination = pagination.create(page, searchData.pageCount, req.query);
|
||||||
searchData.searchDefaultSortBy = meta.config.searchDefaultSortBy || '';
|
searchData.showAsPosts = !req.query.showAs || req.query.showAs === 'posts';
|
||||||
searchData.search_query = validator.escape(String(req.query.term || ''));
|
searchData.showAsTopics = req.query.showAs === 'topics';
|
||||||
searchData.term = req.query.term;
|
searchData.title = '[[global:header.search]]';
|
||||||
res.render('search', searchData);
|
searchData.breadcrumbs = helpers.buildBreadcrumbs([{ text: '[[global:search]]' }]);
|
||||||
});
|
searchData.expandSearch = !req.query.term;
|
||||||
|
searchData.searchDefaultSortBy = meta.config.searchDefaultSortBy || '';
|
||||||
|
searchData.search_query = validator.escape(String(req.query.term || ''));
|
||||||
|
searchData.term = req.query.term;
|
||||||
|
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,
|
||||||
|
|||||||
30
src/upgrades/1.9.4/search_privileges.js
Normal file
30
src/upgrades/1.9.4/search_privileges.js
Normal file
@@ -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§ion=sort-posts', function (err, res, body) {
|
request(nconf.get('url') + '/api/users?term=bar§ion=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§ion=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);
|
||||||
|
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);
|
||||||
|
|
||||||
done();
|
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();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user