mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-29 10:06:13 +01:00
feat: #7957, allow post queue based on group
allow multiple select in ACP pages
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
"chatMessageDelay": 200,
|
"chatMessageDelay": 200,
|
||||||
"newbiePostDelayThreshold": 3,
|
"newbiePostDelayThreshold": 3,
|
||||||
"postQueueReputationThreshold": 0,
|
"postQueueReputationThreshold": 0,
|
||||||
|
"groupsExemptFromPostQueue": ["administrators", "Global Moderators"],
|
||||||
"minimumPostLength": 8,
|
"minimumPostLength": 8,
|
||||||
"maximumPostLength": 32767,
|
"maximumPostLength": 32767,
|
||||||
"minimumTagsPerTopic": 0,
|
"minimumTagsPerTopic": 0,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
"restrictions-new": "New User Restrictions",
|
"restrictions-new": "New User Restrictions",
|
||||||
"restrictions.post-queue": "Enable post queue",
|
"restrictions.post-queue": "Enable post queue",
|
||||||
"restrictions.post-queue-rep-threshold": "Reputation required to bypass post queue",
|
"restrictions.post-queue-rep-threshold": "Reputation required to bypass post queue",
|
||||||
|
"restrictions.groups-exempt-from-post-queue": "Select groups that should be exempt from the post queue",
|
||||||
"restrictions-new.post-queue": "Enable new user restrictions",
|
"restrictions-new.post-queue": "Enable new user restrictions",
|
||||||
"restrictions.post-queue-help": "Enabling post queue will put the posts of new users in a queue for approval",
|
"restrictions.post-queue-help": "Enabling post queue will put the posts of new users in a queue for approval",
|
||||||
"restrictions-new.post-queue-help": "Enabling new user restrictions will set restrictions on posts created by new users",
|
"restrictions-new.post-queue-help": "Enabling new user restrictions will set restrictions on posts created by new users",
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
const meta = require('../../meta');
|
const meta = require('../../meta');
|
||||||
const emailer = require('../../emailer');
|
const emailer = require('../../emailer');
|
||||||
const notifications = require('../../notifications');
|
const notifications = require('../../notifications');
|
||||||
|
const groups = require('../../groups');
|
||||||
|
|
||||||
const settingsController = module.exports;
|
const settingsController = module.exports;
|
||||||
|
|
||||||
@@ -13,6 +14,8 @@ settingsController.get = async function (req, res, next) {
|
|||||||
await renderEmail(req, res, next);
|
await renderEmail(req, res, next);
|
||||||
} else if (term === 'user') {
|
} else if (term === 'user') {
|
||||||
await renderUser(req, res, next);
|
await renderUser(req, res, next);
|
||||||
|
} else if (term === 'post') {
|
||||||
|
await renderPost(req, res, next);
|
||||||
} else {
|
} else {
|
||||||
res.render('admin/settings/' + term);
|
res.render('admin/settings/' + term);
|
||||||
}
|
}
|
||||||
@@ -41,3 +44,10 @@ async function renderUser(req, res) {
|
|||||||
notificationSettings: notificationSettings,
|
notificationSettings: notificationSettings,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function renderPost(req, res) {
|
||||||
|
const groupData = await groups.getNonPrivilegeGroups('groups:createtime', 0, -1);
|
||||||
|
res.render('admin/settings/post', {
|
||||||
|
groupsExemptFromPostQueue: groupData,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ const utils = require('../utils');
|
|||||||
const db = require('../database');
|
const db = require('../database');
|
||||||
const user = require('../user');
|
const user = require('../user');
|
||||||
const batch = require('../batch');
|
const batch = require('../batch');
|
||||||
|
const meta = require('../meta');
|
||||||
|
|
||||||
|
|
||||||
module.exports = function (Groups) {
|
module.exports = function (Groups) {
|
||||||
@@ -164,6 +165,7 @@ module.exports = function (Groups) {
|
|||||||
await updateMemberGroupTitles(oldName, newName);
|
await updateMemberGroupTitles(oldName, newName);
|
||||||
await updateNavigationItems(oldName, newName);
|
await updateNavigationItems(oldName, newName);
|
||||||
await updateWidgets(oldName, newName);
|
await updateWidgets(oldName, newName);
|
||||||
|
await updateConfig(oldName, newName);
|
||||||
await db.setObject('group:' + oldName, { name: newName, slug: utils.slugify(newName) });
|
await db.setObject('group:' + oldName, { name: newName, slug: utils.slugify(newName) });
|
||||||
await db.deleteObjectField('groupslug:groupname', group.slug);
|
await db.deleteObjectField('groupslug:groupname', group.slug);
|
||||||
await db.setObjectField('groupslug:groupname', utils.slugify(newName), newName);
|
await db.setObjectField('groupslug:groupname', utils.slugify(newName), newName);
|
||||||
@@ -245,4 +247,11 @@ module.exports = function (Groups) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updateConfig(oldName, newName) {
|
||||||
|
if (meta.config.groupsExemptFromPostQueue.includes(oldName)) {
|
||||||
|
meta.config.groupsExemptFromPostQueue.splice(meta.config.groupsExemptFromPostQueue.indexOf(oldName), 1, newName);
|
||||||
|
await meta.configs.set('groupsExemptFromPostQueue', meta.config.groupsExemptFromPostQueue);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ const Configs = module.exports;
|
|||||||
|
|
||||||
Meta.config = {};
|
Meta.config = {};
|
||||||
|
|
||||||
|
// called after data is loaded from db
|
||||||
function deserialize(config) {
|
function deserialize(config) {
|
||||||
const deserialized = {};
|
const deserialized = {};
|
||||||
Object.keys(config).forEach(function (key) {
|
Object.keys(config).forEach(function (key) {
|
||||||
@@ -39,6 +40,13 @@ function deserialize(config) {
|
|||||||
deserialized[key] = defaults[key];
|
deserialized[key] = defaults[key];
|
||||||
} else if (defaultType === 'undefined' && !isNaN(number) && isFinite(config[key])) {
|
} else if (defaultType === 'undefined' && !isNaN(number) && isFinite(config[key])) {
|
||||||
deserialized[key] = number;
|
deserialized[key] = number;
|
||||||
|
} else if (Array.isArray(defaults[key]) && !Array.isArray(config[key])) {
|
||||||
|
try {
|
||||||
|
deserialized[key] = JSON.parse(config[key] || '[]');
|
||||||
|
} catch (err) {
|
||||||
|
winston.error(err);
|
||||||
|
deserialized[key] = defaults[key];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
deserialized[key] = config[key];
|
deserialized[key] = config[key];
|
||||||
}
|
}
|
||||||
@@ -46,7 +54,37 @@ function deserialize(config) {
|
|||||||
return deserialized;
|
return deserialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// called before data is saved to db
|
||||||
|
function serialize(config) {
|
||||||
|
const serialized = {};
|
||||||
|
Object.keys(config).forEach(function (key) {
|
||||||
|
const defaultType = typeof defaults[key];
|
||||||
|
const type = typeof config[key];
|
||||||
|
const number = parseFloat(config[key]);
|
||||||
|
|
||||||
|
if (defaultType === 'string' && type === 'number') {
|
||||||
|
serialized[key] = String(config[key]);
|
||||||
|
} else if (defaultType === 'number' && type === 'string') {
|
||||||
|
if (!isNaN(number) && isFinite(config[key])) {
|
||||||
|
serialized[key] = number;
|
||||||
|
} else {
|
||||||
|
serialized[key] = defaults[key];
|
||||||
|
}
|
||||||
|
} else if (config[key] === null) {
|
||||||
|
serialized[key] = defaults[key];
|
||||||
|
} else if (defaultType === 'undefined' && !isNaN(number) && isFinite(config[key])) {
|
||||||
|
serialized[key] = number;
|
||||||
|
} else if (Array.isArray(defaults[key]) && Array.isArray(config[key])) {
|
||||||
|
serialized[key] = JSON.stringify(config[key]);
|
||||||
|
} else {
|
||||||
|
serialized[key] = config[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return serialized;
|
||||||
|
}
|
||||||
|
|
||||||
Configs.deserialize = deserialize;
|
Configs.deserialize = deserialize;
|
||||||
|
Configs.serialize = serialize;
|
||||||
|
|
||||||
Configs.init = async function () {
|
Configs.init = async function () {
|
||||||
const config = await Configs.list();
|
const config = await Configs.list();
|
||||||
@@ -92,15 +130,15 @@ Configs.set = async function (field, value) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Configs.setMultiple = async function (data) {
|
Configs.setMultiple = async function (data) {
|
||||||
data = deserialize(data);
|
|
||||||
await processConfig(data);
|
await processConfig(data);
|
||||||
|
data = serialize(data);
|
||||||
await db.setObject('config', data);
|
await db.setObject('config', data);
|
||||||
updateConfig(data);
|
updateConfig(deserialize(data));
|
||||||
};
|
};
|
||||||
|
|
||||||
Configs.setOnEmpty = async function (values) {
|
Configs.setOnEmpty = async function (values) {
|
||||||
const data = await db.getObject('config');
|
const data = await db.getObject('config');
|
||||||
const config = { ...values, ...(data ? deserialize(data) : {}) };
|
const config = { ...values, ...(data ? serialize(data) : {}) };
|
||||||
await db.setObject('config', config);
|
await db.setObject('config', config);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ const socketHelpers = require('../socket.io/helpers');
|
|||||||
module.exports = function (Posts) {
|
module.exports = function (Posts) {
|
||||||
Posts.shouldQueue = async function (uid, data) {
|
Posts.shouldQueue = async function (uid, data) {
|
||||||
const userData = await user.getUserFields(uid, ['uid', 'reputation', 'postcount']);
|
const userData = await user.getUserFields(uid, ['uid', 'reputation', 'postcount']);
|
||||||
const shouldQueue = meta.config.postQueue && (!userData.uid || userData.reputation < meta.config.postQueueReputationThreshold || userData.postcount <= 0);
|
const isMemberOfExempt = await groups.isMemberOfAny(userData.uid, meta.config.groupsExemptFromPostQueue);
|
||||||
|
const shouldQueue = meta.config.postQueue && !isMemberOfExempt && (!userData.uid || userData.reputation < meta.config.postQueueReputationThreshold || userData.postcount <= 0);
|
||||||
const result = await plugins.fireHook('filter:post.shouldQueue', {
|
const result = await plugins.fireHook('filter:post.shouldQueue', {
|
||||||
shouldQueue: !!shouldQueue,
|
shouldQueue: !!shouldQueue,
|
||||||
uid: uid,
|
uid: uid,
|
||||||
|
|||||||
@@ -165,10 +165,11 @@ SocketAdmin.config.setMultiple = async function (socket, data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const changes = {};
|
const changes = {};
|
||||||
data = meta.configs.deserialize(data);
|
const newData = meta.configs.serialize(data);
|
||||||
Object.keys(data).forEach(function (key) {
|
const oldData = meta.configs.serialize(meta.config);
|
||||||
if (data[key] !== meta.config[key]) {
|
Object.keys(newData).forEach(function (key) {
|
||||||
changes[key] = data[key];
|
if (newData[key] !== oldData[key]) {
|
||||||
|
changes[key] = newData[key];
|
||||||
changes[key + '_old'] = meta.config[key];
|
changes[key + '_old'] = meta.config[key];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -138,6 +138,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>[[admin/settings/post:restrictions.groups-exempt-from-post-queue]]</label>
|
||||||
|
<select class="form-control" multiple data-field="groupsExemptFromPostQueue">
|
||||||
|
<!-- BEGIN groupsExemptFromPostQueue -->
|
||||||
|
<option value="{groupsExemptFromPostQueue.displayName}">{groupsExemptFromPostQueue.displayName}</option>
|
||||||
|
<!-- END -->
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -964,6 +964,7 @@ describe('Post\'s', function () {
|
|||||||
|
|
||||||
after(function (done) {
|
after(function (done) {
|
||||||
meta.config.postQueue = 0;
|
meta.config.postQueue = 0;
|
||||||
|
meta.config.groupsExemptFromPostQueue = [];
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1057,6 +1058,15 @@ describe('Post\'s', function () {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should bypass post queue if user is in exempt group', function (done) {
|
||||||
|
meta.config.groupsExemptFromPostQueue = ['registered-users'];
|
||||||
|
socketTopics.post({ uid: uid, emit: () => {} }, { title: 'should not be queued', content: 'topic content', cid: cid }, function (err, result) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.strictEqual(result.title, 'should not be queued');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('upload methods', function () {
|
describe('upload methods', function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user