mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-16 06:07:21 +01:00
Disallow interactions by blocked users; new "get objections" Members API route (#8755)
* Make flags.chatRevoked prevent sending private messages (issue #7971) * Disallow sending gems when messages aren't allowed. * Created function to check for objections to an interaction to user model and wired it into the API (issue #7971) * Fixes for issues raised by reviewers. * Added allowed values to apidoc for api.getObjectionsToInteraction. * Refactoring of getObjectionsToInteraction and minor API changes. * fix(objections): address PR comments * fix(strings): use US English for base edits * refactor(test): typos and phrasing
This commit is contained in:
committed by
Keith Holliday
parent
00e5896ac6
commit
018976a723
@@ -5,7 +5,7 @@ import {
|
||||
chatDefaults,
|
||||
TAVERN_ID,
|
||||
} from '../group';
|
||||
import { defaults } from 'lodash';
|
||||
import { defaults, map, flatten, flow, compact, uniq, partialRight } from 'lodash';
|
||||
import { model as UserNotification } from '../userNotification';
|
||||
import schema from './schema';
|
||||
import payments from '../../libs/payments';
|
||||
@@ -33,6 +33,56 @@ schema.methods.getGroups = function getUserGroups () {
|
||||
return userGroups;
|
||||
};
|
||||
|
||||
/* eslint-disable no-unused-vars */ // The checks below all get access to sndr and rcvr, but not all use both
|
||||
const INTERACTION_CHECKS = Object.freeze({
|
||||
always: [
|
||||
// Revoked chat privileges block all interactions to prevent the evading of harassment protections
|
||||
// See issue #7971 for some discussion
|
||||
(sndr, rcvr) => sndr.flags.chatRevoked && 'chatPrivilegesRevoked',
|
||||
|
||||
// Direct user blocks prevent all interactions
|
||||
(sndr, rcvr) => rcvr.inbox.blocks.includes(sndr._id) && 'notAuthorizedToSendMessageToThisUser',
|
||||
(sndr, rcvr) => sndr.inbox.blocks.includes(rcvr._id) && 'notAuthorizedToSendMessageToThisUser',
|
||||
],
|
||||
|
||||
'send-private-message': [
|
||||
// Private messaging has an opt-out, which does not affect other interactions
|
||||
(sndr, rcvr) => rcvr.inbox.optOut && 'notAuthorizedToSendMessageToThisUser',
|
||||
|
||||
// We allow a player to message themselves so they can test how PMs work or send their own notes to themselves
|
||||
],
|
||||
|
||||
'transfer-gems': [
|
||||
// Unlike private messages, gems can't be sent to oneself
|
||||
(sndr, rcvr) => rcvr._id === sndr._id && 'cannotSendGemsToYourself',
|
||||
],
|
||||
});
|
||||
/* eslint-enable no-unused-vars */
|
||||
|
||||
export const KNOWN_INTERACTIONS = Object.freeze(Object.keys(INTERACTION_CHECKS).filter(key => key !== 'always'));
|
||||
|
||||
// Get an array of error message keys that would be thrown if the given interaction was attempted
|
||||
schema.methods.getObjectionsToInteraction = function getObjectionsToInteraction (interaction, receiver) {
|
||||
if (!KNOWN_INTERACTIONS.includes(interaction)) {
|
||||
throw new Error(`Unknown kind of interaction: "${interaction}", expected one of ${KNOWN_INTERACTIONS.join(', ')}`);
|
||||
}
|
||||
|
||||
let sender = this;
|
||||
let checks = [
|
||||
INTERACTION_CHECKS.always,
|
||||
INTERACTION_CHECKS[interaction],
|
||||
];
|
||||
|
||||
let executeChecks = partialRight(map, (check) => check(sender, receiver));
|
||||
|
||||
return flow(
|
||||
flatten,
|
||||
executeChecks,
|
||||
compact, // Remove passed checks (passed checks return falsy; failed checks return message keys)
|
||||
uniq
|
||||
)(checks);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sends a message to a user. Archives a copy in sender's inbox.
|
||||
|
||||
Reference in New Issue
Block a user