mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-06-17 16:20:10 +02:00
feat: min:rep:upvote, and other limits similar to downvotes
closes #10380
This commit is contained in:
@@ -289,7 +289,7 @@ Flags.validate = async function (payload) {
|
||||
if (payload.type === 'post') {
|
||||
const editable = await privileges.posts.canEdit(payload.id, payload.uid);
|
||||
if (!editable.flag && !meta.config['reputation:disabled'] && reporter.reputation < meta.config['min:rep:flag']) {
|
||||
throw new Error('[[error:not-enough-reputation-to-flag]]');
|
||||
throw new Error(`[[error:not-enough-reputation-to-flag, ${meta.config['min:rep:flag']}]]`);
|
||||
}
|
||||
} else if (payload.type === 'user') {
|
||||
if (parseInt(payload.id, 10) === parseInt(payload.uid, 10)) {
|
||||
@@ -297,7 +297,7 @@ Flags.validate = async function (payload) {
|
||||
}
|
||||
const editable = await privileges.users.canEdit(payload.uid, payload.id);
|
||||
if (!editable && !meta.config['reputation:disabled'] && reporter.reputation < meta.config['min:rep:flag']) {
|
||||
throw new Error('[[error:not-enough-reputation-to-flag]]');
|
||||
throw new Error(`[[error:not-enough-reputation-to-flag, ${meta.config['min:rep:flag']}]]`);
|
||||
}
|
||||
} else {
|
||||
throw new Error('[[error:invalid-data]]');
|
||||
|
||||
@@ -128,8 +128,8 @@ module.exports = function (Posts) {
|
||||
throw new Error('[[error:self-vote]]');
|
||||
}
|
||||
|
||||
if (type === 'downvote') {
|
||||
await checkDownvoteLimitation(pid, uid);
|
||||
if (type === 'downvote' || type === 'upvote') {
|
||||
await checkVoteLimitation(pid, uid, type);
|
||||
}
|
||||
|
||||
if (!voteStatus || (!voteStatus.upvoted && !voteStatus.downvoted)) {
|
||||
@@ -139,29 +139,30 @@ module.exports = function (Posts) {
|
||||
return await vote(voteStatus.upvoted ? 'downvote' : 'upvote', true, pid, uid, voteStatus);
|
||||
}
|
||||
|
||||
async function checkDownvoteLimitation(pid, uid) {
|
||||
async function checkVoteLimitation(pid, uid, type) {
|
||||
// type = 'upvote' or 'downvote'
|
||||
const oneDay = 86400000;
|
||||
const [reputation, targetUid, downvotedPids] = await Promise.all([
|
||||
const [reputation, targetUid, votedPidsToday] = await Promise.all([
|
||||
user.getUserField(uid, 'reputation'),
|
||||
Posts.getPostField(pid, 'uid'),
|
||||
db.getSortedSetRevRangeByScore(
|
||||
`uid:${uid}:downvote`, 0, -1, '+inf', Date.now() - oneDay
|
||||
`uid:${uid}:${type}`, 0, -1, '+inf', Date.now() - oneDay
|
||||
),
|
||||
]);
|
||||
|
||||
if (reputation < meta.config['min:rep:downvote']) {
|
||||
throw new Error('[[error:not-enough-reputation-to-downvote]]');
|
||||
if (reputation < meta.config[`min:rep:${type}`]) {
|
||||
throw new Error(`[[error:not-enough-reputation-to-${type}, ${meta.config[`min:rep:${type}`]}]]`);
|
||||
}
|
||||
|
||||
if (meta.config.downvotesPerDay && downvotedPids.length >= meta.config.downvotesPerDay) {
|
||||
throw new Error(`[[error:too-many-downvotes-today, ${meta.config.downvotesPerDay}]]`);
|
||||
const votesToday = meta.config[`${type}sPerDay`];
|
||||
if (votesToday && votedPidsToday.length >= votesToday) {
|
||||
throw new Error(`[[error:too-many-${type}s-today, ${votesToday}]]`);
|
||||
}
|
||||
|
||||
if (meta.config.downvotesPerUserPerDay) {
|
||||
const postData = await Posts.getPostsFields(downvotedPids, ['uid']);
|
||||
const targetDownvotes = postData.filter(p => p.uid === targetUid).length;
|
||||
if (targetDownvotes >= meta.config.downvotesPerUserPerDay) {
|
||||
throw new Error(`[[error:too-many-downvotes-today-user, ${meta.config.downvotesPerUserPerDay}]]`);
|
||||
const voterPerUserToday = meta.config[`${type}sPerUserPerDay`];
|
||||
if (voterPerUserToday) {
|
||||
const postData = await Posts.getPostsFields(votedPidsToday, ['uid']);
|
||||
const targetUpVotes = postData.filter(p => p.uid === targetUid).length;
|
||||
if (targetUpVotes >= voterPerUserToday) {
|
||||
throw new Error(`[[error:too-many-${type}s-today-user, ${voterPerUserToday}]]`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ module.exports = function (User) {
|
||||
}
|
||||
const reputation = await User.getUserField(uid, 'reputation');
|
||||
if (reputation < meta.config[setting]) {
|
||||
throw new Error(`[[error:not-enough-reputation-${setting.replace(/:/g, '-')}]]`);
|
||||
throw new Error(`[[error:not-enough-reputation-${setting.replace(/:/g, '-')}, ${meta.config[setting]}]]`);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -31,6 +31,19 @@
|
||||
<div class="col-sm-2 col-xs-12 settings-header">[[admin/settings/reputation:thresholds]]</div>
|
||||
<div class="col-sm-10 col-xs-12">
|
||||
<form>
|
||||
<div class="form-group">
|
||||
<label for="min:rep:upvote">[[admin/settings/reputation:min-rep-upvote]]</label>
|
||||
<input type="text" class="form-control" placeholder="0" data-field="min:rep:upvote" id="min:rep:upvote">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="upvotesPerDay">[[admin/settings/reputation:upvotes-per-day]]</label>
|
||||
<input type="text" class="form-control" placeholder="10" data-field="upvotesPerDay" id="upvotesPerDay">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="upvotesPerUserPerDay">[[admin/settings/reputation:upvotes-per-user-per-day]]</label>
|
||||
<input type="text" class="form-control" placeholder="3" data-field="upvotesPerUserPerDay" id="upvotesPerUserPerDay">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="min:rep:downvote">[[admin/settings/reputation:min-rep-downvote]]</label>
|
||||
<input type="text" class="form-control" placeholder="0" data-field="min:rep:downvote" id="min:rep:downvote">
|
||||
|
||||
Reference in New Issue
Block a user