Merge branch 'develop' of https://github.com/HabitRPG/habitica into autocomplete-username
# Conflicts: # package.json
This commit is contained in:
@@ -23,7 +23,7 @@ import {
|
||||
import {verifyUsername} from '../../libs/user/validation';
|
||||
|
||||
const BASE_URL = nconf.get('BASE_URL');
|
||||
const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS:TECH_ASSISTANCE_EMAIL');
|
||||
const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL');
|
||||
|
||||
let api = {};
|
||||
|
||||
|
||||
@@ -577,7 +577,7 @@ api.exportChallengeCsv = {
|
||||
.lean().exec(),
|
||||
]);
|
||||
|
||||
let resArray = members.map(member => [member._id, member.profile.name]);
|
||||
let resArray = members.map(member => [member._id, member.profile.name, member.auth.local.username]);
|
||||
|
||||
let lastUserId;
|
||||
let index = -1;
|
||||
@@ -606,7 +606,7 @@ api.exportChallengeCsv = {
|
||||
let challengeTasks = _.reduce(challenge.tasksOrder.toObject(), (result, array) => {
|
||||
return result.concat(array);
|
||||
}, []).sort();
|
||||
resArray.unshift(['UUID', 'name']);
|
||||
resArray.unshift(['UUID', 'Display Name', 'Username']);
|
||||
|
||||
_.times(challengeTasks.length, () => resArray[0].push('Task', 'Value', 'Notes', 'Streak'));
|
||||
|
||||
|
||||
@@ -84,6 +84,8 @@ function getBannedWordsFromText (message) {
|
||||
return getMatchesByWordArray(message, bannedWords);
|
||||
}
|
||||
|
||||
|
||||
const mentionRegex = new RegExp('\\B@[-\\w]+', 'g');
|
||||
/**
|
||||
* @api {post} /api/v3/groups/:groupId/chat Post chat message to a group
|
||||
* @apiName PostChat
|
||||
@@ -192,6 +194,27 @@ api.postChat = {
|
||||
|
||||
await Promise.all(toSave);
|
||||
|
||||
let analyticsObject = {
|
||||
uuid: user._id,
|
||||
hitType: 'event',
|
||||
category: 'behavior',
|
||||
groupType: group.type,
|
||||
privacy: group.privacy,
|
||||
headers: req.headers,
|
||||
};
|
||||
|
||||
const mentions = req.body.message.match(mentionRegex);
|
||||
if (mentions) {
|
||||
analyticsObject.mentionsCount = mentions.length;
|
||||
} else {
|
||||
analyticsObject.mentionsCount = 0;
|
||||
}
|
||||
if (group.privacy === 'public') {
|
||||
analyticsObject.groupName = group.name;
|
||||
}
|
||||
|
||||
res.analytics.track('group chat', analyticsObject);
|
||||
|
||||
if (chatUpdated) {
|
||||
res.respond(200, {chat: chatRes.chat});
|
||||
} else {
|
||||
@@ -256,6 +279,7 @@ api.likeChat = {
|
||||
*
|
||||
* @apiParam (Path) {UUID} groupId The group id ('party' for the user party and 'habitrpg' for tavern are accepted)
|
||||
* @apiParam (Path) {UUID} chatId The chat message id
|
||||
* @apiParam (Body) {String} [comment] explain why the message was flagged
|
||||
*
|
||||
* @apiSuccess {Object} data The flagged chat message
|
||||
* @apiSuccess {UUID} data.id The id of the message
|
||||
|
||||
@@ -29,7 +29,7 @@ import shared from '../../../common';
|
||||
import apiError from '../../libs/apiError';
|
||||
|
||||
const MAX_EMAIL_INVITES_BY_USER = 200;
|
||||
const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS:TECH_ASSISTANCE_EMAIL');
|
||||
const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL');
|
||||
|
||||
/**
|
||||
* @apiDefine GroupBodyInvalid
|
||||
|
||||
@@ -3,7 +3,7 @@ import { authWithHeaders } from '../../middlewares/auth';
|
||||
let api = {};
|
||||
|
||||
// @TODO export this const, cannot export it from here because only routes are exported from controllers
|
||||
const LAST_ANNOUNCEMENT_TITLE = 'HAPPY THANKSGIVING!';
|
||||
const LAST_ANNOUNCEMENT_TITLE = 'FEBRUARY RESOLUTION SUCCESS CHALLENGE AND NEW TAKE THIS CHALLENGE';
|
||||
const worldDmg = { // @TODO
|
||||
bailey: false,
|
||||
};
|
||||
@@ -30,17 +30,18 @@ api.getNews = {
|
||||
<div class="mr-3 ${baileyClass}"></div>
|
||||
<div class="media-body">
|
||||
<h1 class="align-self-center">${res.t('newStuff')}</h1>
|
||||
<h2>11/22/2018 - ${LAST_ANNOUNCEMENT_TITLE}</h2>
|
||||
<h2>2/4/2019 - ${LAST_ANNOUNCEMENT_TITLE}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="npc_matt center-block"></div>
|
||||
<p>It's Thanksgiving in Habitica! On this day Habiticans celebrate by spending time with loved ones, giving thanks, and riding their glorious turkeys into the magnificent sunset. Some of the NPCs are celebrating the occasion!</p>
|
||||
<h3>Turkey Pet, Mount, and Costumes!</h3>
|
||||
<p>In celebration of Turkey Day, everyone has received an adorable Turkey! What kind of Turkey? It all depends on how many Habitica Thanksgivings you've celebrated with us. Each Thanksgiving, you'll get a new and exciting Turkey variety!</p>
|
||||
<p>Thank you for using Habitica - we really love you all <3</p>
|
||||
<div class="small mb-3">by Lemoness and Beffymaroo</div>
|
||||
<div class="promo_turkey_day_2018 center-block"></div>
|
||||
<div class="scene_yesterdailies center-block"></div>
|
||||
<p>The Habitica team has launched a special official Challenge series hosted in the <a href='/groups/guild/6e6a8bd3-9f5f-4351-9188-9f11fcd80a99' target='_blank'>Official New Year's Resolution Guild</a>. These Challenges are designed to help you build and maintain goals that are destined for success and then stick with them as the year progresses. For this month's Challenge, <a href='/challenges/03498939-08f2-49dc-af77-1c891525f22d'>Hone Your Weapons</a>, we're focusing on refining and narrowing down your goals to make them more achievable! It has a 15 Gem prize, which will be awarded to five lucky winners on March 1st.</p>
|
||||
<p>Congratulations to the winners of January's Challenge, RainbowZebra27, Annobethal, Pheonix_Heart, rachalza, and grimreader!</p>
|
||||
<p>The next Take This Challenge has also launched, "<a href='/challenges/f0828ccc-f567-47ab-9c22-18c335c9cad9'>Achievement Unlocked: Self-Care!</a>", with a focus on tending to the energy reserves we use when helping others. Be sure to check it out to earn additional pieces of the Take This armor set!</p>
|
||||
<p><a href='http://www.takethis.org/' target='_blank'>Take This</a> is a nonprofit that seeks to inform the gamer community about mental health issues, to provide education about mental disorders and mental illness prevention, and to reduce the stigma of mental illness.</p>
|
||||
<p>Congratulations to the winners of the last Take This Challenge, "Feed Me, Seymour!": grand prize winner _andrey, and runners-up Comebach, FoxInABoxPls, chadm73, creadeliefje, and NTScott! Plus, all participants in that Challenge have received a piece of the <a href='http://habitica.wikia.com/wiki/Event_Item_Sequences#Take_This_Armor_Set' target='_blank'>Take This item set</a> if they hadn't completed it already. It is located in your Rewards column. Enjoy!</p>
|
||||
<div class="small mb-3">by Doctor B, the Take This team, Lemoness, Beffymaroo, and SabreCat</div>
|
||||
<div class="promo_take_this center-block"></div>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { authWithHeaders } from '../../middlewares/auth';
|
||||
import {
|
||||
NotFound,
|
||||
NotificationNotFound,
|
||||
} from '../../libs/errors';
|
||||
import {
|
||||
model as User,
|
||||
@@ -37,7 +37,7 @@ api.readNotification = {
|
||||
});
|
||||
|
||||
if (index === -1) {
|
||||
throw new NotFound(res.t('messageNotificationNotFound'));
|
||||
throw new NotificationNotFound(req.language);
|
||||
}
|
||||
|
||||
user.notifications.splice(index, 1);
|
||||
@@ -81,7 +81,7 @@ api.readNotifications = {
|
||||
});
|
||||
|
||||
if (index === -1) {
|
||||
throw new NotFound(res.t('messageNotificationNotFound'));
|
||||
throw new NotificationNotFound(req.language);
|
||||
}
|
||||
|
||||
user.notifications.splice(index, 1);
|
||||
@@ -129,7 +129,7 @@ api.seeNotification = {
|
||||
});
|
||||
|
||||
if (!notification) {
|
||||
throw new NotFound(res.t('messageNotificationNotFound'));
|
||||
throw new NotificationNotFound(req.language);
|
||||
}
|
||||
|
||||
notification.seen = true;
|
||||
@@ -179,7 +179,7 @@ api.seeNotifications = {
|
||||
});
|
||||
|
||||
if (!notification) {
|
||||
throw new NotFound(res.t('messageNotificationNotFound'));
|
||||
throw new NotificationNotFound(req.language);
|
||||
}
|
||||
|
||||
notification.seen = true;
|
||||
|
||||
@@ -245,7 +245,7 @@ api.rejectQuest = {
|
||||
if (group.quest.members[user._id]) throw new BadRequest(res.t('questAlreadyAccepted'));
|
||||
if (group.quest.members[user._id] === false) throw new BadRequest(res.t('questAlreadyRejected'));
|
||||
|
||||
user.party.quest = Group.cleanQuestProgress();
|
||||
user.party.quest = Group.cleanQuestUser(user.party.quest.progress);
|
||||
user.markModified('party.quest');
|
||||
await user.save();
|
||||
|
||||
@@ -376,7 +376,7 @@ api.cancelQuest = {
|
||||
group.save(),
|
||||
User.update(
|
||||
{'party._id': groupId},
|
||||
{$set: {'party.quest': Group.cleanQuestProgress()}},
|
||||
Group.cleanQuestParty(),
|
||||
{multi: true}
|
||||
).exec(),
|
||||
]);
|
||||
@@ -427,9 +427,8 @@ api.abortQuest = {
|
||||
|
||||
let memberUpdates = User.update({
|
||||
'party._id': groupId,
|
||||
}, {
|
||||
$set: {'party.quest': Group.cleanQuestProgress()},
|
||||
}, {multi: true}).exec();
|
||||
}, Group.cleanQuestParty(),
|
||||
{multi: true}).exec();
|
||||
|
||||
let questLeaderUpdate = User.update({
|
||||
_id: group.quest.leader,
|
||||
@@ -484,7 +483,7 @@ api.leaveQuest = {
|
||||
group.quest.members[user._id] = false;
|
||||
group.markModified('quest.members');
|
||||
|
||||
user.party.quest = Group.cleanQuestProgress();
|
||||
user.party.quest = Group.cleanQuestUser(user.party.quest.progress);
|
||||
user.markModified('party.quest');
|
||||
|
||||
let [savedGroup] = await Promise.all([
|
||||
|
||||
@@ -182,7 +182,10 @@ api.reorderTags = {
|
||||
return tag.id === req.body.tagId;
|
||||
});
|
||||
if (tagIndex === -1) throw new NotFound(res.t('tagNotFound'));
|
||||
user.tags.splice(req.body.to, 0, user.tags.splice(tagIndex, 1)[0]);
|
||||
|
||||
const removedItem = user.tags.splice(tagIndex, 1)[0];
|
||||
|
||||
user.tags.splice(req.body.to, 0, removedItem);
|
||||
|
||||
await user.save();
|
||||
res.respond(200, {});
|
||||
|
||||
@@ -16,15 +16,14 @@ import {
|
||||
} from '../../libs/webhook';
|
||||
import {
|
||||
getUserInfo,
|
||||
sendTxn as txnEmail,
|
||||
sendTxn,
|
||||
} from '../../libs/email';
|
||||
import Queue from '../../libs/queue';
|
||||
import * as inboxLib from '../../libs/inbox';
|
||||
import * as userLib from '../../libs/user';
|
||||
import nconf from 'nconf';
|
||||
import get from 'lodash/get';
|
||||
|
||||
const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS:TECH_ASSISTANCE_EMAIL');
|
||||
const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL');
|
||||
const DELETE_CONFIRMATION = 'DELETE';
|
||||
|
||||
/**
|
||||
@@ -291,8 +290,9 @@ api.deleteUser = {
|
||||
await user.remove();
|
||||
|
||||
if (feedback) {
|
||||
txnEmail({email: TECH_ASSISTANCE_EMAIL}, 'admin-feedback', [
|
||||
sendTxn({email: TECH_ASSISTANCE_EMAIL}, 'admin-feedback', [
|
||||
{name: 'PROFILE_NAME', content: user.profile.name},
|
||||
{name: 'USERNAME', content: user.auth.local.username},
|
||||
{name: 'UUID', content: user._id},
|
||||
{name: 'EMAIL', content: getUserInfo(user, ['email']).email},
|
||||
{name: 'FEEDBACK_SOURCE', content: 'from deletion form'},
|
||||
@@ -300,8 +300,6 @@ api.deleteUser = {
|
||||
]);
|
||||
}
|
||||
|
||||
if (feedback) Queue.sendMessage({feedback, username: user.profile.name}, user._id);
|
||||
|
||||
res.analytics.track('account delete', {
|
||||
uuid: user._id,
|
||||
hitType: 'event',
|
||||
|
||||
Reference in New Issue
Block a user