Improvements to shadow muting (#15543)

* fix test wording

* make shadow mute work for dms

* shadow mute chat messages

* shadow mute invites

* oops

* refactor mute handling into middleware

* correctly throw error

* fix

* test(chat): expect errors when muted
Also fixes the Linux version in the mongo commands. Again. wtf

---------

Co-authored-by: Kalista Payne <kalista@habitica.com>
This commit is contained in:
Phillip Thelen
2025-11-04 22:35:56 +01:00
committed by GitHub
parent 215e5e1c40
commit 5ff3cc35a6
9 changed files with 225 additions and 75 deletions

View File

@@ -1,7 +1,7 @@
import pick from 'lodash/pick';
import moment from 'moment';
import nconf from 'nconf';
import { authWithHeaders } from '../../middlewares/auth';
import { authWithHeaders, chatPrivilegesRequired } from '../../middlewares/auth';
import { model as Group } from '../../models/group';
import { model as User } from '../../models/user';
import {
@@ -118,7 +118,7 @@ function getBannedWordsFromText (message) {
api.postChat = {
method: 'POST',
url: '/groups/:groupId/chat',
middlewares: [authWithHeaders()],
middlewares: [authWithHeaders(), chatPrivilegesRequired()],
async handler (req, res) {
const { user } = res.locals;
const { groupId } = req.params;
@@ -161,10 +161,6 @@ api.postChat = {
throw new BadRequest(res.t('bannedSlurUsed'));
}
if (group.privacy === 'public' && user.flags.chatRevoked) {
throw new NotAuthorized(res.t('chatPrivilegesRevoked'));
}
// prevent banned words being posted, except in private guilds/parties
// and in certain public guilds with specific topics
if (group.privacy === 'public' && !group.bannedWordsAllowed) {
@@ -204,7 +200,7 @@ api.postChat = {
}
let flagCount = 0;
if (group.privacy === 'public' && user.flags.chatShadowMuted) {
if (user.flags.chatShadowMuted) {
flagCount = common.constants.CHAT_FLAG_FROM_SHADOW_MUTE;
// Email the mods

View File

@@ -9,7 +9,7 @@ import pick from 'lodash/pick';
import uniqBy from 'lodash/uniqBy';
import nconf from 'nconf';
import moment from 'moment';
import { authWithHeaders } from '../../middlewares/auth';
import { authWithHeaders, chatPrivilegesRequired } from '../../middlewares/auth';
import {
model as Group,
basicFields as basicGroupFields,
@@ -97,8 +97,6 @@ const api = {};
* @apiError (401) {NotAuthorized} messageInsufficientGems User does not have enough gems (4)
* @apiError (401) {NotAuthorized} partyMustbePrivate Party must have privacy set to private
* @apiError (401) {NotAuthorized} messageGroupAlreadyInParty
* @apiError (401) {NotAuthorized} chatPrivilegesRevoked You cannot do this because your chat
privileges have been removed...
*
* @apiSuccess (201) {Object} data The created group (See <a href="https://github.com/HabitRPG/habitica/blob/develop/website/server/models/group.js" target="_blank">/website/server/models/group.js</a>)
*
@@ -1099,12 +1097,10 @@ api.removeGroupMember = {
api.inviteToGroup = {
method: 'POST',
url: '/groups/:groupId/invite',
middlewares: [authWithHeaders()],
middlewares: [authWithHeaders(), chatPrivilegesRequired()],
async handler (req, res) {
const { user } = res.locals;
if (user.flags.chatRevoked) throw new NotAuthorized(res.t('chatPrivilegesRevoked'));
req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
if (user.invitesSent >= MAX_EMAIL_INVITES_BY_USER) throw new NotAuthorized(res.t('inviteLimitReached', { techAssistanceEmail: TECH_ASSISTANCE_EMAIL }));
@@ -1131,25 +1127,41 @@ api.inviteToGroup = {
const results = [];
if (uuids) {
const uuidInvites = uuids.map(uuid => inviteByUUID(uuid, group, user, req, res));
const uuidResults = await Promise.all(uuidInvites);
results.push(...uuidResults);
}
if (!user.flags.chatShadowMuted) {
if (uuids) {
const uuidInvites = uuids.map(uuid => inviteByUUID(uuid, group, user, req, res));
const uuidResults = await Promise.all(uuidInvites);
results.push(...uuidResults);
}
if (emails) {
const emailInvites = emails.map(invite => inviteByEmail(invite, group, user, req, res));
user.invitesSent += emails.length;
await user.save();
const emailResults = await Promise.all(emailInvites);
results.push(...emailResults);
}
if (emails) {
const emailInvites = emails.map(invite => inviteByEmail(invite, group, user, req, res));
user.invitesSent += emails.length;
await user.save();
const emailResults = await Promise.all(emailInvites);
results.push(...emailResults);
}
if (usernames) {
const usernameInvites = usernames
.map(username => inviteByUserName(username, group, user, req, res));
const usernameResults = await Promise.all(usernameInvites);
results.push(...usernameResults);
if (usernames) {
const usernameInvites = usernames
.map(username => inviteByUserName(username, group, user, req, res));
const usernameResults = await Promise.all(usernameInvites);
results.push(...usernameResults);
}
} else {
const fakeCount = (uuids ? uuids.length : 0)
+ (emails ? emails.length : 0)
+ (usernames ? usernames.length : 0);
results.push(...new Array(fakeCount).fill({
id: group._id,
_id: group._id,
name: group.name,
inviter: user._id,
}));
if (emails) {
user.invitesSent += emails.length;
await user.save();
}
}
res.respond(200, results);