mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
@@ -23,10 +23,11 @@
|
|||||||
"chatMessageDelay": 2000,
|
"chatMessageDelay": 2000,
|
||||||
"newbieChatMessageDelay": 120000,
|
"newbieChatMessageDelay": 120000,
|
||||||
"notificationSendDelay": 60,
|
"notificationSendDelay": 60,
|
||||||
"newbiePostDelayThreshold": 3,
|
"newbieReputationThreshold": 3,
|
||||||
"postQueue": 0,
|
"postQueue": 0,
|
||||||
"postQueueReputationThreshold": 0,
|
"postQueueReputationThreshold": 0,
|
||||||
"groupsExemptFromPostQueue": ["administrators", "Global Moderators"],
|
"groupsExemptFromPostQueue": ["administrators", "Global Moderators"],
|
||||||
|
"groupsExemptFromNewUserRestrictions": ["administrators", "Global Moderators"],
|
||||||
"groupsExemptFromMaintenanceMode": ["administrators", "Global Moderators"],
|
"groupsExemptFromMaintenanceMode": ["administrators", "Global Moderators"],
|
||||||
"minimumPostLength": 8,
|
"minimumPostLength": 8,
|
||||||
"maximumPostLength": 32767,
|
"maximumPostLength": 32767,
|
||||||
|
|||||||
@@ -87,5 +87,6 @@
|
|||||||
"restrictions.seconds-between-new": "Seconds between posts for new users",
|
"restrictions.seconds-between-new": "Seconds between posts for new users",
|
||||||
"restrictions.seconds-before-new": "Seconds before a new user can make their first post",
|
"restrictions.seconds-before-new": "Seconds before a new user can make their first post",
|
||||||
"restrictions.seconds-edit-after-new": "Number of seconds a post remains editable for new users (set to 0 to disable)",
|
"restrictions.seconds-edit-after-new": "Number of seconds a post remains editable for new users (set to 0 to disable)",
|
||||||
"restrictions.milliseconds-between-messages": "Time between chat messages for new users (ms)"
|
"restrictions.milliseconds-between-messages": "Time between chat messages for new users (ms)",
|
||||||
|
"restrictions.groups-exempt-from-new-user-restrictions": "Select groups that should be exempt from the new user restrictions"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ get:
|
|||||||
properties:
|
properties:
|
||||||
title:
|
title:
|
||||||
type: string
|
type: string
|
||||||
|
groupsExemptFromNewUserRestrictions:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: ../../../components/schemas/GroupObject.yaml#/GroupDataObject
|
||||||
notificationSettings:
|
notificationSettings:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ async function rateLimitExceeded(caller, field) {
|
|||||||
user.isPrivileged(caller.uid),
|
user.isPrivileged(caller.uid),
|
||||||
user.getUserField(caller.uid, 'reputation'),
|
user.getUserField(caller.uid, 'reputation'),
|
||||||
]);
|
]);
|
||||||
const newbie = !isPrivileged && meta.config.newbiePostDelayThreshold > reputation;
|
const newbie = !isPrivileged && meta.config.newbieReputationThreshold > reputation;
|
||||||
const delay = newbie ? meta.config.newbieChatMessageDelay : meta.config.chatMessageDelay;
|
const delay = newbie ? meta.config.newbieChatMessageDelay : meta.config.chatMessageDelay;
|
||||||
session[field] = session[field] || 0;
|
session[field] = session[field] || 0;
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,10 @@ settingsController.email = async (req, res) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
settingsController.user = async (req, res) => {
|
settingsController.user = async (req, res) => {
|
||||||
const notificationTypes = await notifications.getAllNotificationTypes();
|
const [notificationTypes, groupData] = await Promise.all([
|
||||||
|
notifications.getAllNotificationTypes(),
|
||||||
|
groups.getNonPrivilegeGroups('groups:createtime', 0, -1),
|
||||||
|
]);
|
||||||
const notificationSettings = notificationTypes.map(type => ({
|
const notificationSettings = notificationTypes.map(type => ({
|
||||||
name: type,
|
name: type,
|
||||||
label: `[[notifications:${type.replace(/_/g, '-')}]]`,
|
label: `[[notifications:${type.replace(/_/g, '-')}]]`,
|
||||||
@@ -54,6 +57,7 @@ settingsController.user = async (req, res) => {
|
|||||||
res.render('admin/settings/user', {
|
res.render('admin/settings/user', {
|
||||||
title: '[[admin/menu:settings/user]]',
|
title: '[[admin/menu:settings/user]]',
|
||||||
notificationSettings: notificationSettings,
|
notificationSettings: notificationSettings,
|
||||||
|
groupsExemptFromNewUserRestrictions: groupData,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -274,17 +274,19 @@ module.exports = function (Groups) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function updateConfig(oldName, newName) {
|
async function updateConfig(oldName, newName) {
|
||||||
if (meta.config.groupsExemptFromPostQueue.includes(oldName)) {
|
const configKeys = [
|
||||||
meta.config.groupsExemptFromPostQueue.splice(
|
'groupsExemptFromPostQueue',
|
||||||
meta.config.groupsExemptFromPostQueue.indexOf(oldName), 1, newName
|
'groupsExemptFromNewUserRestrictions',
|
||||||
);
|
'groupsExemptFromMaintenanceMode',
|
||||||
await meta.configs.set('groupsExemptFromPostQueue', meta.config.groupsExemptFromPostQueue);
|
];
|
||||||
}
|
|
||||||
if (meta.config.groupsExemptFromMaintenanceMode.includes(oldName)) {
|
for (const key of configKeys) {
|
||||||
meta.config.groupsExemptFromMaintenanceMode.splice(
|
if (meta.config[key] && meta.config[key].includes(oldName)) {
|
||||||
meta.config.groupsExemptFromMaintenanceMode.indexOf(oldName), 1, newName
|
meta.config[key].splice(
|
||||||
);
|
meta.config[key].indexOf(oldName), 1, newName
|
||||||
await meta.configs.set('groupsExemptFromMaintenanceMode', meta.config.groupsExemptFromMaintenanceMode);
|
);
|
||||||
|
await meta.configs.set(key, meta.config[key]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ privsPosts.canEdit = async function (pid, uid) {
|
|||||||
if (
|
if (
|
||||||
!results.isMod &&
|
!results.isMod &&
|
||||||
meta.config.newbiePostEditDuration > 0 &&
|
meta.config.newbiePostEditDuration > 0 &&
|
||||||
meta.config.newbiePostDelayThreshold > results.userData.reputation &&
|
meta.config.newbieReputationThreshold > results.userData.reputation &&
|
||||||
Date.now() - results.postData.timestamp > meta.config.newbiePostEditDuration * 1000
|
Date.now() - results.postData.timestamp > meta.config.newbiePostEditDuration * 1000
|
||||||
) {
|
) {
|
||||||
return { flag: false, message: `[[error:post-edit-duration-expired, ${meta.config.newbiePostEditDuration}]]` };
|
return { flag: false, message: `[[error:post-edit-duration-expired, ${meta.config.newbiePostEditDuration}]]` };
|
||||||
|
|||||||
15
src/upgrades/3.6.0/rename_newbie_config.js
Normal file
15
src/upgrades/3.6.0/rename_newbie_config.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/* eslint-disable no-await-in-loop */
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const db = require('../../database');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'Rename newbiePostDelayThreshold to newbieReputationThreshold',
|
||||||
|
timestamp: Date.UTC(2023, 10, 7),
|
||||||
|
method: async function () {
|
||||||
|
const current = await db.getObjectField('config', 'newbiePostDelayThreshold');
|
||||||
|
await db.setObjectField('config', 'newbieReputationThreshold', current);
|
||||||
|
await db.deleteObjectField('config', 'newbiePostDelayThreshold');
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
const db = require('../database');
|
const db = require('../database');
|
||||||
const meta = require('../meta');
|
const meta = require('../meta');
|
||||||
const privileges = require('../privileges');
|
const privileges = require('../privileges');
|
||||||
|
const groups = require('../groups');
|
||||||
|
|
||||||
module.exports = function (User) {
|
module.exports = function (User) {
|
||||||
User.isReadyToPost = async function (uid, cid) {
|
User.isReadyToPost = async function (uid, cid) {
|
||||||
@@ -31,9 +32,10 @@ module.exports = function (User) {
|
|||||||
if (parseInt(uid, 10) === 0) {
|
if (parseInt(uid, 10) === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const [userData, isAdminOrMod] = await Promise.all([
|
const [userData, isAdminOrMod, isMemberOfExempt] = await Promise.all([
|
||||||
User.getUserFields(uid, ['uid', 'mutedUntil', 'joindate', 'email', 'reputation'].concat([field])),
|
User.getUserFields(uid, ['uid', 'mutedUntil', 'joindate', 'email', 'reputation'].concat([field])),
|
||||||
privileges.categories.isAdminOrMod(cid, uid),
|
privileges.categories.isAdminOrMod(cid, uid),
|
||||||
|
groups.isMemberOfAny(uid, meta.config.groupsExemptFromNewUserRestrictions),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (!userData.uid) {
|
if (!userData.uid) {
|
||||||
@@ -54,14 +56,15 @@ module.exports = function (User) {
|
|||||||
const lasttime = userData[field] || 0;
|
const lasttime = userData[field] || 0;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
!isMemberOfExempt &&
|
||||||
meta.config.newbiePostDelay > 0 &&
|
meta.config.newbiePostDelay > 0 &&
|
||||||
meta.config.newbiePostDelayThreshold > userData.reputation &&
|
meta.config.newbieReputationThreshold > userData.reputation &&
|
||||||
now - lasttime < meta.config.newbiePostDelay * 1000
|
now - lasttime < meta.config.newbiePostDelay * 1000
|
||||||
) {
|
) {
|
||||||
if (meta.config.newbiewPostDelay % 60 === 0) {
|
if (meta.config.newbiewPostDelay % 60 === 0) {
|
||||||
throw new Error(`[[error:too-many-posts-newbie-minutes, ${Math.floor(meta.config.newbiePostDelay / 60)}, ${meta.config.newbiePostDelayThreshold}]]`);
|
throw new Error(`[[error:too-many-posts-newbie-minutes, ${Math.floor(meta.config.newbiePostDelay / 60)}, ${meta.config.newbieReputationThreshold}]]`);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`[[error:too-many-posts-newbie, ${meta.config.newbiePostDelay}, ${meta.config.newbiePostDelayThreshold}]]`);
|
throw new Error(`[[error:too-many-posts-newbie, ${meta.config.newbiePostDelay}, ${meta.config.newbieReputationThreshold}]]`);
|
||||||
}
|
}
|
||||||
} else if (now - lasttime < meta.config.postDelay * 1000) {
|
} else if (now - lasttime < meta.config.postDelay * 1000) {
|
||||||
throw new Error(`[[error:too-many-posts, ${meta.config.postDelay}]]`);
|
throw new Error(`[[error:too-many-posts, ${meta.config.postDelay}]]`);
|
||||||
|
|||||||
@@ -218,8 +218,8 @@
|
|||||||
<h5 class="fw-bold tracking-tight settings-header">[[admin/settings/user:restrictions-new]]</h5>
|
<h5 class="fw-bold tracking-tight settings-header">[[admin/settings/user:restrictions-new]]</h5>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label" for="newbiePostDelayThreshold">[[admin/settings/user:restrictions.rep-threshold]]</label>
|
<label class="form-label" for="newbieReputationThreshold">[[admin/settings/user:restrictions.rep-threshold]]</label>
|
||||||
<input id="newbiePostDelayThreshold" type="text" class="form-control" value="3" data-field="newbiePostDelayThreshold">
|
<input id="newbieReputationThreshold" type="text" class="form-control" value="3" data-field="newbieReputationThreshold">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
@@ -241,6 +241,16 @@
|
|||||||
<label class="form-label" for="newbieChatMessageDelay">[[admin/settings/user:restrictions.milliseconds-between-messages]]</label>
|
<label class="form-label" for="newbieChatMessageDelay">[[admin/settings/user:restrictions.milliseconds-between-messages]]</label>
|
||||||
<input id="newbieChatMessageDelay" type="text" class="form-control" data-field="newbieChatMessageDelay">
|
<input id="newbieChatMessageDelay" type="text" class="form-control" data-field="newbieChatMessageDelay">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label" for="groupsExemptFromNewUserRestrictions">[[admin/settings/user:restrictions.groups-exempt-from-new-user-restrictions]]</label>
|
||||||
|
<select id="groupsExemptFromNewUserRestrictions" class="form-select" multiple data-field="groupsExemptFromNewUserRestrictions">
|
||||||
|
{{{ each groupsExemptFromNewUserRestrictions }}}
|
||||||
|
<option value="{groupsExemptFromNewUserRestrictions.displayName}">{groupsExemptFromNewUserRestrictions.displayName}</option>
|
||||||
|
{{{ end }}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|||||||
@@ -317,7 +317,7 @@ describe('User', () => {
|
|||||||
|
|
||||||
it('should error when a new user posts if the last post time is 10 < 30 seconds', (done) => {
|
it('should error when a new user posts if the last post time is 10 < 30 seconds', (done) => {
|
||||||
meta.config.newbiePostDelay = 30;
|
meta.config.newbiePostDelay = 30;
|
||||||
meta.config.newbiePostDelayThreshold = 3;
|
meta.config.newbieReputationThreshold = 3;
|
||||||
|
|
||||||
User.setUserField(testUid, 'lastposttime', +new Date() - (20 * 1000), () => {
|
User.setUserField(testUid, 'lastposttime', +new Date() - (20 * 1000), () => {
|
||||||
Topics.post({
|
Topics.post({
|
||||||
|
|||||||
Reference in New Issue
Block a user