closes #5991, closes #5884

v1.18.x
Barış Soner Uşaklı 7 years ago
parent d8fbd51e93
commit 72140e5338

@ -38,5 +38,5 @@
"bookmarkThreshold": 5,
"topicsPerList": 20,
"autoDetectLang": 1,
"privileges:flag": 0
"min:rep:flag": 0
}

@ -69,9 +69,9 @@
"nodebb-plugin-spam-be-gone": "0.5.1",
"nodebb-rewards-essentials": "0.0.9",
"nodebb-theme-lavender": "5.0.0",
"nodebb-theme-persona": "7.2.11",
"nodebb-theme-persona": "7.2.12",
"nodebb-theme-slick": "1.1.2",
"nodebb-theme-vanilla": "8.1.5",
"nodebb-theme-vanilla": "8.1.6",
"nodebb-widget-essentials": "4.0.1",
"nodemailer": "4.4.1",
"passport": "^0.4.0",

@ -5,5 +5,8 @@
"votes-are-public": "All Votes Are Public",
"thresholds": "Activity Thresholds",
"min-rep-downvote": "Minimum reputation to downvote posts",
"min-rep-flag": "Minimum reputation to flag posts"
"min-rep-flag": "Minimum reputation to flag posts",
"min-rep-website": "Minimum reputation to add \"Website\" to user profile",
"min-rep-aboutme": "Minimum reputation to add \"About me\" to user profile",
"min-rep-signature": "Minimum reputation to add \"Signature\" to user profile"
}

@ -146,6 +146,9 @@
"downvoting-disabled": "Downvoting is disabled",
"not-enough-reputation-to-downvote": "You do not have enough reputation to downvote this post",
"not-enough-reputation-to-flag": "You do not have enough reputation to flag this post",
"not-enough-reputation-min-rep-website": "You do not have enough reputation to add a website",
"not-enough-reputation-min-rep-aboutme": "You do not have enough reputation to add an about me",
"not-enough-reputation-min-rep-signature": "You do not have enough reputation to add a signature",
"already-flagged": "You have already flagged this post",
"self-vote": "You cannot vote on your own post",

@ -28,6 +28,9 @@ editController.get = function (req, res, callback) {
userData.maximumProfileImageSize = parseInt(meta.config.maximumProfileImageSize, 10);
userData.allowProfileImageUploads = parseInt(meta.config.allowProfileImageUploads, 10) === 1;
userData.allowAccountDelete = parseInt(meta.config.allowAccountDelete, 10) === 1;
userData.allowWebsite = !userData.isSelf || parseInt(userData.reputation, 10) >= (parseInt(meta.config['min:rep:website'], 10) || 0);
userData.allowAboutMe = !userData.isSelf || parseInt(userData.reputation, 10) >= (parseInt(meta.config['min:rep:aboutme'], 10) || 0);
userData.allowSignature = !userData.isSelf || parseInt(userData.reputation, 10) >= (parseInt(meta.config['min:rep:signature'], 10) || 0);
userData.profileImageDimension = parseInt(meta.config.profileImageDimension, 10) || 200;
userData.defaultAvatar = user.getDefaultAvatar();

@ -241,7 +241,7 @@ Flags.validate = function (payload, callback) {
return callback(err);
}
var minimumReputation = utils.isNumber(meta.config['privileges:flag']) ? parseInt(meta.config['privileges:flag'], 10) : 0;
var minimumReputation = utils.isNumber(meta.config['min:rep:flag']) ? parseInt(meta.config['min:rep:flag'], 10) : 0;
// Check if reporter meets rep threshold (or can edit the target post, in which case threshold does not apply)
if (!editable.flag && parseInt(data.reporter.reputation, 10) < minimumReputation) {
return callback(new Error('[[error:not-enough-reputation-to-flag]]'));
@ -257,7 +257,7 @@ Flags.validate = function (payload, callback) {
return callback(err);
}
var minimumReputation = utils.isNumber(meta.config['privileges:flag']) ? parseInt(meta.config['privileges:flag'], 10) : 0;
var minimumReputation = utils.isNumber(meta.config['min:rep:flag']) ? parseInt(meta.config['min:rep:flag'], 10) : 0;
// Check if reporter meets rep threshold (or can edit the target user, in which case threshold does not apply)
if (!editable && parseInt(data.reporter.reputation, 10) < minimumReputation) {
return callback(new Error('[[error:not-enough-reputation-to-flag]]'));

@ -179,7 +179,7 @@ module.exports = function (Posts) {
return callback(new Error('[[error:self-vote]]'));
}
if (command === 'downvote' && parseInt(results.reputation, 10) < parseInt(meta.config['privileges:downvote'], 10)) {
if (command === 'downvote' && parseInt(results.reputation, 10) < parseInt(meta.config['min:rep:downvote'], 10)) {
return callback(new Error('[[error:not-enough-reputation-to-downvote]]'));
}

@ -200,7 +200,7 @@ module.exports = function (privileges) {
}, next);
},
function (results, next) {
var minimumReputation = utils.isNumber(meta.config['privileges:flag']) ? parseInt(meta.config['privileges:flag'], 10) : 0;
var minimumReputation = utils.isNumber(meta.config['min:rep:flag']) ? parseInt(meta.config['min:rep:flag'], 10) : 0;
var canFlag = results.isAdminOrMod || parseInt(results.userReputation, 10) >= minimumReputation;
next(null, { flag: canFlag });
},

@ -0,0 +1,25 @@
'use strict';
var db = require('../../database');
module.exports = {
name: 'Rename privileges:downvote and privileges:flag to min:rep:downvote, min:rep:flag respectively',
timestamp: Date.UTC(2018, 0, 12),
method: function (callback) {
db.getObjectFields('config', ['privileges:downvote', 'privileges:flag'], function (err, config) {
if (err) {
return callback(err);
}
db.setObject('config', {
'min:rep:downvote': parseInt(config['privileges:downvote'], 10) || 0,
'min:rep:flag': parseInt(config['privileges:downvote'], 10) || 0,
}, function (err) {
if (err) {
return callback(err);
}
db.deleteObjectFields('config', ['privileges:downvote', 'privileges:flag'], callback);
});
});
},
};

@ -17,14 +17,6 @@ module.exports = function (User) {
var updateUid = data.uid;
var oldData;
if (data.aboutme !== undefined && data.aboutme.length > meta.config.maximumAboutMeLength) {
return callback(new Error('[[error:about-me-too-long, ' + meta.config.maximumAboutMeLength + ']]'));
}
if (data.signature !== undefined && data.signature.length > meta.config.maximumSignatureLength) {
return callback(new Error('[[error:signature-too-long, ' + meta.config.maximumSignatureLength + ']]'));
}
async.waterfall([
function (next) {
plugins.fireHook('filter:user.updateProfile', { uid: uid, data: data, fields: fields }, next);
@ -33,13 +25,7 @@ module.exports = function (User) {
fields = data.fields;
data = data.data;
async.series([
async.apply(isEmailAvailable, data, updateUid),
async.apply(isUsernameAvailable, data, updateUid),
async.apply(isGroupTitleValid, data),
], function (err) {
next(err);
});
validateData(uid, data, next);
},
function (next) {
User.getUserFields(updateUid, fields, next);
@ -73,6 +59,19 @@ module.exports = function (User) {
], callback);
};
function validateData(callerUid, data, callback) {
async.series([
async.apply(isEmailAvailable, data, data.uid),
async.apply(isUsernameAvailable, data, data.uid),
async.apply(isGroupTitleValid, data),
async.apply(isWebsiteValid, callerUid, data),
async.apply(isAboutMeValid, callerUid, data),
async.apply(isSignatureValid, callerUid, data),
], function (err) {
callback(err);
});
}
function isEmailAvailable(data, uid, callback) {
if (!data.email) {
return callback();
@ -141,6 +140,52 @@ module.exports = function (User) {
}
}
function isWebsiteValid(callerUid, data, callback) {
if (!data.website) {
return setImmediate(callback);
}
checkMinReputation(callerUid, data.uid, 'min:rep:website', callback);
}
function isAboutMeValid(callerUid, data, callback) {
if (!data.aboutme) {
return setImmediate(callback);
}
if (data.aboutme !== undefined && data.aboutme.length > meta.config.maximumAboutMeLength) {
return callback(new Error('[[error:about-me-too-long, ' + meta.config.maximumAboutMeLength + ']]'));
}
checkMinReputation(callerUid, data.uid, 'min:rep:aboutme', callback);
}
function isSignatureValid(callerUid, data, callback) {
if (!data.signature) {
return setImmediate(callback);
}
if (data.signature !== undefined && data.signature.length > meta.config.maximumSignatureLength) {
return callback(new Error('[[error:signature-too-long, ' + meta.config.maximumSignatureLength + ']]'));
}
checkMinReputation(callerUid, data.uid, 'min:rep:signature', callback);
}
function checkMinReputation(callerUid, uid, setting, callback) {
var isSelf = parseInt(callerUid, 10) === parseInt(uid, 10);
if (!isSelf) {
return setImmediate(callback);
}
async.waterfall([
function (next) {
User.getUserField(uid, 'reputation', next);
},
function (reputation, next) {
if (parseInt(reputation, 10) < (parseInt(meta.config[setting], 10) || 0)) {
return next(new Error('[[error:not-enough-reputation-' + setting.replace(/:/g, '-') + ']]'));
}
next();
},
], callback);
}
function updateEmail(uid, newEmail, callback) {
async.waterfall([
function (next) {

@ -32,8 +32,11 @@
<div class="col-sm-2 col-xs-12 settings-header">[[admin/settings/reputation:thresholds]]</div>
<div class="col-sm-10 col-xs-12">
<form>
<strong>[[admin/settings/reputation:min-rep-downvote]]</strong><br /> <input type="text" class="form-control" placeholder="0" data-field="privileges:downvote"><br />
<strong>[[admin/settings/reputation:min-rep-flag]]</strong><br /> <input type="text" class="form-control" placeholder="0" data-field="privileges:flag"><br />
<strong>[[admin/settings/reputation:min-rep-downvote]]</strong><br /> <input type="text" class="form-control" placeholder="0" data-field="min:rep:downvote"><br />
<strong>[[admin/settings/reputation:min-rep-flag]]</strong><br /> <input type="text" class="form-control" placeholder="0" data-field="min:rep:flag"><br />
<strong>[[admin/settings/reputation:min-rep-website]]</strong><br /> <input type="text" class="form-control" placeholder="0" data-field="min:rep:website"><br />
<strong>[[admin/settings/reputation:min-rep-aboutme]]</strong><br /> <input type="text" class="form-control" placeholder="0" data-field="min:rep:aboutme"><br />
<strong>[[admin/settings/reputation:min-rep-signature]]</strong><br /> <input type="text" class="form-control" placeholder="0" data-field="min:rep:signature"><br />
</form>
</div>
</div>

@ -591,21 +591,21 @@ describe('Admin Controllers', function () {
it('should error with not enough reputation to flag', function (done) {
var socketFlags = require('../src/socket.io/flags');
var oldValue = meta.config['privileges:flag'];
meta.config['privileges:flag'] = 1000;
var oldValue = meta.config['min:rep:flag'];
meta.config['min:rep:flag'] = 1000;
socketFlags.create({ uid: regularUid }, { id: pid, type: 'post', reason: 'spam' }, function (err) {
assert.equal(err.message, '[[error:not-enough-reputation-to-flag]]');
meta.config['privileges:flag'] = oldValue;
meta.config['min:rep:flag'] = oldValue;
done();
});
});
it('should return flag details', function (done) {
var socketFlags = require('../src/socket.io/flags');
var oldValue = meta.config['privileges:flag'];
meta.config['privileges:flag'] = 0;
var oldValue = meta.config['min:rep:flag'];
meta.config['min:rep:flag'] = 0;
socketFlags.create({ uid: regularUid }, { id: pid, type: 'post', reason: 'spam' }, function (err, data) {
meta.config['privileges:flag'] = oldValue;
meta.config['min:rep:flag'] = oldValue;
assert.ifError(err);
request(nconf.get('url') + '/api/flags/' + data.flagId, { jar: moderatorJar, json: true }, function (err, res, body) {
assert.ifError(err);

@ -364,7 +364,7 @@ describe('Flags', function () {
});
it('should not pass validation if flag threshold is set and user rep does not meet it', function (done) {
Meta.configs.set('privileges:flag', '50', function (err) {
Meta.configs.set('min:rep:flag', '50', function (err) {
assert.ifError(err);
Flags.validate({
@ -374,7 +374,7 @@ describe('Flags', function () {
}, function (err) {
assert.ok(err);
assert.strictEqual('[[error:not-enough-reputation-to-flag]]', err.message);
Meta.configs.set('privileges:flag', 0, done);
Meta.configs.set('min:rep:flag', 0, done);
});
});
});

Loading…
Cancel
Save