habitica/website/server/libs/chatReporting/groupChatReporter.js

110 lines
3.8 KiB
JavaScript
Raw Normal View History

2018-02-11 15:35:24 +00:00
import nconf from 'nconf';
import moment from 'moment';
2018-02-11 15:35:24 +00:00
import ChatReporter from './chatReporter';
import {
BadRequest,
NotFound,
} from '../errors';
import { getGroupUrl, sendTxn } from '../email';
import slack from '../slack';
import { model as Group } from '../../models/group';
Move inbox to its own model (#10428) * shared model for chat and inbox * disable inbox schema * inbox: use separate model * remove old code that used group.chat * add back chat field (not used) and remove old tests * remove inbox exclusions when loading user * add GET /api/v3/inbox/messages * add comment * implement DELETE /inbox/messages/:messageid in v4 * implement GET /inbox/messages in v4 and update tests * implement DELETE /api/v4/inbox/clear * fix url * fix doc * update /export/inbox.html * update other data exports * add back messages in user schema * add user.toJSONWithInbox * add compativility until migration is done * more compatibility * fix tojson called twice * add compatibility methods * fix common tests * fix v4 integration tests * v3 get user -> with inbox * start to fix tests * fix v3 integration tests * wip * wip, client use new route * update tests for members/send-private-message * tests for get user in v4 * add tests for DELETE /inbox/messages/:messageId * add tests for DELETE /inbox/clear in v4 * update docs * fix tests * initial migration * fix migration * fix migration * migration fixes * migrate api.enterCouponCode * migrate api.castSpell * migrate reset, reroll, rebirth * add routes to v4 version * fix tests * fixes * api.updateUser * remove .only * get user -> userLib * refactor inbox.vue to work with new data model * fix return message when messaging yourself * wip fix bug with new conversation * wip * fix remaining ui issues * move api.registerLocal, fixes * keep only v3 version of GET /inbox/messages
2018-09-21 13:12:20 +00:00
import { chatModel as Chat } from '../../models/message';
import apiError from '../apiError';
2018-02-11 15:35:24 +00:00
const COMMUNITY_MANAGER_EMAIL = nconf.get('EMAILS:COMMUNITY_MANAGER_EMAIL');
const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL').split(',').map((email) => {
return { email, canSend: true };
});
const USER_AGE_FOR_FLAGGING = 3; // accounts less than this many days old don't increment flagCount
2018-02-11 15:35:24 +00:00
export default class GroupChatReporter extends ChatReporter {
constructor (req, res) {
super(req, res);
this.user = res.locals.user;
this.groupId = req.params.groupId;
}
async validate () {
this.req.checkParams('groupId', apiError('groupIdRequired')).notEmpty();
this.req.checkParams('chatId', apiError('chatIdRequired')).notEmpty();
2018-02-11 15:35:24 +00:00
let validationErrors = this.req.validationErrors();
if (validationErrors) throw validationErrors;
let group = await Group.getGroup({
user: this.user,
groupId: this.groupId,
optionalMembership: this.user.contributor.admin,
});
if (!group) throw new NotFound(this.res.t('groupNotFound'));
const message = await Chat.findOne({_id: this.req.params.chatId}).exec();
2018-02-11 15:35:24 +00:00
if (!message) throw new NotFound(this.res.t('messageGroupChatNotFound'));
if (message.uuid === 'system') throw new BadRequest(this.res.t('messageCannotFlagSystemMessages', {communityManagerEmail: COMMUNITY_MANAGER_EMAIL}));
const userComment = this.req.body.comment;
return {message, group, userComment};
2018-02-11 15:35:24 +00:00
}
async notify (group, message, userComment, automatedComment = '') {
2018-02-11 15:35:24 +00:00
await super.notify(group, message);
const groupUrl = getGroupUrl(group);
sendTxn(FLAG_REPORT_EMAILS, 'flag-report-to-mods-with-comments', this.emailVariables.concat([
2018-02-11 15:35:24 +00:00
{name: 'GROUP_NAME', content: group.name},
{name: 'GROUP_TYPE', content: group.type},
{name: 'GROUP_ID', content: group._id},
{name: 'GROUP_URL', content: groupUrl},
{name: 'REPORTER_COMMENT', content: userComment || ''},
2018-02-11 15:35:24 +00:00
]));
slack.sendFlagNotification({
authorEmail: this.authorEmail,
flagger: this.user,
group,
message,
userComment,
automatedComment,
2018-02-11 15:35:24 +00:00
});
}
async flagGroupMessage (group, message, increaseFlagCount) {
2018-02-11 15:35:24 +00:00
// Log user ids that have flagged the message
if (!message.flags) message.flags = {};
// TODO fix error type
if (message.flags[this.user._id] && !this.user.contributor.admin) throw new NotFound(this.res.t('messageGroupChatFlagAlreadyReported'));
message.flags[this.user._id] = true;
message.markModified('flags');
2018-02-11 15:35:24 +00:00
// Log total number of flags (publicly viewable)
if (!message.flagCount) message.flagCount = 0;
if (this.user.contributor.admin) {
// Arbitrary amount, higher than 2
message.flagCount = 5;
} else if (increaseFlagCount) {
2018-02-11 15:35:24 +00:00
message.flagCount++;
}
await message.save();
2018-02-11 15:35:24 +00:00
}
async flag () {
let {message, group, userComment} = await this.validate();
let increaseFlagCount = true;
let automatedComment = '';
if (moment().diff(this.user.auth.timestamps.created, 'days') < USER_AGE_FOR_FLAGGING) {
increaseFlagCount = false;
automatedComment = `The post's flag count has not been increased because the flagger's account is less than ${USER_AGE_FOR_FLAGGING} days old.`;
// This is to prevent trolls from making new accounts to maliciously flag-and-hide.
}
await this.notify(group, message, userComment, automatedComment);
await this.flagGroupMessage(group, message, increaseFlagCount);
2018-02-11 15:35:24 +00:00
return message;
}
}