From a34f41f0f7bf18782ee40d5965fa3c7530bcbfa3 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Sun, 13 Dec 2015 20:08:14 +0100 Subject: [PATCH] misc fixes, GET user (with tests), more comments for preenHistory --- common/script/api-v3/preenHistory.js | 49 +++++++++++++------ test/api/v3/integration/user/GET-user.test.js | 31 ++++++++++++ website/src/controllers/api-v3/auth.js | 2 +- website/src/controllers/api-v3/user.js | 33 +++++++++++++ website/src/models/user.js | 2 +- 5 files changed, 99 insertions(+), 18 deletions(-) create mode 100644 test/api/v3/integration/user/GET-user.test.js create mode 100644 website/src/controllers/api-v3/user.js diff --git a/common/script/api-v3/preenHistory.js b/common/script/api-v3/preenHistory.js index 44ed51862e..50ffb1518f 100644 --- a/common/script/api-v3/preenHistory.js +++ b/common/script/api-v3/preenHistory.js @@ -2,30 +2,47 @@ import moment from 'moment'; import _ from 'lodash'; function _preen (newHistory, history, amount, groupBy) { - let groups = _.chain(history) + _.chain(history) .groupBy(h => moment(h.date).format(groupBy)) .sortBy((h, k) => k) + .slice(-amount) + .pop() + .each((group) => { + newHistory.push({ + date: moment(group[0].date).toDate(), + value: _.reduce(group, (m, obj) => m + obj.value, 0) / group.length, + }); + }) .value(); - - groups = groups.slice(-amount); - groups.pop(); - - _.each(groups, (group) => { - newHistory.push({ - date: moment(group[0].date).toDate(), - value: _.reduce(group, (m, obj) => m + obj.value, 0) / group.length, - }); - }); } // Free users: -// Preen history for users with > 7 history entries -// This takes an infinite array of single day entries [day day day day day...], and turns it into a condensed array -// of averages, condensing more the further back in time we go. Eg, 7 entries each for last 7 days; 1 entry each week -// of this month; 1 entry for each month of this year; 1 entry per previous year: [day*7 week*4 month*12 year*infinite] +// Preen history for users with > 7 history entries +// This takes an infinite array of single day entries [day day day day day...], and turns it into a condensed array +// of averages, condensing more the further back in time we go. Eg, 7 entries each for last 7 days; 1 entry each week +// of this month; 1 entry for each month of this year; 1 entry per previous year: [day*7 week*4 month*12 year*infinite] // // Subscribers: -// TODO implement +// TODO implement + +// TODO Probably the description ^ is not too correct, this method actually takes 1 value each for the last 50 years, +// then the X last months, where X is the month we're in (september = 8 starting from 0) +// and all the days in this month +// Allowing for multiple values in a single day for habits we probably want something different: +// For free users: +// - At max 30 values for today (max 30) +// - 1 value each for the previous 61 days (2 months) +// - 1 value each for the previous 10 months (max 10) +// - 1 value each for the previous 50 years +// - Total: 30+61+10+ a few years ~= 105 +// +// For subscribed users +// - At max 30 values for today (max 30) +// - 1 value each for the previous 364 days (max 364) +// - 1 value each for the previous 12 months (max 12) +// - 1 value each for the previous 50 years +// - Total: 30+364+12+ a few years ~= 410 +// export function preenHistory (history) { // TODO remember to add this to migration /* history = _.filter(history, function(h) { diff --git a/test/api/v3/integration/user/GET-user.test.js b/test/api/v3/integration/user/GET-user.test.js new file mode 100644 index 0000000000..47c8eb4cc9 --- /dev/null +++ b/test/api/v3/integration/user/GET-user.test.js @@ -0,0 +1,31 @@ +import { + generateUser, + requester, +} from '../../../../helpers/api-integration.helper'; + +describe('GET /user', () => { + let user, api; + + before(() => { + return generateUser().then((generatedUser) => { + user = generatedUser; + api = requester(user); + }); + }); + + it('returns the authenticated user', () => { + return api.get('/user') + .then(returnedUser => { + expect(returnedUser._id).to.equal(user._id); + }); + }); + + it('does not return private paths (and apiToken)', () => { + return api.get('/user') + .then(returnedUser => { + expect(returnedUser.auth.local.hashed_password).to.be.a('undefined'); + expect(returnedUser.auth.local.salt).to.be.a('undefined'); + expect(returnedUser.apiToken).to.be.a('undefined'); + }); + }); +}); diff --git a/website/src/controllers/api-v3/auth.js b/website/src/controllers/api-v3/auth.js index 7a818d9877..6693dba861 100644 --- a/website/src/controllers/api-v3/auth.js +++ b/website/src/controllers/api-v3/auth.js @@ -30,7 +30,7 @@ api.registerLocal = { url: '/user/auth/local/register', handler (req, res, next) { let fbUser = res.locals.user; // If adding local auth to social user - + // TODO check user doesn't have local auth req.checkBody({ email: { notEmpty: {errorMessage: res.t('missingEmail')}, diff --git a/website/src/controllers/api-v3/user.js b/website/src/controllers/api-v3/user.js new file mode 100644 index 0000000000..690b18aeb2 --- /dev/null +++ b/website/src/controllers/api-v3/user.js @@ -0,0 +1,33 @@ +import { authWithHeaders } from '../../middlewares/api-v3/auth'; +import common from '../../../../common'; + +let api = {}; + +/** + * @api {get} /user Get the authenticated user's profile + * @apiVersion 3.0.0 + * @apiName UserGet + * @apiGroup User + * + * @apiSuccess {Object} user The user object + */ +api.getUser = { + method: 'GET', + middlewares: [authWithHeaders()], + url: '/user', + handler (req, res) { + let user = res.locals.user.toJSON(); + + // Remove apiToken from resonse TODO make it priavte at the user level? returned in signup/login + delete user.apiToken; + + // TODO move to model (maybe virtuals, maybe in toJSON) + user.stats.toNextLevel = common.tnl(user.stats.lvl); + user.stats.maxHealth = common.maxHealth; + user.stats.maxMP = res.locals.user._statsComputed.maxMP; + + return res.json(200, user); + }, +}; + +export default api; diff --git a/website/src/models/user.js b/website/src/models/user.js index a2e414a296..42bb83f7a0 100644 --- a/website/src/models/user.js +++ b/website/src/models/user.js @@ -469,7 +469,7 @@ export let schema = new Schema({ }); schema.plugin(baseModel, { - noSet: ['_id', 'apikey', 'auth.blocked', 'auth.timestamps', 'lastCron', 'auth.local.hashed_password', 'auth.local.salt', 'tasksOrder', 'tags'], + noSet: ['_id', 'apiToken', 'auth.blocked', 'auth.timestamps', 'lastCron', 'auth.local.hashed_password', 'auth.local.salt', 'tasksOrder', 'tags'], private: ['auth.local.hashed_password', 'auth.local.salt'], toJSONTransform: function toJSON (doc) { // FIXME? Is this a reference to `doc.filters` or just disabled code? Remove?