mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-14 21:27:23 +01:00
misc fixes, GET user (with tests), more comments for preenHistory
This commit is contained in:
@@ -2,30 +2,47 @@ import moment from 'moment';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
function _preen (newHistory, history, amount, groupBy) {
|
function _preen (newHistory, history, amount, groupBy) {
|
||||||
let groups = _.chain(history)
|
_.chain(history)
|
||||||
.groupBy(h => moment(h.date).format(groupBy))
|
.groupBy(h => moment(h.date).format(groupBy))
|
||||||
.sortBy((h, k) => k)
|
.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();
|
.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:
|
// Free users:
|
||||||
// Preen history for users with > 7 history entries
|
// 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
|
// 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 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]
|
// 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:
|
// 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) {
|
export function preenHistory (history) {
|
||||||
// TODO remember to add this to migration
|
// TODO remember to add this to migration
|
||||||
/* history = _.filter(history, function(h) {
|
/* history = _.filter(history, function(h) {
|
||||||
|
|||||||
31
test/api/v3/integration/user/GET-user.test.js
Normal file
31
test/api/v3/integration/user/GET-user.test.js
Normal file
@@ -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');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -30,7 +30,7 @@ api.registerLocal = {
|
|||||||
url: '/user/auth/local/register',
|
url: '/user/auth/local/register',
|
||||||
handler (req, res, next) {
|
handler (req, res, next) {
|
||||||
let fbUser = res.locals.user; // If adding local auth to social user
|
let fbUser = res.locals.user; // If adding local auth to social user
|
||||||
|
// TODO check user doesn't have local auth
|
||||||
req.checkBody({
|
req.checkBody({
|
||||||
email: {
|
email: {
|
||||||
notEmpty: {errorMessage: res.t('missingEmail')},
|
notEmpty: {errorMessage: res.t('missingEmail')},
|
||||||
|
|||||||
33
website/src/controllers/api-v3/user.js
Normal file
33
website/src/controllers/api-v3/user.js
Normal file
@@ -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;
|
||||||
@@ -469,7 +469,7 @@ export let schema = new Schema({
|
|||||||
});
|
});
|
||||||
|
|
||||||
schema.plugin(baseModel, {
|
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'],
|
private: ['auth.local.hashed_password', 'auth.local.salt'],
|
||||||
toJSONTransform: function toJSON (doc) {
|
toJSONTransform: function toJSON (doc) {
|
||||||
// FIXME? Is this a reference to `doc.filters` or just disabled code? Remove?
|
// FIXME? Is this a reference to `doc.filters` or just disabled code? Remove?
|
||||||
|
|||||||
Reference in New Issue
Block a user