mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
feat: chat allow/deny list, closes #13359
This commit is contained in:
@@ -107,10 +107,10 @@
|
|||||||
"nodebb-plugin-spam-be-gone": "2.3.1",
|
"nodebb-plugin-spam-be-gone": "2.3.1",
|
||||||
"nodebb-plugin-web-push": "0.7.3",
|
"nodebb-plugin-web-push": "0.7.3",
|
||||||
"nodebb-rewards-essentials": "1.0.1",
|
"nodebb-rewards-essentials": "1.0.1",
|
||||||
"nodebb-theme-harmony": "2.1.9",
|
"nodebb-theme-harmony": "2.1.10",
|
||||||
"nodebb-theme-lavender": "7.1.18",
|
"nodebb-theme-lavender": "7.1.18",
|
||||||
"nodebb-theme-peace": "2.2.40",
|
"nodebb-theme-peace": "2.2.40",
|
||||||
"nodebb-theme-persona": "14.1.7",
|
"nodebb-theme-persona": "14.1.8",
|
||||||
"nodebb-widget-essentials": "7.0.36",
|
"nodebb-widget-essentials": "7.0.36",
|
||||||
"nodemailer": "6.10.1",
|
"nodemailer": "6.10.1",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
|
|||||||
@@ -154,6 +154,8 @@
|
|||||||
"about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).",
|
"about-me-too-long": "Sorry, your about me cannot be longer than %1 character(s).",
|
||||||
"cant-chat-with-yourself": "Δεν μπορείς να συνομιλήσεις με τον εαυτό σου!",
|
"cant-chat-with-yourself": "Δεν μπορείς να συνομιλήσεις με τον εαυτό σου!",
|
||||||
"chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them",
|
"chat-restricted": "This user has restricted their chat messages. They must follow you before you can chat with them",
|
||||||
|
"chat-allow-list-user-already-added": "This user is already in your allow list",
|
||||||
|
"chat-deny-list-user-already-added": "This user is already in your deny list",
|
||||||
"chat-user-blocked": "You have been blocked by this user.",
|
"chat-user-blocked": "You have been blocked by this user.",
|
||||||
"chat-disabled": "Chat system disabled",
|
"chat-disabled": "Chat system disabled",
|
||||||
"too-many-messages": "You have sent too many messages, please wait awhile.",
|
"too-many-messages": "You have sent too many messages, please wait awhile.",
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
"show-email": "Show email",
|
"show-email": "Show email",
|
||||||
"show-fullname": "Show fullname",
|
"show-fullname": "Show fullname",
|
||||||
"restrict-chat": "Only allow chat messages from users I follow",
|
"restrict-chat": "Only allow chat messages from users I follow",
|
||||||
|
"disable-incoming-chats": "Disable incoming chat messages",
|
||||||
"outgoing-new-tab": "Open outgoing links in new tab",
|
"outgoing-new-tab": "Open outgoing links in new tab",
|
||||||
"topic-search": "Enable In-Topic Searching",
|
"topic-search": "Enable In-Topic Searching",
|
||||||
"update-url-with-post-index": "Update url with post index while browsing topics",
|
"update-url-with-post-index": "Update url with post index while browsing topics",
|
||||||
|
|||||||
@@ -111,6 +111,10 @@
|
|||||||
"show-email": "Show My Email",
|
"show-email": "Show My Email",
|
||||||
"show-fullname": "Show My Full Name",
|
"show-fullname": "Show My Full Name",
|
||||||
"restrict-chats": "Only allow chat messages from users I follow",
|
"restrict-chats": "Only allow chat messages from users I follow",
|
||||||
|
"disable-incoming-chats": "Disable incoming chat messages <a data-bs-toggle=\"tooltip\" href=\"#\" title=\"Admins and moderators can still send you messages\"><i class=\"fa-solid fa-circle-info\"></i></a>",
|
||||||
|
"chat-allow-list": "Allow chat messages from the following users",
|
||||||
|
"chat-deny-list": "Deny chat messages from the following users",
|
||||||
|
"chat-list-add-user": "Add user",
|
||||||
"digest-label": "Subscribe to Digest",
|
"digest-label": "Subscribe to Digest",
|
||||||
"digest-description": "Subscribe to email updates for this forum (new notifications and topics) according to a set schedule",
|
"digest-description": "Subscribe to email updates for this forum (new notifications and topics) according to a set schedule",
|
||||||
"digest-off": "Off",
|
"digest-off": "Off",
|
||||||
|
|||||||
@@ -31,9 +31,25 @@ Settings:
|
|||||||
followTopicsOnReply:
|
followTopicsOnReply:
|
||||||
type: boolean
|
type: boolean
|
||||||
description: Automatically be notified of new posts in a topic, when you reply to that topic
|
description: Automatically be notified of new posts in a topic, when you reply to that topic
|
||||||
restrictChat:
|
disableIncomingChats:
|
||||||
type: boolean
|
type: boolean
|
||||||
description: Do not allow other users to start chats with you (or add you to other chat rooms)
|
description: Do not allow other users to start chats with you (or add you to other chat rooms)
|
||||||
|
chatAllowList:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
description: List of uids that can start chats with you
|
||||||
|
chatDenyList:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
description: List of uids that are not allowed to start chats with you
|
||||||
|
chatAllowListUsers:
|
||||||
|
type: array
|
||||||
|
description: List of users that can start chats with you
|
||||||
|
chatDenyListUsers:
|
||||||
|
type: array
|
||||||
|
description: List of users that are not allowed to start chats with you
|
||||||
topicSearchEnabled:
|
topicSearchEnabled:
|
||||||
type: boolean
|
type: boolean
|
||||||
description: Enable keyword searching within topics
|
description: Enable keyword searching within topics
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
|
|
||||||
define('forum/account/settings', [
|
define('forum/account/settings', [
|
||||||
'forum/account/header', 'components', 'api', 'alerts', 'hooks',
|
'forum/account/header', 'components', 'api', 'alerts', 'hooks', 'autocomplete',
|
||||||
], function (header, components, api, alerts, hooks) {
|
], function (header, components, api, alerts, hooks, autocomplete) {
|
||||||
const AccountSettings = {};
|
const AccountSettings = {};
|
||||||
let savedSkin = '';
|
let savedSkin = '';
|
||||||
// If page skin is changed but not saved, switch the skin back
|
// If page skin is changed but not saved, switch the skin back
|
||||||
@@ -45,6 +45,8 @@ define('forum/account/settings', [
|
|||||||
toggleCustomRoute();
|
toggleCustomRoute();
|
||||||
|
|
||||||
components.get('user/sessions').find('.timeago').timeago();
|
components.get('user/sessions').find('.timeago').timeago();
|
||||||
|
|
||||||
|
handleChatAllowDenyList();
|
||||||
};
|
};
|
||||||
|
|
||||||
function loadSettings() {
|
function loadSettings() {
|
||||||
@@ -53,6 +55,9 @@ define('forum/account/settings', [
|
|||||||
$('.account').find('input, textarea, select').each(function (id, input) {
|
$('.account').find('input, textarea, select').each(function (id, input) {
|
||||||
input = $(input);
|
input = $(input);
|
||||||
const setting = input.attr('data-property');
|
const setting = input.attr('data-property');
|
||||||
|
if (!setting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (input.is('select')) {
|
if (input.is('select')) {
|
||||||
settings[setting] = input.val();
|
settings[setting] = input.val();
|
||||||
return;
|
return;
|
||||||
@@ -68,6 +73,13 @@ define('forum/account/settings', [
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const chatAllowList = $('[component="chat/allow/list/user"][data-uid]')
|
||||||
|
.map((i, el) => $(el).data('uid')).get();
|
||||||
|
const chatDenyList = $('[component="chat/deny/list/user"][data-uid]')
|
||||||
|
.map((i, el) => $(el).data('uid')).get();
|
||||||
|
settings.chatAllowList = JSON.stringify(chatAllowList);
|
||||||
|
settings.chatDenyList = JSON.stringify(chatDenyList);
|
||||||
|
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,5 +171,56 @@ define('forum/account/settings', [
|
|||||||
reskin(skin);
|
reskin(skin);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function handleChatAllowDenyList() {
|
||||||
|
autocomplete.user($('#chatAllowListAdd'), async function (ev, selected) {
|
||||||
|
const { user } = selected.item;
|
||||||
|
if (!user || String(user.uid) === String(app.user.uid)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($(`[component="chat/allow/list/user"][data-uid="${user.uid}"]`).length) {
|
||||||
|
return alerts.error('[[error:chat-allow-list-user-already-added]]');
|
||||||
|
}
|
||||||
|
const html = await app.parseAndTranslate('account/settings', 'settings.chatAllowListUsers', {
|
||||||
|
settings: { chatAllowListUsers: [selected.item.user] },
|
||||||
|
});
|
||||||
|
|
||||||
|
$('[component="chat/allow/list"]').append(html);
|
||||||
|
$('#chatAllowListAdd').val('');
|
||||||
|
toggleNoUsersElement();
|
||||||
|
});
|
||||||
|
|
||||||
|
autocomplete.user($('#chatDenyListAdd'), async function (ev, selected) {
|
||||||
|
const { user } = selected.item;
|
||||||
|
if (!user || String(user.uid) === String(app.user.uid)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($(`[component="chat/deny/list/user"][data-uid="${user.uid}"]`).length) {
|
||||||
|
return alerts.error('[[error:chat-deny-list-user-already-added]]');
|
||||||
|
}
|
||||||
|
const html = await app.parseAndTranslate('account/settings', 'settings.chatDenyListUsers', {
|
||||||
|
settings: { chatDenyListUsers: [selected.item.user] },
|
||||||
|
});
|
||||||
|
|
||||||
|
$('[component="chat/deny/list"]').append(html);
|
||||||
|
$('#chatDenyListAdd').val('');
|
||||||
|
toggleNoUsersElement();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('[component="chat/allow/list"]').on('click', '[component="chat/allow/delete"]', function () {
|
||||||
|
$(this).parent().remove();
|
||||||
|
toggleNoUsersElement();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('[component="chat/deny/list"]').on('click', '[component="chat/deny/delete"]', function () {
|
||||||
|
$(this).parent().remove();
|
||||||
|
toggleNoUsersElement();
|
||||||
|
});
|
||||||
|
|
||||||
|
function toggleNoUsersElement() {
|
||||||
|
$('[component="chat/allow/list/no-users"]').toggleClass('hidden', !!$('[component="chat/allow/list/user"]').length);
|
||||||
|
$('[component="chat/deny/list/no-users"]').toggleClass('hidden', !!$('[component="chat/deny/list/user"]').length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return AccountSettings;
|
return AccountSettings;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ define('autocomplete', [
|
|||||||
slug: user.userslug,
|
slug: user.userslug,
|
||||||
username: user.username,
|
username: user.username,
|
||||||
userslug: user.userslug,
|
userslug: user.userslug,
|
||||||
|
displayname: user.displayname,
|
||||||
picture: user.picture,
|
picture: user.picture,
|
||||||
banned: user.banned,
|
banned: user.banned,
|
||||||
'icon:text': user['icon:text'],
|
'icon:text': user['icon:text'],
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ settingsController.get = async function (req, res, next) {
|
|||||||
getNotificationSettings(userData),
|
getNotificationSettings(userData),
|
||||||
getHomePageRoutes(userData),
|
getHomePageRoutes(userData),
|
||||||
getSkinOptions(userData),
|
getSkinOptions(userData),
|
||||||
|
getChatAllowDenyList(userData),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
userData.customSettings = data.customSettings;
|
userData.customSettings = data.customSettings;
|
||||||
@@ -254,3 +255,13 @@ async function getSkinOptions(userData) {
|
|||||||
});
|
});
|
||||||
return bootswatchSkinOptions;
|
return bootswatchSkinOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getChatAllowDenyList(userData) {
|
||||||
|
const [chatAllowListUsers, chatDenyListUsers] = await Promise.all([
|
||||||
|
user.getUsersFields(userData.settings.chatAllowList, ['uid', 'username', 'picture']),
|
||||||
|
user.getUsersFields(userData.settings.chatDenyList, ['uid', 'username', 'picture']),
|
||||||
|
]);
|
||||||
|
|
||||||
|
userData.settings.chatAllowListUsers = chatAllowListUsers;
|
||||||
|
userData.settings.chatDenyListUsers = chatDenyListUsers;
|
||||||
|
};
|
||||||
|
|||||||
@@ -358,19 +358,27 @@ Messaging.canMessageUser = async (uid, toUid) => {
|
|||||||
throw new Error('[[error:no-privileges]]');
|
throw new Error('[[error:no-privileges]]');
|
||||||
}
|
}
|
||||||
|
|
||||||
const [settings, isAdmin, isModerator, isFollowing, isBlocked] = await Promise.all([
|
const [settings, isAdmin, isModerator, isBlocked] = await Promise.all([
|
||||||
user.getSettings(toUid),
|
user.getSettings(toUid),
|
||||||
user.isAdministrator(uid),
|
user.isAdministrator(uid),
|
||||||
user.isModeratorOfAnyCategory(uid),
|
user.isModeratorOfAnyCategory(uid),
|
||||||
user.isFollowing(toUid, uid),
|
|
||||||
user.blocks.is(uid, toUid),
|
user.blocks.is(uid, toUid),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (isBlocked) {
|
if (isBlocked) {
|
||||||
throw new Error('[[error:chat-user-blocked]]');
|
throw new Error('[[error:chat-user-blocked]]');
|
||||||
}
|
}
|
||||||
if (settings.restrictChat && !isAdmin && !isModerator && !isFollowing) {
|
const isPrivileged = isAdmin || isModerator;
|
||||||
throw new Error('[[error:chat-restricted]]');
|
if (!isPrivileged) {
|
||||||
|
if (settings.disableIncomingChats) {
|
||||||
|
throw new Error('[[error:chat-restricted]]');
|
||||||
|
}
|
||||||
|
if (settings.chatAllowList.length && !settings.chatAllowList.includes(String(uid))) {
|
||||||
|
throw new Error('[[error:chat-restricted]]');
|
||||||
|
}
|
||||||
|
if (settings.chatDenyList.length && settings.chatDenyList.includes(String(uid))) {
|
||||||
|
throw new Error('[[error:chat-restricted]]');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await plugins.hooks.fire('static:messaging.canMessageUser', {
|
await plugins.hooks.fire('static:messaging.canMessageUser', {
|
||||||
|
|||||||
44
src/upgrades/4.3.0/chat_allow_list.js
Normal file
44
src/upgrades/4.3.0/chat_allow_list.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const db = require('../../database');
|
||||||
|
const batch = require('../../batch');
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'Set user chat allow list to the users following if they turned on restrict chat',
|
||||||
|
timestamp: Date.UTC(2025, 3, 25),
|
||||||
|
method: async function () {
|
||||||
|
const { progress } = this;
|
||||||
|
|
||||||
|
progress.total = await db.sortedSetCard('users:joindate');
|
||||||
|
|
||||||
|
await batch.processSortedSet('users:joindate', async (uids) => {
|
||||||
|
const keys = uids.map(uid => `user:${uid}:settings`);
|
||||||
|
const [userSettings, followingUids] = await Promise.all([
|
||||||
|
db.getObjects(keys),
|
||||||
|
db.getSortedSetsMembers(uids.map(uid => `following:${uid}`)),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const bulkSet = [];
|
||||||
|
|
||||||
|
userSettings.forEach((settings, idx) => {
|
||||||
|
if (settings) {
|
||||||
|
const uid = uids[idx];
|
||||||
|
const followingUidsOfThisUser = followingUids[idx] || [];
|
||||||
|
|
||||||
|
if (parseInt(settings.restrictChat, 10) === 1 && followingUidsOfThisUser.length > 0) {
|
||||||
|
bulkSet.push([
|
||||||
|
`user:${uid}:settings`, { chatAllowList: JSON.stringify(followingUidsOfThisUser) },
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await db.setObjectBulk(bulkSet);
|
||||||
|
|
||||||
|
progress.incr(uids.length);
|
||||||
|
}, {
|
||||||
|
batch: 500,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -76,7 +76,7 @@ module.exports = function (User) {
|
|||||||
settings.followTopicsOnCreate = parseInt(getSetting(settings, 'followTopicsOnCreate', 1), 10) === 1;
|
settings.followTopicsOnCreate = parseInt(getSetting(settings, 'followTopicsOnCreate', 1), 10) === 1;
|
||||||
settings.followTopicsOnReply = parseInt(getSetting(settings, 'followTopicsOnReply', 0), 10) === 1;
|
settings.followTopicsOnReply = parseInt(getSetting(settings, 'followTopicsOnReply', 0), 10) === 1;
|
||||||
settings.upvoteNotifFreq = getSetting(settings, 'upvoteNotifFreq', 'all');
|
settings.upvoteNotifFreq = getSetting(settings, 'upvoteNotifFreq', 'all');
|
||||||
settings.restrictChat = parseInt(getSetting(settings, 'restrictChat', 0), 10) === 1;
|
settings.disableIncomingChats = parseInt(getSetting(settings, 'disableIncomingChats', 0), 10) === 1;
|
||||||
settings.topicSearchEnabled = parseInt(getSetting(settings, 'topicSearchEnabled', 0), 10) === 1;
|
settings.topicSearchEnabled = parseInt(getSetting(settings, 'topicSearchEnabled', 0), 10) === 1;
|
||||||
settings.updateUrlWithPostIndex = parseInt(getSetting(settings, 'updateUrlWithPostIndex', 1), 10) === 1;
|
settings.updateUrlWithPostIndex = parseInt(getSetting(settings, 'updateUrlWithPostIndex', 1), 10) === 1;
|
||||||
settings.bootswatchSkin = validator.escape(String(settings.bootswatchSkin || ''));
|
settings.bootswatchSkin = validator.escape(String(settings.bootswatchSkin || ''));
|
||||||
@@ -89,9 +89,19 @@ module.exports = function (User) {
|
|||||||
settings[notificationType] = getSetting(settings, notificationType, 'notification');
|
settings[notificationType] = getSetting(settings, notificationType, 'notification');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
settings.chatAllowList = parseJSONSetting(settings.chatAllowList || '[]', []).map(String);
|
||||||
|
settings.chatDenyList = parseJSONSetting(settings.chatDenyList || '[]', []).map(String);
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseJSONSetting(value, defaultValue) {
|
||||||
|
try {
|
||||||
|
return JSON.parse(value);
|
||||||
|
} catch (err) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getSetting(settings, key, defaultValue) {
|
function getSetting(settings, key, defaultValue) {
|
||||||
if (settings[key] || settings[key] === 0) {
|
if (settings[key] || settings[key] === 0) {
|
||||||
return settings[key];
|
return settings[key];
|
||||||
@@ -145,7 +155,7 @@ module.exports = function (User) {
|
|||||||
acpLang: data.acpLang || meta.config.defaultLang,
|
acpLang: data.acpLang || meta.config.defaultLang,
|
||||||
followTopicsOnCreate: data.followTopicsOnCreate,
|
followTopicsOnCreate: data.followTopicsOnCreate,
|
||||||
followTopicsOnReply: data.followTopicsOnReply,
|
followTopicsOnReply: data.followTopicsOnReply,
|
||||||
restrictChat: data.restrictChat,
|
disableIncomingChats: data.disableIncomingChats,
|
||||||
topicSearchEnabled: data.topicSearchEnabled,
|
topicSearchEnabled: data.topicSearchEnabled,
|
||||||
updateUrlWithPostIndex: data.updateUrlWithPostIndex,
|
updateUrlWithPostIndex: data.updateUrlWithPostIndex,
|
||||||
homePageRoute: ((data.homePageRoute === 'custom' ? data.homePageCustom : data.homePageRoute) || '').replace(/^\//, ''),
|
homePageRoute: ((data.homePageRoute === 'custom' ? data.homePageCustom : data.homePageRoute) || '').replace(/^\//, ''),
|
||||||
@@ -155,6 +165,8 @@ module.exports = function (User) {
|
|||||||
categoryWatchState: data.categoryWatchState,
|
categoryWatchState: data.categoryWatchState,
|
||||||
categoryTopicSort: data.categoryTopicSort,
|
categoryTopicSort: data.categoryTopicSort,
|
||||||
topicPostSort: data.topicPostSort,
|
topicPostSort: data.topicPostSort,
|
||||||
|
chatAllowList: data.chatAllowList,
|
||||||
|
chatDenyList: data.chatDenyList,
|
||||||
};
|
};
|
||||||
const notificationTypes = await notifications.getAllNotificationTypes();
|
const notificationTypes = await notifications.getAllNotificationTypes();
|
||||||
notificationTypes.forEach((notificationType) => {
|
notificationTypes.forEach((notificationType) => {
|
||||||
|
|||||||
@@ -296,8 +296,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-check form-switch mb-3">
|
<div class="form-check form-switch mb-3">
|
||||||
<input class="form-check-input" type="checkbox" id="restrictChat" data-field="restrictChat">
|
<input class="form-check-input" type="checkbox" id="disableIncomingChats" data-field="disableIncomingChats">
|
||||||
<label for="restrictChat" class="form-check-label">[[admin/settings/user:restrict-chat]]</label>
|
<label for="disableIncomingChats" class="form-check-label">[[admin/settings/user:disable-incoming-chats]]</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-check form-switch mb-3">
|
<div class="form-check form-switch mb-3">
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ describe('Messaging Library', () => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
await Groups.join('administrators', mocks.users.foo.uid);
|
await Groups.join('administrators', mocks.users.foo.uid);
|
||||||
await User.setSetting(mocks.users.baz.uid, 'restrictChat', '1');
|
await User.setSetting(mocks.users.baz.uid, 'disableIncomingChats', '1');
|
||||||
|
|
||||||
({ jar: mocks.users.foo.jar, csrf_token: mocks.users.foo.csrf } = await helpers.loginUser('foo', 'barbar'));
|
({ jar: mocks.users.foo.jar, csrf_token: mocks.users.foo.csrf } = await helpers.loginUser('foo', 'barbar'));
|
||||||
({ jar: mocks.users.bar.jar, csrf_token: mocks.users.bar.csrf } = await helpers.loginUser('bar', 'bazbaz'));
|
({ jar: mocks.users.bar.jar, csrf_token: mocks.users.bar.csrf } = await helpers.loginUser('bar', 'bazbaz'));
|
||||||
@@ -85,7 +85,7 @@ describe('Messaging Library', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT allow messages to be sent to a restricted user', async () => {
|
it('should NOT allow messages to be sent to a restricted user', async () => {
|
||||||
await User.setSetting(mocks.users.baz.uid, 'restrictChat', '1');
|
await User.setSetting(mocks.users.baz.uid, 'disableIncomingMessages', '1');
|
||||||
try {
|
try {
|
||||||
await Messaging.canMessageUser(mocks.users.herp.uid, mocks.users.baz.uid);
|
await Messaging.canMessageUser(mocks.users.herp.uid, mocks.users.baz.uid);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -100,13 +100,25 @@ describe('Messaging Library', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow messages to be sent to a restricted user if restricted user follows sender', (done) => {
|
it('should respect allow/deny list when sending chat messages', async () => {
|
||||||
User.follow(mocks.users.baz.uid, mocks.users.herp.uid, () => {
|
const uid1 = await User.create({ username: 'allowdeny1', password: 'barbar' });
|
||||||
Messaging.canMessageUser(mocks.users.herp.uid, mocks.users.baz.uid, (err) => {
|
const uid2 = await User.create({ username: 'allowdeny2', password: 'bazbaz' });
|
||||||
assert.ifError(err);
|
const uid3 = await User.create({ username: 'allowdeny3', password: 'bazbaz' });
|
||||||
done();
|
await Messaging.canMessageUser(uid1, uid2);
|
||||||
});
|
|
||||||
});
|
// rejects uid1 only allows uid3 to chat
|
||||||
|
await User.setSetting(uid1, 'chatAllowList', JSON.stringify([uid3]));
|
||||||
|
await assert.rejects(
|
||||||
|
Messaging.canMessageUser(uid2, uid1),
|
||||||
|
{ message: '[[error:chat-restricted]]' },
|
||||||
|
);
|
||||||
|
|
||||||
|
// rejects uid2 denies chat from uid1
|
||||||
|
await User.setSetting(uid2, 'chatDenyList', JSON.stringify([uid1]));
|
||||||
|
await assert.rejects(
|
||||||
|
Messaging.canMessageUser(uid1, uid2),
|
||||||
|
{ message: '[[error:chat-restricted]]' },
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not allow messaging room if user is muted', async () => {
|
it('should not allow messaging room if user is muted', async () => {
|
||||||
@@ -169,11 +181,11 @@ describe('Messaging Library', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should create a new chat room', async () => {
|
it('should create a new chat room', async () => {
|
||||||
await User.setSetting(mocks.users.baz.uid, 'restrictChat', '0');
|
await User.setSetting(mocks.users.baz.uid, 'disableIncomingMessages', '0');
|
||||||
const { body } = await callv3API('post', `/chats`, {
|
const { body } = await callv3API('post', `/chats`, {
|
||||||
uids: [mocks.users.baz.uid],
|
uids: [mocks.users.baz.uid],
|
||||||
}, 'foo');
|
}, 'foo');
|
||||||
await User.setSetting(mocks.users.baz.uid, 'restrictChat', '1');
|
await User.setSetting(mocks.users.baz.uid, 'disableIncomingMessages', '1');
|
||||||
|
|
||||||
roomId = body.response.roomId;
|
roomId = body.response.roomId;
|
||||||
assert(roomId);
|
assert(roomId);
|
||||||
|
|||||||
@@ -1629,7 +1629,7 @@ describe('User', () => {
|
|||||||
postsPerPage: '5',
|
postsPerPage: '5',
|
||||||
showemail: 1,
|
showemail: 1,
|
||||||
showfullname: 1,
|
showfullname: 1,
|
||||||
restrictChat: 0,
|
disableIncomingMessages: 0,
|
||||||
followTopicsOnCreate: 1,
|
followTopicsOnCreate: 1,
|
||||||
followTopicsOnReply: 1,
|
followTopicsOnReply: 1,
|
||||||
},
|
},
|
||||||
@@ -1654,7 +1654,7 @@ describe('User', () => {
|
|||||||
postsPerPage: '5',
|
postsPerPage: '5',
|
||||||
showemail: 1,
|
showemail: 1,
|
||||||
showfullname: 1,
|
showfullname: 1,
|
||||||
restrictChat: 0,
|
disableIncomingMessages: 0,
|
||||||
followTopicsOnCreate: 1,
|
followTopicsOnCreate: 1,
|
||||||
followTopicsOnReply: 1,
|
followTopicsOnReply: 1,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user