Merge branch 'develop' into negue/flagpm
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
} from '../../libs/errors';
|
||||
import _ from 'lodash';
|
||||
import apiError from '../../libs/apiError';
|
||||
import validator from 'validator';
|
||||
|
||||
let api = {};
|
||||
|
||||
@@ -142,8 +143,8 @@ api.getHeroes = {
|
||||
const heroAdminFields = 'contributor balance profile.name purchased items auth flags.chatRevoked';
|
||||
|
||||
/**
|
||||
* @api {get} /api/v3/hall/heroes/:heroId Get any user ("hero") given the UUID
|
||||
* @apiParam (Path) {UUID} heroId User ID
|
||||
* @api {get} /api/v3/hall/heroes/:heroId Get any user ("hero") given the UUID or Username
|
||||
* @apiParam (Path) {UUID} heroId user ID
|
||||
* @apiName GetHero
|
||||
* @apiGroup Hall
|
||||
* @apiPermission Admin
|
||||
@@ -162,15 +163,23 @@ api.getHero = {
|
||||
url: '/hall/heroes/:heroId',
|
||||
middlewares: [authWithHeaders(), ensureAdmin],
|
||||
async handler (req, res) {
|
||||
let heroId = req.params.heroId;
|
||||
let validationErrors;
|
||||
req.checkParams('heroId', res.t('heroIdRequired')).notEmpty();
|
||||
|
||||
req.checkParams('heroId', res.t('heroIdRequired')).notEmpty().isUUID();
|
||||
|
||||
let validationErrors = req.validationErrors();
|
||||
validationErrors = req.validationErrors();
|
||||
if (validationErrors) throw validationErrors;
|
||||
|
||||
let hero = await User
|
||||
.findById(heroId)
|
||||
const heroId = req.params.heroId;
|
||||
|
||||
let query;
|
||||
if (validator.isUUID(heroId)) {
|
||||
query = {_id: heroId};
|
||||
} else {
|
||||
query = {'auth.local.username': heroId};
|
||||
}
|
||||
|
||||
const hero = await User
|
||||
.findOne(query)
|
||||
.select(heroAdminFields)
|
||||
.exec();
|
||||
|
||||
|
||||
@@ -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 = 'FEBRUARY BACKGROUNDS AND ARMOIRE ITEMS!';
|
||||
const LAST_ANNOUNCEMENT_TITLE = 'MARCH RESOLUTION SUCCESS CHALLENGE AND NEW TAKE THIS CHALLENGE';
|
||||
const worldDmg = { // @TODO
|
||||
bailey: false,
|
||||
};
|
||||
@@ -30,14 +30,18 @@ api.getNews = {
|
||||
<div class="mr-3 ${baileyClass}"></div>
|
||||
<div class="media-body">
|
||||
<h1 class="align-self-center">${res.t('newStuff')}</h1>
|
||||
<h2>2/5/2019 - ${LAST_ANNOUNCEMENT_TITLE}</h2>
|
||||
<h2>3/1/2019 - ${LAST_ANNOUNCEMENT_TITLE}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="promo_armoire_backgrounds_201902 center-block"></div>
|
||||
<p>We’ve added three new backgrounds to the Background Shop! Now your avatar can cook up a storm in a Medieval Kitchen, enjoy delicious smells outside an Old-Fashioned Bakery, and feel the love in a Valentines' Day Feasting Hall. Check them out under User Icon > Backgrounds!</p>
|
||||
<p>Plus, there’s new Gold-purchasable equipment in the Enchanted Armoire, including the Chef Set. Better work hard on your real-life tasks to earn all the pieces! Enjoy :)</p>
|
||||
<div class="small mb-3">by Vampitch, GeraldThePixel, Aspiring Advocate, Marmarru, NekoAtsumeLARPer, and Giu09</div>
|
||||
<div class="scene_achievement 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/00bbaeaa-d4e0-4eab-92e8-78ba1e754229'>Reach for Your First Achievement</a>, we're focusing on setting smaller mini-goals as milestones! It has a 15 Gem prize, which will be awarded to five lucky winners on April 1st.</p>
|
||||
<p>Congratulations to the winners of the February Challenge, Mistress Cerny, Zsuzsa, Chelusine, Sparks, and Jinmav!</p>
|
||||
<p>The next Take This Challenge has also launched, "<a href='/challenges/7d199231-f3de-4d93-9765-06392f521e96'>Do One Thing Well!</a>", with a focus on minimizing multitasking. 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, "Achievement Unlocked: Self-Care!": grand prize winner orli, and runners-up Hoofter, Fluor, wema, Shilo_The_Eldest, and selesnyancat! 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, shanaqui, and SabreCat</div>
|
||||
<div class="promo_take_this center-block"></div>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
||||
@@ -10,9 +10,11 @@ if (process.env.NODE_ENV !== 'production') {
|
||||
// Initialize configuration BEFORE anything
|
||||
const setupNconf = require('./libs/setupNconf');
|
||||
setupNconf();
|
||||
|
||||
const nconf = require('nconf');
|
||||
|
||||
// Initialize @google-cloud/trace-agent
|
||||
require('./libs/gcpTraceAgent');
|
||||
|
||||
const cluster = require('cluster');
|
||||
const logger = require('./libs/logger');
|
||||
|
||||
|
||||
@@ -183,7 +183,12 @@ async function registerLocal (req, res, { isV3 = false }) {
|
||||
EmailUnsubscription
|
||||
.remove({email: savedUser.auth.local.email})
|
||||
.then(() => {
|
||||
if (!existingUser) sendTxnEmail(savedUser, 'welcome');
|
||||
if (existingUser) return;
|
||||
if (savedUser._ABtests && savedUser._ABtests.welcomeEmailSplit) {
|
||||
sendTxnEmail(savedUser, savedUser._ABtests.welcomeEmailSplit);
|
||||
} else {
|
||||
sendTxnEmail(savedUser, 'welcome');
|
||||
}
|
||||
});
|
||||
|
||||
if (!existingUser) {
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
const nconf = require('nconf');
|
||||
|
||||
const IS_PROD = nconf.get('IS_PROD');
|
||||
const STACKDRIVER_TRACING_ENABLED = nconf.get('ENABLE_STACKDRIVER_TRACING') === 'true';
|
||||
|
||||
let tracer = null;
|
||||
|
||||
if (IS_PROD && STACKDRIVER_TRACING_ENABLED) {
|
||||
tracer = require('@google-cloud/trace-agent').start(); // eslint-disable-line global-require
|
||||
}
|
||||
|
||||
export default tracer;
|
||||
@@ -239,17 +239,26 @@ api.cancelSubscribe = async function cancelSubscribe (user, headers) {
|
||||
|
||||
await iap.setup();
|
||||
|
||||
let appleRes = await iap.validate(iap.APPLE, plan.additionalData);
|
||||
let dateTerminated;
|
||||
|
||||
let isValidated = iap.isValidated(appleRes);
|
||||
if (!isValidated) throw new NotAuthorized(this.constants.RESPONSE_INVALID_RECEIPT);
|
||||
try {
|
||||
let appleRes = await iap.validate(iap.APPLE, plan.additionalData);
|
||||
|
||||
let purchases = iap.getPurchaseData(appleRes);
|
||||
if (purchases.length === 0) throw new NotAuthorized(this.constants.RESPONSE_INVALID_RECEIPT);
|
||||
let subscriptionData = purchases[0];
|
||||
let isValidated = iap.isValidated(appleRes);
|
||||
if (!isValidated) throw new NotAuthorized(this.constants.RESPONSE_INVALID_RECEIPT);
|
||||
|
||||
let dateTerminated = new Date(Number(subscriptionData.expirationDate));
|
||||
if (dateTerminated > new Date()) throw new NotAuthorized(this.constants.RESPONSE_STILL_VALID);
|
||||
let purchases = iap.getPurchaseData(appleRes);
|
||||
if (purchases.length === 0) throw new NotAuthorized(this.constants.RESPONSE_INVALID_RECEIPT);
|
||||
let subscriptionData = purchases[0];
|
||||
|
||||
dateTerminated = new Date(Number(subscriptionData.expirationDate));
|
||||
if (dateTerminated > new Date()) throw new NotAuthorized(this.constants.RESPONSE_STILL_VALID);
|
||||
} catch (err) {
|
||||
// If we have an invalid receipt, cancel anyway
|
||||
if (!err || !err.validatedData || err.validatedData.is_retryable === true || err.validatedData.status !== 21010) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
await payments.cancelSubscription({
|
||||
user,
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
} from '../models/user';
|
||||
import nconf from 'nconf';
|
||||
import url from 'url';
|
||||
import gcpStackdriverTracer from '../libs/gcpTraceAgent';
|
||||
|
||||
const COMMUNITY_MANAGER_EMAIL = nconf.get('EMAILS_COMMUNITY_MANAGER_EMAIL');
|
||||
|
||||
@@ -34,6 +35,13 @@ function getUserFields (options, req) {
|
||||
return `notifications ${userFieldOptions.join(' ')}`;
|
||||
}
|
||||
|
||||
// Make sure stackdriver traces are storing the user id
|
||||
function stackdriverTraceUserId (userId) {
|
||||
if (gcpStackdriverTracer) {
|
||||
gcpStackdriverTracer.getCurrentRootSpan().addLabel('userId', userId);
|
||||
}
|
||||
}
|
||||
|
||||
// Strins won't be translated here because getUserLanguage has not run yet
|
||||
|
||||
// Authenticate a request through the x-api-user and x-api key header
|
||||
@@ -64,8 +72,9 @@ export function authWithHeaders (options = {}) {
|
||||
if (user.auth.blocked) throw new NotAuthorized(res.t('accountSuspended', {communityManagerEmail: COMMUNITY_MANAGER_EMAIL, userId: user._id}));
|
||||
|
||||
res.locals.user = user;
|
||||
|
||||
req.session.userId = user._id;
|
||||
stackdriverTraceUserId(user._id);
|
||||
|
||||
return next();
|
||||
})
|
||||
.catch(next);
|
||||
@@ -93,6 +102,7 @@ export function authWithSession (req, res, next) {
|
||||
if (!user) throw new NotAuthorized(res.t('invalidCredentials'));
|
||||
|
||||
res.locals.user = user;
|
||||
stackdriverTraceUserId(user._id);
|
||||
return next();
|
||||
})
|
||||
.catch(next);
|
||||
|
||||
@@ -128,6 +128,17 @@ function _setUpNewUser (user) {
|
||||
user.purchased.background.violet = true;
|
||||
user.preferences.background = 'violet';
|
||||
|
||||
const testGroup = Math.random();
|
||||
if (testGroup < 0.25) {
|
||||
user._ABtests.welcomeEmailSplit = 'welcome-v2';
|
||||
} else if (testGroup < 0.5) {
|
||||
user._ABtests.welcomeEmailSplit = 'welcome-v2b';
|
||||
} else if (testGroup < 0.75) {
|
||||
user._ABtests.welcomeEmailSplit = 'welcome-v2c';
|
||||
} else {
|
||||
user._ABtests.welcomeEmailSplit = 'welcome-v2d';
|
||||
}
|
||||
|
||||
if (user.registeredThrough === 'habitica-web') {
|
||||
taskTypes = ['habit', 'daily', 'todo', 'reward', 'tag'];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user